Applicazioni pratiche di machine learning/Identificazione delle pulsar
Caricamento librerie
[modifica | modifica sorgente] library(dplyr)
library(ggplot2)
library(caret)
Parte 1: Dati
[modifica | modifica sorgente]Il dataset "pulsar_stars.csv" scaricabile da qui : https://archive.ics.uci.edu/ml/datasets/HTRU2 contiene 17.898 osservazioni con 9 variabili relative a stelle, di cui soltanto 1.639 pulsar . Le pulsar sono un raro tipo di stella a neutroni che producono onde radio rilevabili qui sulla Terra. Mentre le pulsar ruotano, producono un modello rilevabile di onde radio a banda larga. Quando le pulsar ruotano rapidamente l'emissione delle onde radio si ripete periodicamente. Quindi l'identificazione delle pulsar implica la ricerca di segnali radio periodici con grandi radiotelescopi. Tuttavia quasi tutti i rilevamenti sono soggetti a interferenze in radiofrequenza (RFI) e rumore, rendendo difficile trovare i segnali legittimi. Le 9 variabili relative a ciascuna osservazione sono :
- Mean.of.the.integrated.profile: Media del profilo integrato
- Standard.deviation.of.the.integrated.profile:Deviazione standard del profilo integrato
- Excess.kurtosis.of.the.integrated.profile:Eccessiva curtosi del profilo integrato
- Skewness.of.the.integrated.profile:asimmetria del profilo integrato
- Mean.of.the.DM.SNR.curve: Media della curva DM-SNR
- Standard.deviation.of.the.DM.SNR.curve: Deviazione standard della curva DM-SNR
- Excess.kurtosis.of.the.DM.SNR.curve: Eccessiva curtosi della curva DM-SNR
- Skewness.of.the.DM.SNR.curve: Asimmetria della curva DM-SNR
- Stella Pulsar: può assumere i valori "Si" e "No" (variabile da predire)
Caricamento dei dati e visualizzazione della struttura del dataset:
pulsar_stars <- read.csv("pulsar_stars.csv")
names(pulsar_stars)[9]="Stella_Pulsar"
pulsar_stars$Stella_Pulsar[pulsar_stars$Stella_Pulsar==0]="No"
pulsar_stars$Stella_Pulsar[pulsar_stars$Stella_Pulsar==1]="Si"
pulsar_stars$Stella_Pulsar <- as.factor(pulsar_stars$Stella_Pulsar)
str(pulsar_stars)
'data.frame': 17898 obs. of 9 variables:
$ Mean.of.the.integrated.profile : num 140.6 102.5 103 136.8 88.7 ... $ Standard.deviation.of.the.integrated.profile: num 55.7 58.9 39.3 57.2 40.7 ... $ Excess.kurtosis.of.the.integrated.profile : num -0.2346 0.4653 0.3233 -0.0684 0.6009 ... $ Skewness.of.the.integrated.profile : num -0.7 -0.515 1.051 -0.636 1.123 ... $ Mean.of.the.DM.SNR.curve : num 3.2 1.68 3.12 3.64 1.18 ... $ Standard.deviation.of.the.DM.SNR.curve : num 19.1 14.9 21.7 21 11.5 ... $ Excess.kurtosis.of.the.DM.SNR.curve : num 7.98 10.58 7.74 6.9 14.27 ... $ Skewness.of.the.DM.SNR.curve : num 74.2 127.4 63.2 53.6 252.6 ... $ Stella_Pulsar : Factor w/ 2 levels "No","Si": 1 1 1 1 1 1 1 1 1 1 ...
Parte 2: Domanda di ricerca
[modifica | modifica sorgente]Si vuole costruire un modello previsionale tramite un algoritmo di machine learning per predire quali stelle sono pulsar e quali no, avendo a disposizione alcune delle variabili di ingresso elencate in precedenza.
Parte 3 : Esplorazione dei dati
[modifica | modifica sorgente] pulsar_stars %>%
ggplot(aes(Stella_Pulsar, fill=Stella_Pulsar))+
geom_bar()+
scale_y_continuous(breaks=seq(0,17000,2000))+
ggtitle("Numero di stelle del campione",subtitle = "suddivise in base alla variabile Stella Pulsar")

pulsar_stars %>%
ggplot(aes(Mean.of.the.integrated.profile , fill=Stella_Pulsar))+
geom_histogram(binwidth = 10,colour="gray")+
ggtitle("Istogrammi della variabile Mean.of.the.integrated.profile", subtitle = "suddivisi in base alla variabile Stella Pulsar")

pulsar_stars %>%
ggplot(aes(Excess.kurtosis.of.the.integrated.profile, Skewness.of.the.integrated.profile , colour=Stella_Pulsar))+
geom_point()+
ggtitle("Scatterplot di 2 variabili", subtitle = "suddiviso in base alla variabile Stella Pulsar")

