Applicazioni pratiche di machine learning/Diagnosi di malattie mentali

Wikibooks, manuali e libri di testo liberi.
Jump to navigation Jump to search
Indice del libro

Caricamento librerie[modifica]

 library(ggplot2)
 library(dplyr)
 library(statsr)
 library(hashmap)

Parte 1 : Dati[modifica]

Il dataset scaricabile da qui : https://osmihelp.org/research è ricavato da un sondaggio del 2014, che misura le attitudini verso la salute mentale e la frequenza di disturbi mentali in ambienti di lavoro tecnologici. E' costituito da 1259 records contenenti ognuna 27 risposte, confluite nelle seguenti 27 variabili:

  • Timestamp: Data della registrazione
  • Age: Età del rispondente
  • Gender: Sesso
  • Country: Paese del rispondente
  • state: Se vivi negli Stati Uniti, in quale stato o territorio risiedi?
  • self_employed: Sei un lavoratore autonomo ?
  • family_history: Hai una storia familiare di malattia mentale?
  • treatment: Hai cercato un trattamento farmacologico o psicoterapeutico per problemi di salute mentale?
  • work_interfere: Se hai un problema di salute mentale, questo interferisce con il tuo lavoro?
  • no_employees: Quanti impiegati ha la tua azienda o organizzazione?
  • remote_work: Lavori in remoto al di fuori dell'ufficio per almeno il 50% del tempo?
  • tech_company: Il tuo datore di lavoro è principalmente un'azienda oppure un' organizzazione tecnologica?
  • benefits: Il tuo datore di lavoro offre benefits per la salute mentale?
  • care_options: Conosci le possibilità di assistenza per la salute mentale offerte dal tuo datore di lavoro??
  • wellness_program: Il tuo datore di lavoro ha mai discusso di salute mentale nell'ambito di un programma di benessere per i dipendenti?
  • seek_help: il tuo datore di lavoro fornisce risorse per saperne di più sui problemi di salute mentale e su come chiedere aiuto?
  • anonymity: il tuo anonimato è protetto se scegli di utilizzare le risorse per la salute mentale o contro l'abuso di sostanze?
  • leave: quanto è facile per te prendere un congedo medico per un problema di salute mentale??
  • mentalhealthconsequence: Pensi che discutere di un problema di salute mentale con il tuo datore di lavoro avrebbe conseguenze negative?
  • physhealthconsequence: Pensi che discutere di un problema di salute fisica con il tuo datore di lavoro avrebbe conseguenze negative?
  • coworkers: Saresti disposto a discutere di un problema di salute mentale con i tuoi colleghi?
  • supervisor: Saresti disposto a discutere un problema di salute mentale con i tuoi diretti supervisori?
  • mentalhealthinterview: Faresti emergere un problema di salute mentale con un potenziale datore di lavoro in un'intervista?
  • physhealthinterview: faresti emergere un problema di salute fisica con un potenziale datore di lavoro in un'intervista?
  • mentalvsphysical: ritieni che il tuo datore di lavoro prenda in considerazione la salute mentale tanto seriamente quanto la salute fisica?
  • obs_consequence: hai sentito parlare o hai osservato conseguenze negative per i colleghi con problemi di salute mentale sul posto di lavoro?
  • comments: eventuali note o commenti aggiuntivi

Si crea una nuova variabile sex, a partire dalla variabile gender, che può assumere soltanto 3 valori : Maschio, Femmina e Trans .

 male_str <- c("male", "m", "male-ish", "maile", "mal", "male (cis)", "make", "male ", "man","msle", "mail", "malr","cis man") 
 trans_str <- c("trans-female", "something kinda male?", "queer/she/they", "non-binary","nah", "all", "enby", "fluid", "genderqueer", "androgyne", "agender", "male leaning androgynous", "guy (-ish) ^_^", "trans woman", "neuter", "female (trans)", "queer", "ostensibly male, unsure what that really means" ) 
 female_str <- c("cis female", "f", "female", "woman", "femake", "female ","cis-female/femme", "female (cis)", "femail") 

 df <- data.frame(str=male_str,gender="Maschio")
 df <- rbind(df,data.frame(str=trans_str,gender="Trans"))
 df <- rbind(df,data.frame(str=female_str,gender="Femmina"))

 map <-hashmap(as.character(df$str),as.character(df$gender))

 n<-nrow(survey)
 v<- rep(NA,n)

 for (i in 1:n) {
  v[i]<-map[[tolower(survey[i,3])]]
 }

 survey <- cbind(survey,sex=v)


Gestione dei valori mancanti:

 colSums(is.na(survey))
 survey <- survey[-which(is.na(survey$sex)),]
 survey$work_interfere <- as.character(survey$work_interfere)
 survey$work_interfere[is.na(survey$work_interfere)] <- "No"
 survey$work_interfere <- as.factor(survey$work_interfere)


Parte 2 : Domanda di ricerca[modifica]

Predicendo la variabile treatment a partire dalle variabili family_history, work_interfere e sex si vuole effettuare una diagnosi del disturbo mentale utilizzando come predictors il sesso, se si ha una storia familiare di malattia mentale e se il disagio mentale interferisce con il lavoro, utilizzando l'algoritmo di machine learning Random Forest.

Parte 3 : Esplorazione dei dati[modifica]

Come si vede dal seguente grafico nel campione il numero di persone in trattamento farmacologico o psicoterapico che hanno una storia familiare di malattia mentale è maggiore di chi è sano mentalmente:

 survey %>%
  ggplot(aes(treatment, fill=family_history))+
  geom_bar()
Family treatment.png

Come si vede dal seguente grafico nel campione chi ha un problema di salute mentale ha maggiori problemi in ambito lavorativo:


 survey %>%
  filter(!is.na(work_interfere)) %>%
  ggplot(aes(treatment, fill=work_interfere))+
  geom_bar()
Work interfere.png

Parte 4 : Modellizzazione e diagnosi[modifica]

Si divide il dataset in un training set con 879 osservazioni ed un testing set con 375 osservazioni . Sul training set si costruisce un modello previsionale per diagnosticare un disturbo mentale a partire dalle variabili sex, work_interfere e family_history, utilizzando l'algoritmo Random Forest e lo si prova sul testing set, ottenendo un'Accuracy nella diagnosi dell'82,67%

 train <- createDataPartition(survey$treatment, p=0.7, list = FALSE)
 training <- survey[train,]
 testing <- survey[-train,]

 model <-  train( treatment ~ sex + family_history + work_interfere, data=training,  method="rf")
 p1 <- predict(model,newdata = testing)
 print(confusionMatrix(p1,testing$treatment))
Confusion Matrix and Statistics
          Reference
Prediction  No Yes
       No  131  10
       Yes  55 179
                                         
              Accuracy : 0.8267          
                95% CI : (0.7845, 0.8636)
   No Information Rate : 0.504           
   P-Value [Acc > NIR] : < 2.2e-16       
                                         
                 Kappa : 0.6526          
                                         
Mcnemar's Test P-Value : 4.828e-08       
                                         
           Sensitivity : 0.7043          
           Specificity : 0.9471          
        Pos Pred Value : 0.9291          
        Neg Pred Value : 0.7650          
            Prevalence : 0.4960          
        Detection Rate : 0.3493          
  Detection Prevalence : 0.3760          
     Balanced Accuracy : 0.8257          
                                         
      'Positive' Class : No