Tutorial > Machine Learning adoperando Python – Regression - Pt 1

Machine Learning adoperando Python – Regression - Pt 1

Pubblicato il: 09 marzo 2021

Machine Learning ML Python Regression

Regression

In questo percorso di apprendimento, finora, abbiamo connesso programmazione, matematica e analisi statistica per mettere insieme le fondamenta per il Machine Learning (ML). In questo capitolo studieremo la Regressione applicata al Machine Learning.

Analisi dei dati basata sulla Regressione

L’analisi di regressione è un insieme di tecniche statistiche che vengono usate per stimare le relazioni tra una singola variabile dipendente e una o più variabili indipendenti. Oltre che per classificare i dati, l’analisi di regressione viene usata anche per stimare la forza delle relazioni tra le variabili ed è anche utile a costruire previsioni per i valori futuri di queste variabili.

Il diagramma illustra le varie tecniche statistiche di un'analisi di regressione. Quest'ultima si divide in regressione a variabile singola e regressione multivariata. La regressione a variabile singola è composta dalla regressione lineare; la regressione multivariata si compone di regressione lineare multipla e regressione non lineare polinomiale.

Non-collinearità: Nell’analisi di regressione ci si aspetta che le variabili indipendenti presentino tra loro un grado minimo di correlazione. Inoltre, anche nel caso in cui queste esibiscano una correlazione molto elevata, diventa piuttosto difficile valutare quali siano le reali relazioni che sussistono tra di loro. Pertanto, un requisito obbligatorio per la buona riuscita di un’analisi di regressione è la minimizzazione della collinearità tra variabili indipendenti.

Regressione lineare a singola variabile

Espressione: Y = a + bX + epsilon, dove
Y – Variabile dipendente
X – Variabile indipendente o esplicativa
a – Intercetta
b – Pendenza
epsilon – Errore

REGRESSIONE MULTIVARIATA

Espressione: Y = a + bX1 + cX2 + dX3 + epsilon, dove
Y – Variabile dipendente
X1, X2, X3 – Variabili indipendenti o esplicative
a – Intercetta
b, c, d – Pendenze
epsilon – Errore

Modelli Ensemble

I metodi Ensemble sono tecniche statistiche che prevedono l’applicazione di più algoritmi di apprendimento al fine di migliorare i risultati predetti dai dati in ingresso, rispetto a un modello preso singolarmente. A differenza delle tradizionali tecniche ensemble statistiche, i modelli di machine learning lavorano con un numero limitato di modelli specifici.

Vediamo un esempio per capire il funzionamento dei modelli Ensemble. Quando si vuole acquistare un’auto è molto difficile che si scelga di acquistare la prima auto vista. Al contrario preferiamo valutare varie alternative e diverse fonti per comprendere bene le differenze tra le auto in modo da scegliere la migliore, cioè quella che si adatta meglio alle nostre esigenze. La stessa cosa viene fatta dagli algoritmi Ensemble di Machine Learning durante l’addestramento, sia per modelli di classificazione che di regressione.

Apprendimento supervisionato e importanza dell’Ensemble

Gli algoritmi di apprendimento supervisionato si muovono all’interno di uno spazio d’ipotesi predefinito per apprendere gli input e gli output e per generare i risultati. I modelli ensemble, nella ricerca di risultati migliori, combinano insieme più classi d’ipotesi.

Tecniche Ensemble

Vediamo le principali metodologie di implementazione delle tecniche ensemble negli algoritmi di ML.

  • Voto di maggioranza: questo metodo viene usato solitamente per i problemi di classificazione, dove si vanno a considerare più scenari predittivi. La predizione di ogni singolo modello è un “voto” e come output finale dell’ensemble si sceglie il voto di maggioranza, cioè il valore che è stato predetto dal maggior numero di modelli.
  • Media: come suggerisce anche il nome, si usa il problema del calcolo della media e si considerano quindi algoritmi diversi per ottenere più predizioni per il problema. Infine, si prende come risultato la media di queste predizioni.
  • Media ponderata: un’estensione della tecnica della media è quella della media pesata. A ogni singola predizione viene assegnato un peso di importanza. Ad esempio, se un risultato sperimentale è dato da un docente esperto in un certo campo di ricerca, il suo valore avrà un peso sicuramente maggiore rispetto al risultato di qualcuno che è nuovo in quel campo. Allo stesso modo si pesano i risultati dei modelli di ensemble in base alla conoscenza a priori che abbiamo sulla loro affidabilità.

Vediamo come implementare le tecniche Ensemble in Python:


# Consideriamo un dataset di training e usiamo 3 tecniche diverse – Decision Tree, KNN e Regressione logistica
model_one = sklearn.tree.DecisionTreeClassifier()
model_two = sklearn.neighbors.KNeighborsClassifier()
model_three = sklearn.linear_model.LogisticRegression()

# Fittiamo i tre modelli sugli stessi dati e calcoliamo separatamente i risultati
model_one.fit(x_train,y_train)
model_two.fit(x_train,y_train)
model_three.fit(x_train,y_train)

prediction_one = model_one.predict(x_test)
prediction_two = model_two.predict(x_test)
prediction_three = model_three.predict(x_test)

# Un modo per usare l’algoritmo max voting è di usare la moda dei risultati 
from statistics import mode
final_pred = np.array([])
for i in range(0,len(x_test)):
    final_pred = np.append(final_pred, mode([pred1[i], pred2[i], pred3[i]]))

# Anche scikit–learn fornisce un metodo VotingClassifier() per effettuale il max voting
# Il VotingClassifier è un classificatore “soft” di voto/maggioranza per estimatori non corretti
# Variabile estimators, sono liste di tuple (str, estimator) – quando si chiama il metodo VotingClassifier(), all’interno degli attributi di classe vengono memorizzate le copie degli estimatori originali
# Variabile voting {'hard', 'soft'}, default = 'hard' – ha due possibili argomenti. Per ottenere il voto di maggioranza, hard utilizza le etichette attese delle classi, mentre soft utilizza l'argmax delle probabilità predette e genera le etichette per le classi.
from sklearn.ensemble import VotingClassifier
model_one = LogisticRegression(random_state=2)
model_two = tree.DecisionTreeClassifier(random_state=2)
model_final = VotingClassifier(estimators=[('lr', model_one), ('dt', model_two)], voting='hard')
model_final.fit(x_train,y_train)
model_final.score(x_test,y_test)

# Per calcolare la media del modello ensemble, prendiamo i 3 risultati dei 3 diversi modelli e calcoliamone la media
final_prediction=(prediction_one + prediction_two + prediction_three) / 3

# In maniera simile, per calcolare la media pesata, assegnamo dei pesi ai risultati e poi facciamo la media
final_prediction=(prediction_one * 0.3 + prediction_two * 0.4 + prediction_three * 0.7) 

I modelli Ensemble sono utili nell’analisi di regressione in quanto modellano lo scenario migliore e calcolano le predizioni combinando i risultati di più modelli.

Il diagramma illustra come, a partire da un insieme di dati etichettato e/o non etichettato, si possano applicare tre modelli, ognuno dei quali con una propria predizione, e che attraverso delle tecniche di Ensamble, questi possano essere integrati in una predizione unica finale.
Rappresentazione dell’Ensemble

Le tecniche Ensemble usano una combinazione di più algoritmi di addestramento e delle rispettive predizioni per costruire la proiezione migliore e più adeguata possibile per i dati di test.

Algoritmi di Regressione per il Machine Learning

Per implementare gli algoritmi di regressione in Python useremo la libreria scikit-learn, già usata in precedenza per costruire i classificatori. Vediamo alcune importanti funzioni che ci serviranno per costruire un regressore.

  • Regressore Lineare: la regressione lineare, o regressione singola, tenta di costruire un grafico lineare con due variabili, e viene usata per determinare le relazioni concrete tra le due variabili. Un algoritmo di regressione lineare in sostanza traccia la retta che si avvicina di più ai punti su entrambi gli assi. Per determinare la funzione della retta si calcolano la pendenza e l’intercetta, in modo da minimizzare l’errore.
    Uso della regressione lineare nella vita reale: quando ad esempio si vuole predire l’erosione del suolo, esistono diversi fattori esterni, come le variazioni di temperatura e l’attraversamento degli animali, che però non incidono in maniera significativa. Ciò che invece ha una relazione diretta con l’erosione del suolo sono le precipitazioni. Dunque, la regressione lineare permette di predire i livelli di erosione del suolo in base alle precipitazioni.
  • Regressore Multivariato: quando le variabili indipendenti sono più di una, si usano algoritmi di regressione multipla, che possono essere lineari o non lineari. Questo tipo di regressione si basa sull’assunzione che esista una qualche relazione tra le variabili indipendenti e la variabile dipendente incognita.
    Uso della regressione multipla nella vita reale: nella medicina, è importante predire le variazioni di pressione sanguigna nei pazienti, per comprendere diverse malattie. La predizione della pressione sanguigna è un esempio di regressione multipla. Infatti, per predire la pressione sanguigna di un campione di popolazione, si mette in relazione la variabile dipendente (pressione sanguigna) con le variabili indipendenti che possono determinarla, come l’altezza, il peso, l’età, il genere e le ore settimanali di esercizio fisico.