Parte 4: Modellizzazione e previsione
[modifica | modifica sorgente]Divido il dataset pulsar_stars in un training set costituito dal 70% delle osservazioni casuali, ottenendo 12.530 osservazioni di stelle, ed in un testing set costituito dalle rimanenti 5.368 osservazioni:
train <- createDataPartition(pulsar_stars$Stella_Pulsar ,p=0.7, list = FALSE)
training <- pulsar_stars[train,]
testing <- pulsar_stars[-train,]
Creo una funzione che individua quali variabili sono più importanti per predire se una stella è pulsar oppure no.
get_vars_importance <-function()
{
df <- features$importance
df <- cbind(df,dimnames(features$importance)[1])
names(df)[2]<-"vars"
df <-df %>%
arrange(desc(Overall)) %>%
select(vars,Overall)
return(df)
}
Eseguendo un ciclo for con la suddetta funzione e applicando l'algoritmo Random Forest alle variabili prescelte si nota che già soltanto con le 2 variabili Excess.kurtosis.of.the.integrated.profile e Skewness.of.the.integrated.profile si ottiene un'Accuracy nella previsione del 97,80% sul testing set. Aggiungendo anche la variabile Mean.of.the.integrated.profile si arriva al 98,15%
for (i in 2:7) {
df <- get_vars_importance()
var_temp <-df$vars[1:i]
f <- paste ( 'Stella_Pulsar' ,paste(var_temp, collapse = ' + ' ), sep = ' ~ ')
modelFit <- train(x=training[,as.character(var_temp)], y=training[,c("Stella_Pulsar")] , form=f , data = training, method="rf", ntree =10)
predictions <- predict(modelFit, newdata = testing)
conf <-confusionMatrix(predictions,testing$Stella_Pulsar)
print(f)
print(conf$overall[1])
}
[1] "Stella_Pulsar ~ Excess.kurtosis.of.the.integrated.profile + Skewness.of.the.integrated.profile" Accuracy 0.9780179
[1] "Stella_Pulsar ~ Excess.kurtosis.of.the.integrated.profile + Skewness.of.the.integrated.profile + Mean.of.the.integrated.profile" Accuracy 0.9815574
[1] "Stella_Pulsar ~ Excess.kurtosis.of.the.integrated.profile + Skewness.of.the.integrated.profile + Mean.of.the.integrated.profile + Standard.deviation.of.the.DM.SNR.curve" Accuracy 0.9802534
[1] "Stella_Pulsar ~ Excess.kurtosis.of.the.integrated.profile + Skewness.of.the.integrated.profile + Mean.of.the.integrated.profile + Standard.deviation.of.the.DM.SNR.curve + Mean.of.the.DM.SNR.curve" Accuracy 0.9828614
[1] "Stella_Pulsar ~ Excess.kurtosis.of.the.integrated.profile + Skewness.of.the.integrated.profile + Mean.of.the.integrated.profile + Standard.deviation.of.the.DM.SNR.curve + Mean.of.the.DM.SNR.curve + Standard.deviation.of.the.integrated.profile" Accuracy 0.9791356
[1] "Stella_Pulsar ~ Excess.kurtosis.of.the.integrated.profile + Skewness.of.the.integrated.profile + Mean.of.the.integrated.profile + Standard.deviation.of.the.DM.SNR.curve + Mean.of.the.DM.SNR.curve + Standard.deviation.of.the.integrated.profile + Skewness.of.the.DM.SNR.curve" Accuracy 0.9817437
Nel modello finale utilizzo come variabili predictors soltanto Excess.kurtosis.of.the.integrated.profile e Skewness.of.the.integrated.profile,data ottenendo già un'ottima Accuracy pari a quasi il 100% sul training set e al 97,73% sul testing set.
model <- train( Stella_Pulsar ~ Excess.kurtosis.of.the.integrated.profile + Skewness.of.the.integrated.profile,data=training, method="rf", ntree=10 )
p1 <- predict(model,newdata = training)
print(confusionMatrix(p1,training$Stella_Pulsar ))
p1 <- predict(model,newdata = testing)
print(confusionMatrix(p1,testing$Stella_Pulsar))
Confusion Matrix and Statistics
Reference
Prediction No Si
No 11371 40
Si 11 1108
Accuracy : 0.9959
95% CI : (0.9947, 0.997)
No Information Rate : 0.9084
P-Value [Acc > NIR] : < 2.2e-16
Kappa : 0.9753
Mcnemar's Test P-Value : 8.826e-05
Sensitivity : 0.9990
Specificity : 0.9652
Pos Pred Value : 0.9965
Neg Pred Value : 0.9902
Prevalence : 0.9084
Detection Rate : 0.9075
Detection Prevalence : 0.9107
Balanced Accuracy : 0.9821
'Positive' Class : No
Confusion Matrix and Statistics
Reference
Prediction No Si
No 4831 76
Si 46 415
Accuracy : 0.9773
95% CI : (0.9729, 0.9811)
No Information Rate : 0.9085
P-Value [Acc > NIR] : < 2.2e-16
Kappa : 0.8594
Mcnemar's Test P-Value : 0.008651
Sensitivity : 0.9906
Specificity : 0.8452
Pos Pred Value : 0.9845
Neg Pred Value : 0.9002
Prevalence : 0.9085
Detection Rate : 0.9000
Detection Prevalence : 0.9141
Balanced Accuracy : 0.9179
'Positive' Class : No