Applicazioni pratiche di machine learning/Identificazione delle pulsar

Indice del libro

Caricamento librerie modifica

 library(dplyr)
 library(ggplot2)
 library(caret)

Parte 1: Dati modifica

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

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

 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

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