Esempio di Machine Learning con Python: la Regressione lineare semplice
In questo esempio di machine learning andremo a vedere una regressione lineare con una sola feature in input. Una regressione lineare semplice.
Prima di procedere, vi consiglio di leggere due brevi articoli, dove troverete diverse definizioni:
Visto che useremo Python, se non lo avete ancora sul vostro PC, leggete anche Come installare Python in ambiente Microsoft Windows
Per l’esempio, consideriamo due liste Python: la prima rappresenta valori in input (feature), la seconda i valori in output (target).
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [28, 26, 35, 21, 33, 35, 41, 44, 42, 51]
Queste due liste sono rappresentabili su un grafico a punti a dispersione
Dal grafico possiamo notare che i punti, pur non essendo su una stessa retta, comunque hanno una distribuzione quasi lineare, dal punto in basso a sinistra verso il punto in alto a destra. La distribuzione dei punti sul grafico è identificabile come l’andamento delle liste che sono alla base del modello su cui si baserà la nostra macchina ad apprendimento automatico.
Il Modello
Quindi possiamo dire che se la X cresce, anche la Y cresce, come se i punti fossero intorno a una linea immaginaria. L’obiettivo della regressione è proprio quello di individuare questa linea, questa retta. L’individuazione di questa retta ci aiuterebbe a individuare i punti Y per valori di X non presenti nella lista.
Infatti potremmo chiederci come poter predire il valore di Y per una X non compresa nei casi, non compresa nelle due liste ? Praticamente quale sarebbe il valore di Y se X valesse 11, o 12, o 13 ?
La regressione lineare calcola la retta che meglio approssima i punti, cioè la retta che passa tra i punti riducendo al minimo la distanza da ognuno di essi. E visto che la regressione semplice ci darà una retta, è evidente che la predizione non sarà così precisa, ma comunque saremo in grado di valutare un livello plausibile, molto vicino per la Y.
Facciamolo con scikit-learn:
# importiamo il modello di regressione lineare da scikit-learn
import numpy as np
from sklearn.linear_model import LinearRegression
# istanziamo il modello
model=LinearRegression()
# inizializziamo i valori che ci serviranno per istruire la macchina
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [28, 26, 35, 21, 33, 35, 41, 44, 42, 51]
# strutturiamo i dati in forma bidimensionale
X=np.array(x).reshape(-1,1)
# addestriamo il modello
model.fit(X, y)
Il risultato ottenuto dal codice Python è un modello istruito. L’oggetto model è stato istanziato dalla classe della regressione lineare, e dopo aver invocato il modello fit, model ha studiato i dati ed è pronto per fare predizioni.
La predizione
Per avere la predizione dobbiamo invocare il metodo predict, che si occupa di predire scenari futuri. Aggiungiamo la riga
print(model.predict([[11],[12],[13],[14]]))
avviando nuovamente il programma, otterremo i quattro valori predetti in corrispondenza delle features 11, 12, 13 e 14:
[49.8 52.38181818 54.96363636 57.54545455]
Quindi i quattro valori ottenuti in corrispondenza sono:
- 11 —> 49.8
- 12 —> 52.38181818
- 13 —> 54.96363636
- 14 —> 57.54545455
Come possiamo notare, a valori crescenti di X corrispondono valori crescenti di Y, e la cosa ha senso. Proviamo a vedere cosa succede sul grafico
La retta rossa rappresenta il risultato della regressione. La retta sembra essere l’interpretazione geometrica, e in particolare lineare, della distribuzione dei punti. Praticamente è come dire che il modello scelto per valorizzare la previsione, è un modello semplice e lineare.
Possiamo dire che la previsione non è molto corretta, ma è un’interpretazione.
Come valutare i risultati
Ottenuti i risultati della predizione, sarà importante saper valutare sempre l’efficacia di un modello. Per far questo dobbiamo vedere le metriche che scikit-learn mette a disposizione nel package sklearn.metrics.
Le metriche si basano sul concetto del residuo, cioè quanto la retta si allontana dal vero valore della y per una determinata x. Praticamente per ogni punto la distanza dalla retta del punto stesso.
Possiamo calcolare i residui calcolando la differenza tra il valore reale e il valore predetto, possiamo farlo per i features da 1 a 10:
# calcolo le predizioni per valori di x da 1 a 10
y_pred = model.predict(X)
print(y_pred)
# calcolo i residui
residui = y – y_pred
print(residui)
come risultato ottengo le predizioni
[23.98181818 26.56363636 29.14545455 31.72727273 34.30909091 36.89090909 39.47272727 42.05454545 44.63636364 47.21818182]
e i residui
[ 4.01818182 -0.56363636 5.85454545 -10.72727273 -1.30909091 -1.89090909 1.52727273 1.94545455 -2.63636364 3.78181818]
Ognuno di questi valori misura quanto la retta è passata distante dal punto nel grafico. I punti con residuo maggiore si chiamano outlier, cioè i valori meno allineati con la tendenza generale (ad esempio il quarto -10.72). Il secondo valore è -0.56 e quindi molto allineato con la tendenza generale.
Le Metriche
Per la regressione lineare ci sono metriche molto importanti che scikit-learn mette a disposizione, vediamone alcune:
- Mean Absolute Error: consiste nella media dei valori assoluti dei residui. Concettualmente misura la distanza di ogni punto dalla retta. Semplice e concreto, si misura con i valori assoluti perchè misura la distanza e non la posizione sopra o sotto la retta. Inoltre il valore assoluto ci assicura che valori opposti non si annullano. Il valore di MAE può essere maggiore o uguale a zero, e più si avvicina allo zero e più la previsione è buona;
- Mean Squared Error: consiste nella media dei quadrati dei valori assoluti dei residui, come il MAE ma i quadrati. Il valore di MSE è maggiore o uguale a zero, e più si avvicina allo zero e più la previsione è buona;
- R quadro: un po’ più complicato dei precedenti, ma possiamo dire che mette in relazione gli errori commessi in fase di previsione con la varianza dei dati stessi. Il valore di R quadro è sempre minore o uguale a 1, con la possibilità di avere valori negativi. Se R quadro vale 1 vuol dire che il modello interpreta bene l’andamento, a zero la prestazione è neutra. Se R quadro ha un valore negativo, allora vuol dire che il modello non ha fatto una buona prestazione.
Le funzioni di scikit-learn che ci valorizzano i tre indicatori, sono:
- mean_absolute_error per MAE
- mean_squared_error per MSE
- r2_score per R quadro
applicandole al nostro esempio otteniamo i seguenti valori:
MAE = 3.4254545454545466
MSE = 19.847272727272724
R2 = 0.7348039453865216
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
print(mean_absolute_error(y, y_pred))
print(mean_squared_error(y, y_pred))
print(r2_score(y, y_pred))
Ercole Palmeri: Innovation addicted