Calcoli scientifici con Julia/Diagnosi malattie cardiache

Caricamento librerie

modifica

Innanzitutto occorre installare e utilizzare le seguenti librerie:

using CSV
using DataFrames
using GLM
using StatsBase:mean

Parte 1: Dati

modifica

Il dataset "heart.csv" scaricabile da kaggle contiene 1025 osservazioni, ciascuna delle quali contiene 14 variabili relative al cuore. Tali variabili sono le seguenti :

  • age: l'età della persona in anni
  • sex: il sesso della persona (1 = maschio, 0 = femmina)
  • cp: dolore toracico sperimentato (1: angina tipica, 2: angina atipica, 3:dolore non anginale, 4: asintomatico)
  • trestbps: pressione sanguigna a riposo della persona (mm/Hg al momento del ricovero in ospedale)
  • chol: misurazione del colesterolo in mg/dl
  • fbs: glicemia a digiuno della persona (> 120 mg/dl, 1 = vero; 0 = falso)
  • restecg: elettrocardiogramma a riposo (0 = normale, 1 = con anomalia dell'onda ST-T, 2 = ipertrofia ventricolare sinistra probabile o definita secondo i criteri di Estes)
  • thalach: frequenza cardiaca massima raggiunta dalla persona
  • exang: angina indotta dall'esercizio (1 = sì; 0 = no)
  • oldpeak: depressione ST indotta dall'esercizio ('ST' si riferisce alle posizioni sul diagramma ECG)
  • slop: pendenza del segmento ST (valore 1: salita, valore 2: piano, valore 3: discesa)
  • ca: numero di vasi principali (0-3)
  • tal: disturbo del sangue chiamato talassemia (3 = normale; 6 = difetto fisso; 7 = difetto reversibile)
  • target: malattie cardiache (0 = no, 1 = sì)

Caricamento dei dati:

 data = CSV.read("heart.csv",DataFrame)

Parte 2 : Domanda di ricerca

modifica

Si vuole predire l'eventuale presenza di una malattia cardiaca nel paziente, predicendo la variabile target in base alle 13 suddette variabili.


Parte 3: Modellizzazione e previsione

modifica

Si suddivide il dataset 2 parti : train_data formato dall'80% delle osservazioni su cui si addestra il modello di regressione logistica e test_data formato dal rimanente 20% su cui si prova il modello calcolandone l'accuracy:

train_ratio = 0.8
n = nrow(data)
n_train = Int(floor(train_ratio * n));
train_data = data[1:n_train, :]
test_data = data[(n_train + 1):end, :]

Si crea il modello di regressione logistica sul training set, predicendo la variabile target in base alle restanti 13 variabili:

fm = @formula(target ~ age + sex + cp + trestbps + chol + fbs + restecg + thalach + exang + oldpeak + slope + ca + thal)
logit = glm(fm, train_data, Binomial(), ProbitLink())

Si costruisce il vettore prediction con le previsioni fatte dal modello sul testing set:

prediction = GLM.predict(logit, test_data)
205-element Vector{Union{Missing, Float64}}:
0.017732763641414958
0.06652842473470792
0.04289852866536204
0.5470639026550284
0.006095278913460305
0.9955768152608755
0.9703221524362567
0.5142923144983738
0.9053830876384388
0.0023961543663923637
0.6965675386130677
0.04394901761879894
0.5745052037713632
⋮
0.005816355358123194
0.9984324380351746
0.0003433323966801158
0.7506524853801526
0.000691630070259472
0.6261769123744736
0.7526861512703369
0.7105401597352763
0.0033310752534602382
0.05287226311321894
0.949991107720036
0.06892902969480652

Si costruisce un vettore di 1 e 0 in base alle probabilità contenute nel vettore prediction. Se la probabilità è maggiore del 50% assume valore 1 altrimenti 0. Poi si calcola l'accuracy che risulta pari all' 80,48% :

prediction_class = [if x < 0.5 0 else 1 end for x in prediction];
accuracy = mean(test_data.target.==prediction_class)
0.8048780487804879

Quindi la regressione logistica è un buon modello predittivo per valutare la presenza di malattie cardiache.