Site icon Meccanismo Complesso

Support Vector Regression (SVR) nel Machine Learning con scikit-learn

Support Vector Regression
Support Vector Regression header

La Support Vector Regression (SVR) è una tecnica di regressione che si basa sul concetto di Support Vector Machines (SVM) e mira a trovare una funzione che approssimi i dati di addestramento minimizzando l’errore, ma consentendo anche una certa quantità di errore entro un margine specificato.

La Support Vector Regression

La Support Vector Regression (SVR) è una tecnica derivata dalle Support Vector Machines (SVM), che originariamente sono state sviluppate per problemi di classificazione binaria. Le SVM sono state introdotte da Vladimir Vapnik e Alexey Chervonenkis negli anni ’60 e ’70. Successivamente, l’idea è stata estesa alla regressione, portando alla creazione della SVR. Il passaggio da SVM a SVR coinvolge l’estensione del concetto di Support Vector Machines per gestire problemi di regressione. Nella SVM, l’obiettivo è trovare un iperpiano che massimizzi il margine tra le classi, mentre nella SVR, l’obiettivo è trovare una funzione che approssimi i dati di addestramento entro un certo margine di tolleranza.

La SVR coinvolge la minimizzazione di una funzione di costo che tiene conto sia dell’errore di previsione che della complessità del modello. La funzione obiettivo può essere rappresentata come:

Sotto i vincoli:



Dove:

Aggiungiamo alcune considerazioni da fare:

In sintesi, SVR è una tecnica utile per la regressione che sfrutta i principi delle Support Vector Machines, cercando di trovare una funzione che approssimi i dati di addestramento entro un margine specificato, permettendo al contempo un certo grado di errore.

Se vuoi approfondire l’argomento e scoprire di più sul mondo della Data Science con Python, ti consiglio di leggere il mio libro:

Python Data Analytics 3rd Ed

Fabio Nelli

Esempio di un problema di regressione con Support Vector Regression e scikit-learn

Support Vector Regression (SVR) è incluso nella libreria scikit-learn, che è una delle librerie più utilizzate per il machine learning in Python. Scikit-learn fornisce un’implementazione efficiente e semplice da utilizzare di Support Vector Regression insieme ad altre tecniche di machine learning. Puoi utilizzare la classe SVR di scikit-learn per creare, addestrare e utilizzare modelli di regressione basati su support vector machines (SVM). Ecco un esempio di utilizzo di SVR in Python utilizzando scikit-learn:

from sklearn.svm import SVR
import numpy as np
import matplotlib.pyplot as plt

# Generiamo dati di esempio
X = np.sort(5 * np.random.rand(80, 1), axis=0)
y = np.sin(X).ravel()

# Aggiungiamo rumore ai dati
y[::5] += 3 * (0.5 - np.random.rand(16))

# Addestriamo il modello SVR
svr_rbf = SVR(kernel='rbf', C=100, gamma=0.1, epsilon=0.1)
svr_rbf.fit(X, y)

# Prevediamo sui dati di addestramento
y_pred = svr_rbf.predict(X)

# Visualizziamo i risultati
plt.scatter(X, y, color='darkorange', label='data')
plt.plot(X, y_pred, color='navy', lw=2, label='SVR (RBF kernel)')
plt.xlabel('data')
plt.ylabel('target')
plt.title('Support Vector Regression')
plt.legend()
plt.show()

In questo esempio, la SVR con kernel radiale (RBF) viene utilizzata per approssimare una funzione sinusoidale con dati rumorosi. Per prima cosa si effettua la generazione di dati di esempio. Vengono generati dati di esempio X e y rappresentanti una funzione sinusoidale con rumore aggiunto. Si passa poi alla creazione e all’addestramento del modello SVR.

   svr_rbf = SVR(kernel='rbf', C=100, gamma=0.1, epsilon=0.1)
   svr_rbf.fit(X, y)

Viene creato un modello di Support Vector Regression (SVR) con kernel radiale (RBF) e addestrato utilizzando i dati di addestramento. A questo punto, si effettuano le previsioni e la visualizzazione dei risultati tramite la libreria Matplotlib. L’obiettivo è mostrare come il modello approssima i dati di input, includendo il rumore presente nei dati di addestramento.

Eseguendo il codice sopra si ottiene il seguente grafico.

Problema di Regressione: prevedere il prezzo delle case con Support Vector Regression e scikit-learn

Passiamo ora ad un problema di regressione su di un dataset reale, cioè con valori presi da un contesto reale. Esistono a tal proposito dei dataset già pronti e forniti direttamente da scikit-learn specifici per questi scopi di test e studio dei modelli. Possiamo utilizzare Support Vector Regression (SVR) per un problema di regressione utilizzando il dataset fetch_california_housing fornito da scikit-learn. Il dataset contiene dati sul prezzo medio delle case in diverse regioni della California, insieme a varie caratteristiche delle case stesse. Questo dataset è comunemente utilizzato per scopi di regressione.

