Applicazioni pratiche di machine learning/Identificazione delle pulsar
Caricamento librerie
modifica library(dplyr)
library(ggplot2)
library(caret)
Parte 1: Dati
modificaIl 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
modificaSi 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 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
modificaDivido 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