La tua prima regressione

Giuseppe Gullo
ProfessionAI
Published in
6 min readAug 14, 2018

La regressione è uno dei due principali problemi dell’apprendimento supervisionato, la branca del machine learning che vuole insegnare ai computer a risolvere un determinato problema mostrandogli come questo problema è stato già risolto in passato.

Intuitivamente la regressione consente di trovare la relazione tra input e output, in modo da predire output futuri avendo a disposizione solamente l’input.

Ad esempio, avendo a disposizione un set di dati contenente le specifiche di diversi smartphone e il relativo prezzo di listino, potremmo utilizzare la regressione per predire a che prezzo potrà essere venduto un nuovo smartphone basandosi sulle sue specifiche.

Altri esempi molto più comuni sono il provare a predire il valore futuro di un titolo in borsa in base ai valori passati, provare a predire l’affluenza di utenti al blog in base ai contenuti di un articolo che si vuole pubblicare o il numero di nuovi iscritti in base a delle campagne di advertising in pianificazione.

Matematicamente la regressione può essere intesa come il trovare la funzione che meglio approssima la relazione tra la variabile dipendente X (l’input) e la variabile indipendente Y (l’output).

Nel caso di una regressione lineare la funzione che è un semplice polinomio.

Graficamente questa relazione lineare può essere rappresentata come una retta che passa il più vicino possibile a tutti i punti costituiti da input X e output Y.

Predire il valore di un’abitazione

Per questo primo esempio utilizzeremo il popolarissimo Boston Housing Dataset, un dataset contenente diverse informazioni riguardo alcune alcune abitazioni nei dintorni di Boston.

Un dataset strutturato si può presentare in diversi formati: CSV, TSV, XML, HTTP, JSON, EXCEL eccetera, in ogni caso questo ha una struttura tabulare.

  • Una delle colonne della tabella è il valore che vogliamo addestrare il nostro modello a predire e prende il nome di target.
  • Tutte le altre colonne sono proprietà che possiamo potenzialmente usare per creare il nostro modello, purché abbiano una relazione con il target, e vengono chiamate features.

Pandas è una libreria Python sviluppata appositamente per chi lavora con i dati e mette a disposizione una particolare struttura dati chiamata DataFrame che si presta particolarmente bene a contenere dati in forma tabulare.

Carichiamo il Boston Housing Dataset all’interno di un DataFrame utilizzando la funzione read_csv, seguita dal metodo head del DataFrame per vedere le sue prime 5 righe.

import pandas as pd 
boston = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/housing/housing.data",
sep='\s+', names=["CRIM","ZN","INDUS","CHAS","NOX","RM","AGE","DIS","RAD","TAX","PRATIO","B","LSTAT","MEDV"])
boston.head()

Il DataFrame avrà questa struttura:

La colonna che abbiamo denominato MEDV contiene il valore dell’abitazione in $1000 dollari (ad esempio un MEDV di 24 corrisponde a 24.000$) ed è il nostro target.

Regressione lineare semplice

Una regressione lineare semplice utilizza un’unica feature per costruire il modello, nel nostro caso utilizzeremo solo il numero di stanze, cioè la colonna che abbiamo denominato RM.

Estraiamo la feature RM e il target MEDV e salviamo i valori all’interno di due array numpy che ci serviranno per l’addestramento.

X = boston[['RM']].values
Y = boston["MEDV"].values

E’ buona pratica nel machine learning eseguire l’addestramento su un set di dati per poi verificare i risultati delle sue predizioni con un altro set contente dati non visti durante l’addestramento.
Questo garantisce che il nostro modello è in grado di generalizzare su dati sconosciuti e quindi ha realmente “imparato” dai dati, piuttosto che limitarsi a memorizzare il set di addestramento, condizione conosciuta come overfitting.

Per fare questo dobbiamo suddividere il nostro dataset in due set distinti, uno da utilizzare unicamente per l’addestramento e un altro da utilizzare per il test, possiamo farlo utilizzando il metodo train_test_split di scikit-learn.

from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X,Y, test_size=0.3, random_state=0)

Adesso abbiamo tutto ciò che ci serve per costruire il modello, facciamolo utilizzando la classe LinearRegression di scikit-learn:

  • con il metodo fit eseguiamo l’addestramento
  • con il metodo predict eseguiamo la predizione

Queste due semplici API sono comuni tra tutti i modelli definiti in scikit-learn, il ché rende il sostituire un modello con un altro estremamente semplice.

from sklearn.linear_model import LinearRegressionll = LinearRegression()
ll.fit(X_train, Y_train)
Y_pred_train = ll.predict(X_train)
Y_pred_test = ll.predict(X_test)

Congratulazione ! Hai costruito il tuo primo modello di regressione e hai eseguito la tua prima predizione. Adesso bisogna vedere quanto buono è questo modello.
Per farlo dobbiamo definire una metrica che ci permetterà di misurare quanto le predizioni del modello si avvicinano ai valori corretti.
Una metrica semplice che fa proprio questo è l’errore quadratico medio (mean squadred error — MSE)