import pandas as pd
import numpy as np
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error
import matplotlib.pyplot as plt

housing = fetch_california_housing()

data = pd.DataFrame(data=np.c_[housing['data'], housing['target']], columns=housing['feature_names'] + ['target'])

data.head(10)

Vediamo insieme che tipologia di dati contiene questo dataset:

Il dataset fetch_california_housing è un dataset ampiamente utilizzato nel campo del machine learning e della statistica per scopi di regressione. Contiene dati relativi al prezzo medio delle abitazioni in varie regioni della California, insieme a diverse caratteristiche che descrivono le abitazioni stesse. Ecco una descrizione delle principali caratteristiche del dataset:

Il target di regressione è MedHouseVal che è la mediana del valore delle abitazioni per i blocchi della zona in migliaia di dollari.

In sostanza, ogni riga del dataset rappresenta un blocco (quartiere o zona) della California, e ogni colonna rappresenta una caratteristica di quel blocco.

Questo dataset è spesso utilizzato per scopi di regressione per predire il prezzo medio delle abitazioni in base alle caratteristiche del blocco, rendendolo un buon punto di partenza per esperimenti di machine learning nel contesto della regressione.

Vediamo adesso di applicare SVR per la regressione e ottenere così un modello in grado di prevedere il prezzo medio delle abitazioni.

# Split data into training set and test set
X_train, X_test, y_train, y_test = train_test_split(data.drop('target', axis=1), data['target'], test_size=0.2, random_state=42)

# Standardize features
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# Create the SVR model
svr = SVR(kernel='rbf', C=10, gamma='auto')

# Train the model
svr.fit(X_train_scaled, y_train)

# Make predictions
y_pred = svr.predict(X_test_scaled)

# Calculate the mean square error
mse = mean_squared_error(y_test, y_pred)
print("Mean Squared Error:", mse)

Analizzando il codice, dove aver suddiviso il dataset in training set e testing set, si passa alla standardizzazione delle features utilizzando StandardScaler. La standardizzazione è una pratica comune nel machine learning per rendere le features comparabili, riducendo la scala dei valori delle features. Poi si crea un modello SVR utilizzando il kernel radiale (RBF). C e gamma sono parametri del modello che possono essere regolati per ottimizzare le prestazioni del modello. In questo caso, C è impostato su 10 e gamma è impostato su ‘auto’.

Eseguendo si ottiene il seguente valore:

Mean Squared Error: 0.3236927921625923

Che è un discreto risultato. Se vogliamo vedere graficamente la capacità di previsione del modello rispetto al dataset possiamo aggiungere il seguente codice.

plt.scatter(y_test, y_pred)
plt.plot([0, max(y_test)], [0, max(y_test)], color='red', linestyle='--')  # Aggiungi la linea x = y
plt.xlabel("Actual")
plt.ylabel("Predicted")
plt.title("Actual vs Predicted Prices")
plt.show()

Come possiamo vedere dal grafico, esiste tutta una serie di elementi del dataset che hanno un valore di target maggiore di 5 (in realtà hanno tutti valore 5.0001) dato che sembrerebbe una valutazione di “fuori scala” e quindi sarebbe meglio eliminarli dal dataset di partenza. Aggiungiamo e modifichiamo il codice precedente per tener conto di questo fatto.

# Remove all rows where the 'target' column value is greater than 5
data_cleaned = data.loc[data['target'] <= 5]

# Split data into training set and test set
X_train, X_test, y_train, y_test = train_test_split(data_cleaned.drop('target', axis=1), data_cleaned['target'], test_size=0.2, random_state=42)

Eseguendo questa volta il codice con il dataset ripulito dai fuori scala otteniamo i seguenti risultati:

Mean Squared Error: 0.2733577250854457

Come possiamo vedere l’errore quadratico medio si è ridotto, e quindi siamo andati verso la direzione giusta.

Quando usare SVR nei problemi di regressione?

La scelta del modello dipende da diversi fattori, tra cui la natura dei dati, la dimensionalità del dataset, la distribuzione dei dati, la presenza di relazioni lineari o non lineari tra le features e il target, e le prestazioni desiderate. Ecco alcune situazioni in cui l’uso di Support Vector Regression (SVR) potrebbe essere preferibile rispetto ad altri modelli forniti da scikit-learn:

Tuttavia, è importante notare che SVR potrebbe non essere sempre la scelta migliore. Ad esempio, se il problema di regressione è lineare e non ci sono evidenze di relazioni non lineari tra le features e il target, modelli più semplici come la regressione lineare potrebbero essere più appropriati e computazionalmente meno costosi. Pertanto, è sempre consigliabile esaminare attentamente i dati e sperimentare con diversi modelli per determinare quale funziona meglio per il tuo specifico problema di regressione.

Exit mobile version