Implementare la Regressione in Python

Per implementare gli algoritmi di regressione con Python, continuiamo a usare la libreria scikit-learn. Ecco alcune funzioni importanti per la costruzione di questi algoritmi.

Regressione Lineare:


# L’obiettivo di questo modello di regressione lineare è di predire il peso di varie specie di pesci in un negozio
# Usiamo il Fish Market dataset di Kaggle 
# Link – (https://www.kaggle.com/burhanuddinraja/best–fish–from–the–data)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# Importiamo il csv ed esportiamo il dataset
input_data = pd.read_csv('Fish.csv')
input_data.head()
input_data.info()
input_data.describe()

>>>
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 159 entries, 0 to 158
Data columns (total 7 columns):
 #   Column   Non–Null Count  Dtype  
–––  ––––––   ––––––––––––––  –––––  
 0   Species  159 non–null    object 
 1   Weight   159 non–null    float64
 2   Length1  159 non–null    float64
 3   Length2  159 non–null    float64
 4   Length3  159 non–null    float64
 5   Height   159 non–null    float64
 6   Width    159 non–null    float64
dtypes: float64(6), object(1)
memory usage: 8.8+ KB
>>>
Weight	Length1	Length2	Length3	Height	Width
count	159.000000	159.000000	159.000000	159.000000	159.000000	159.000000
mean	398.326415	26.247170	28.415723	31.227044	8.970994	4.417486
std	357.978317	9.996441	10.716328	11.610246	4.286208	1.685804
min	0.000000	7.500000	8.400000	8.800000	1.728400	1.047600
25%	120.000000	19.050000	21.000000	23.150000	5.944800	3.385650
50%	273.000000	25.200000	27.300000	29.400000	7.786000	4.248500
75%	650.000000	32.700000	35.500000	39.650000	12.365900	5.584500
max	1650.000000	59.000000	63.400000	68.000000	18.957000	8.142000

input_data=input_data[['Species','Length1','Length2','Length3','Height','Width','Weight']]
input_data.head()
>>>
Species	Length1	Length2	Length3	Height	Width	Weight
0	Bream	23.2	25.4	30.0	11.5200	4.0200	242.0
1	Bream	24.0	26.3	31.2	12.4800	4.3056	290.0
2	Bream	23.9	26.5	31.1	12.3778	4.6961	340.0
3	Bream	26.3	29.0	33.5	12.7300	4.4555	363.0
4	Bream	26.5	29.0	34.0	12.4440	5.1340	430.0
# Selezioniamo le righe e le colonne per l’etichettatura
x_axis = input_data.iloc[:,:–1]
y_axis = input_data.iloc[:,–1]

# Per rappresentare numericamente i dati categorici, importiamo il One Hot Encoder di sklearn
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
col_trans = ColumnTransformer(transformers=[('encoder',OneHotEncoder(),[0])],remainder='passthrough')
x_axis = np.array(col_trans.fit_transform(x_axis))
print(x_axis)

# Splittiamo il dataset e addestriamo un regressore lineare sui dati di training
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x_axis, y_axis, test_size=0.33, random_state = 2)

from sklearn.linear_model import LinearRegression
lin_regressor = LinearRegression()
lin_regressor.fit(x_train, y_train)

# Usiamo il modello addestrato per predire i valori di y dal test set e stampiamo i pesi predetti
y_pred = lin_regressor.predict(x_test)
y_pred
>>>
array([62.62, 53.41,  7.73, 61.65, 50.09, 65.8 , 52.7 , 97.17, 90.23,
       67.31, 97.52, 82.12, 72.39, 32.28, 31.12, 35.78, 58.51, 76.83,
       76.07, 58.52, 25.79,  7.95, 41.28, 26.68, 79.01, 59.79, 33.98,
       31.34, 35.74, 50.51, 96.57, 68.57, 92.2 , 64.9 , 32.69, 42.17,
       86.01, 69.66, 31.41, 41.04,  7.4 , 29.87, 48.52, 22.6 ,  8.38,
       74.9 , 79.01, 66.9 , 48.02, 82.43, 30.17, 46.04, 78.89])

# Tracciamo le rette per mappare l’input nell’output
plt.scatter(x_test[:,0], y_test, color='blue')
plt.plot(x_test[:,0], y_pred, color='green', linewidth=3)
plt.xticks(())
plt.yticks(())
plt.show()

>>>
Il grafico con le rette generate dal blocco di codice di esempio.

Nella seconda parte di questo capitolo continuiamo la nostra esposizione della Regressione.