from sklearn.metrics import mean_squared_errorprint("MSE train: %f" % mean_squared_error(Y_train, Y_pred_train))
print("MSE test: %f" % mean_squared_error(Y_test, Y_pred_test))

Il risultato dovrebbe essere circa 42.16 per il train set e 47.03 per il test set, come vanno interpretati ?

Estraendo la radice quadrata otteniamo un valore che indica mediamente di quanto si è sbagliato il modello. Nel nostro caso, il test set ha ottenuto un MSE di 47 la cui radice quadrata è circa 6.9, considerando che i prezzi delle case sono rappresentati in $1000 questo ci dice che in media il modello ha fatto cilecca per 6900$.

Una metrica più intuitiva è il coefficiente di indeterminazione (anche conosciuto come R-squared score), può essere inteso come una versione standardizzata del MSE e ritorna un punteggio compreso tra 0 e 1 che può essere letto in questo modo:

  • R2_score < 0.3 il modello è inutile.
  • 0.3 < R2_score < 0.5 il modello è scarso.
  • 0.5 < R2_score < 0.7 il modello è discreto.
  • 0.7 < R2_score < 0.9 il modello è buono.
  • 0.9 < R2_score < 1 il modello è ottimo.
  • R2_score = 1 molto probabilmente c’è un errore nel modello.
from sklearn.metrics import r2_scoreprint("R2 train: %f" % r2_score(Y_train, Y_pred_train))
print("R2 test: %f" % r2_score(Y_test, Y_pred_test))

Se hai fatto tutto correttamente dovresti ottenere un punteggio R-squared di circa 0.50 sul train set e 0.435 sul test set.

Il risultato non è così male considerando le poche informazioni che abbiamo utilizzato (solamente il numero di stanze), ma possiamo fare meglio !

Regressione lineare multipla

Una regressione lineare multipla è un modello che utilizza due o più features per l’addestramento.

Proviamo a predire il valore delle abitazioni utilizzando tutte le 13 features presenti nel nostro dataset, ricreiamo i nostri array con features e target, questa volta selezionando tutte le proprietà.

X = boston.drop("MEDV", axis=1).values
Y = boston["MEDV"].values
X_train, X_test, Y_train, Y_test = train_test_split(X,Y, test_size=0.3, random_state=0)

Quando lavoriamo con più features dobbiamo essere sicuri che queste siano comprese in un range di valori comune, per far questo abbiamo due possibilità:

  • Normalizzazione: portiamo tutti i dati in un range compreso tra 0 e 1
  • Standardizzazione: convertiamo i dati in una distribuzione normale con media 0 e deviazione standard 1.

Standardizziamo l’array con le features utilizzando la classe StandardScaler di scikit-learn

from sklearn.preprocessing import StandardScalerss = StandardScaler()
X_train_std = ss.fit_transform(X_train)
X_test_std = ss.transform(X_test)

Adesso possiamo creare il modello esattamente come fatto prima…

from sklearn.linear_model import LinearRegressionll = LinearRegression()
ll.fit(X_train_std, Y_train)
Y_pred_train = ll.predict(X_train_std)
Y_pred_test = ll.predict(X_test_std)

… e calcolare le metriche

print("MSE train: %f" % mean_squared_error(Y_train, Y_pred_train))
print("MSE test: %f" % mean_squared_error(Y_test, Y_pred_test))
print("R2 train: %f" % r2_score(Y_train, Y_pred_train))
print("R2 test: %f" % r2_score(Y_test, Y_pred_test))

Dovresti ottenere i seguenti risultati:

  • MSE del train set ≈ 19.96
  • MSE del test set ≈ 27.16
  • R2 del train set ≈ 0.76
  • R2 del test set ≈ 0.67

Come vedi il risultato è nettamente superiore rispetto a quanto ottenuto con un’unica feature, avendo più informazioni a disposizione l’algoritmo di machine learning è riuscito a individuare pattern migliori e quindi a eseguire predizioni migliori.

Infatti una cosa da tenere sempre a mente è che, spesso, nel machine learning la quantità ma soprattutto la qualità dei dati riveste un ruolo anche superiore a quello degli algoritmi stessi.

Trovi il notebook eseguibile con il tutto il codice presente nell’articolo sulla repository Github dei tutorial di ProfessionAI.

Questo articolo è stato originariamente pubblicato sul blog di ProfessionAI, la prima piattaforma italiana per la formazione online nelle varie discipline legate all’Intelligenza Artificiale, come machine learning, deep learning e data science.

Ti interessa il Machine Learning ? Se vuoi approfondire più nel dettaglio la regressione e altri argomenti come classificazione e clustering allora dai uno sguardo al nostro Corso Pratico sul Machine Learning con Python, disponbile su Udemy a soli 9.90 € per un periodo di tempo limitato.

--

--

Giuseppe Gullo
ProfessionAI

Tech Entrepreneur / Full stack Mobile Developer / A.I & Machine Learning