Machine Learning Academy · Lezione

Scalatura delle feature: StandardScaler e MinMaxScaler

Adatterà StandardScaler e MinMaxScaler ai dati di addestramento, trasformerà separatamente i dati di test e comprenderà perché adattare il modello ai dati di test causa data leakage.

Lezione 2 di 413 passaggi

Scalatura delle feature: StandardScaler e MinMaxScaler è una lezione Machine Learning Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Machine Learning Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Machine Learning Academy include 4 lezioni in totale.

Perché la scalatura delle feature è importante

Molti algoritmi di machine learning sono sensibili alla scala delle feature di input. Se una feature varia da 0 a 1000 e un'altra da 0 a 1, i modelli basati sulla distanza, come KNN e SVM, saranno dominati dalla feature con la scala maggiore. Anche gli algoritmi di discesa del gradiente convergono molto più rapidamente quando le feature hanno una scala simile. I modelli basati su alberi, come Random Forest e XGBoost, sono invarianti rispetto alla scala e non richiedono la scalatura, ma quasi tutti gli altri algoritmi ne traggono vantaggio.

import numpy as np

# Without scaling: 'income' dominates 'age'
X = np.array([
    [25, 50000],
    [35, 80000],
    [45, 120000]
])

# Distance between row 0 and row 1 (Euclidean)
dist = np.sqrt((25-35)**2 + (50000-80000)**2)
print('Distance dominated by income:', dist)
# age contributes 100, income contributes 900,000,000 to squared distance

StandardScaler: normalizzazione dello z-score

StandardScaler trasforma ogni feature in modo che abbia media nulla e varianza unitaria, applicando la formula: z = (x - mean) / std. Questa procedura viene chiamata standardizzazione o normalizzazione dello z-score. I valori risultanti sono centrati intorno a 0 e non hanno un intervallo fisso. StandardScaler è la scelta predefinita per la maggior parte degli algoritmi, tra cui regressione logistica, SVM e reti neurali, soprattutto quando la distribuzione della feature è approssimativamente gaussiana.

from sklearn.preprocessing import StandardScaler
import numpy as np

X = np.array([[25, 50000], [35, 80000], [45, 120000]], dtype=float)

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

print('Scaled data:\n', X_scaled)
print('Mean per feature:', X_scaled.mean(axis=0))  # ~[0, 0]
print('Std per feature:', X_scaled.std(axis=0))    # ~[1, 1]

Come StandardScaler memorizza le statistiche

Dopo aver chiamato fit(), StandardScaler memorizza le statistiche del set di addestramento in scaler.mean_ e scaler.scale_ (deviazione standard). Queste stesse statistiche vengono utilizzate quando si chiama transform() su nuovi dati: ciò significa che il set di test viene scalato utilizzando i parametri del set di addestramento, non i propri. Questo è il comportamento corretto: in produzione si ricevono singoli campioni uno alla volta e occorre scalarli utilizzando le statistiche calcolate durante l'addestramento.

from sklearn.preprocessing import StandardScaler
import numpy as np

X_train = np.array([[1, 200], [2, 400], [3, 600]], dtype=float)
X_test  = np.array([[4, 800]], dtype=float)

scaler = StandardScaler()
scaler.fit(X_train)  # Learn mean and std from training data ONLY

print('Learned mean:', scaler.mean_)
print('Learned scale:', scaler.scale_)

X_train_s = scaler.transform(X_train)
X_test_s  = scaler.transform(X_test)  # Uses SAME training statistics
print('Test scaled:', X_test_s)

MinMaxScaler: riscalare a un intervallo fisso

MinMaxScaler comprime ogni feature in un intervallo specificato, in genere [0, 1], utilizzando la formula: x_scaled = (x - x_min) / (x_max - x_min). A differenza di StandardScaler, preserva la forma relativa della distribuzione e gestisce bene i dati non gaussiani. È sensibile ai valori anomali: un singolo valore estremo può comprimere tutti gli altri valori vicino a zero o a uno. MinMaxScaler è molto utilizzato per le reti neurali e per i valori dei pixel delle immagini (scalati nell'intervallo [0, 1]).

from sklearn.preprocessing import MinMaxScaler
import numpy as np

X = np.array([[10], [20], [30], [40], [50]], dtype=float)

scaler = MinMaxScaler(feature_range=(0, 1))
X_scaled = scaler.fit_transform(X)

print('MinMax scaled:', X_scaled.flatten())
# [0.0, 0.25, 0.5, 0.75, 1.0]

# Custom range: scale to [-1, 1]
scaler2 = MinMaxScaler(feature_range=(-1, 1))
print('[-1,1] scaled:', scaler2.fit_transform(X).flatten())

RobustScaler: gestire i valori anomali

RobustScaler esegue la scalatura utilizzando la mediana e l'intervallo interquartile (IQR) invece della media e della deviazione standard. Poiché la mediana e l'IQR non sono influenzati dai valori estremi, RobustScaler è una scelta migliore quando i dati contengono outlier significativi. La formula è: x_scaled = (x - median) / IQR. Utilizzi RobustScaler quando non può rimuovere gli outlier e vuole che abbiano un'influenza minima sui valori scalati passati al modello.

from sklearn.preprocessing import RobustScaler
import numpy as np

# Data with outlier at 1000
X = np.array([[1], [2], [3], [4], [1000]], dtype=float)

from sklearn.preprocessing import StandardScaler, RobustScaler

std_s = StandardScaler().fit_transform(X)
rob_s = RobustScaler().fit_transform(X)

print('StandardScaler (outlier squishes others):')
print(std_s.flatten())
print('RobustScaler (outlier isolated):')
print(rob_s.flatten())

Scegliere lo scaler corretto

Ecco una guida rapida alla scelta: utilizzi StandardScaler quando i dati sono approssimativamente gaussiani e non presentano outlier estremi: è l'impostazione predefinita più sicura. Utilizzi MinMaxScaler quando ha bisogno di valori in un intervallo fisso, ad esempio per dati relativi a immagini o algoritmi che richiedono input nell'intervallo [0, 1]. Utilizzi RobustScaler quando sono presenti outlier significativi, come nei dati finanziari con picchi dovuti alle frodi. Per i modelli basati su alberi (Random Forest, XGBoost, LightGBM), eviti del tutto la scalatura: non offre alcun vantaggio e aggiunge complessità non necessaria.

from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler

# Decision helper
def pick_scaler(has_outliers, needs_fixed_range, is_tree_model):
    if is_tree_model:
        return 'No scaling needed'
    elif has_outliers:
        return 'RobustScaler'
    elif needs_fixed_range:
        return 'MinMaxScaler'
    else:
        return 'StandardScaler'

print(pick_scaler(False, False, False))  # StandardScaler
print(pick_scaler(True, False, False))   # RobustScaler
print(pick_scaler(False, True, False))   # MinMaxScaler
print(pick_scaler(False, False, True))   # No scaling needed

Adattamento sui dati di test: la trappola del data leakage

Un errore comune consiste nel chiamare fit_transform() sul set di test, calcolando così una nuova media e una nuova deviazione standard dai dati di test. Si tratta di una forma di data leakage, perché lo scaler viene influenzato dai valori del set di test. Il procedimento corretto è: fit(X_train) → transform(X_train) → transform(X_test). Anche un piccolo miglioramento dell'accuratezza dovuto a questa perdita può portare a deployment in produzione eccessivamente ottimistici, che falliscono su dati realmente mai osservati.

from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
import numpy as np

X = np.random.randn(100, 3)
y = (X[:, 0] > 0).astype(int)

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

scaler = StandardScaler()

# CORRECT: fit on train, transform both
scaler.fit(X_train)
X_train_s = scaler.transform(X_train)
X_test_s  = scaler.transform(X_test)

# WRONG (leakage):
# scaler.fit_transform(X_test)  <- never do this

Scalatura all'interno di una pipeline

Il modo più efficace per evitare il data leakage durante la scalatura consiste nell'inserire lo scaler in una Pipeline di scikit-learn. Quando la pipeline viene adattata con cross_val_score o GridSearchCV, in ogni fold lo scaler viene adattato esclusivamente sulla parte di training di quel fold. Il fold di test non viene mai utilizzato durante l'adattamento. Questo è il procedimento pronto per la produzione: i passaggi di preprocessing e modellazione vengono raggruppati, rendendo il deployment semplice come chiamare pipeline.predict(X_new).

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)

pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('clf', LogisticRegression(max_iter=200))
])

# Scaler fitted only on train fold in each CV iteration
scores = cross_val_score(pipe, X, y, cv=5)
print('CV accuracy:', scores.mean().round(3))

Trasformazione inversa: tornare alla scala originale

Dopo aver effettuato le previsioni, potrebbe essere necessario riconvertirle alla scala originale: ad esempio, un modello dei prezzi delle abitazioni addestrato su prezzi trasformati con il logaritmo deve restituire prezzi in euro. Sia StandardScaler sia MinMaxScaler forniscono inverse_transform() per annullare la scalatura. Applichi la trasformazione inversa solo alla variabile target se questa è stata scalata prima dell'addestramento. In genere le feature non devono essere trasformate inversamente, perché vengono utilizzate internamente dal modello.

from sklearn.preprocessing import StandardScaler
import numpy as np

y_train = np.array([100000, 200000, 300000, 400000], dtype=float).reshape(-1, 1)

target_scaler = StandardScaler()
y_scaled = target_scaler.fit_transform(y_train)
print('Scaled target:', y_scaled.flatten())

# After predicting in scaled space:
y_pred_scaled = np.array([[0.5]])
y_pred_original = target_scaler.inverse_transform(y_pred_scaled)
print('Prediction in original scale:', y_pred_original)

Scalatura di dati sparsi con MaxAbsScaler

Le matrici sparse, comuni nella classificazione del testo con vettori TF-IDF, non devono essere scalate con StandardScaler o MinMaxScaler, perché il centering distrugge la sparsità trasformando la maggior parte degli zeri in valori diversi da zero, vanificando lo scopo dell'archiviazione sparsa. MaxAbsScaler scala ogni feature in base al suo valore assoluto massimo, mappando i valori nell'intervallo [-1, 1] senza eseguire il centering, e preserva la struttura sparsa. Utilizzi sempre MaxAbsScaler quando lavora con matrici di feature sparse ottenute da vettorizzatori come TfidfVectorizer.

from sklearn.preprocessing import MaxAbsScaler
from scipy.sparse import csr_matrix
import numpy as np

# Simulated sparse TF-IDF matrix
X_sparse = csr_matrix(np.array([
    [0, 0.5, 0.3, 0],
    [0.8, 0, 0, 0.4],
    [0, 0.2, 0, 0.6]
]))

scaler = MaxAbsScaler()
X_scaled = scaler.fit_transform(X_sparse)
print('Scaled sparse matrix:\n', X_scaled.toarray())
# All values in [-1, 1], sparsity preserved

Confrontare gli scaler su dati reali

Per osservare l'effetto pratico di ogni scaler, confronti fianco a fianco le distribuzioni dei risultati. Dopo la scalatura, l'output di StandardScaler dovrebbe seguire approssimativamente N(0,1), l'output di MinMaxScaler dovrebbe estendersi nell'intervallo [0,1] e l'output di RobustScaler dovrebbe avere mediana pari a 0 e IQR pari a 1. Tracciare gli istogrammi prima e dopo la scalatura conferma che la trasformazione è stata eseguita correttamente. Una buona scalatura delle feature è un prerequisito per un addestramento affidabile del modello, non un'aggiunta facoltativa.

import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
import numpy as np

X = np.random.exponential(scale=100, size=(200, 1))  # Skewed data

scalers = {
    'StandardScaler': StandardScaler(),
    'MinMaxScaler': MinMaxScaler(),
    'RobustScaler': RobustScaler()
}

fig, axes = plt.subplots(1, 4, figsize=(16, 4))
axes[0].hist(X, bins=30); axes[0].set_title('Original')
for ax, (name, sc) in zip(axes[1:], scalers.items()):
    ax.hist(sc.fit_transform(X), bins=30)
    ax.set_title(name)
plt.tight_layout()
plt.show()

Verifica rapida

Verifichi la Sua comprensione dei concetti di Machine Learning con Python presentati in questa lezione.

Riepilogo della lezione

In questa lezione ha imparato: perché la scalatura delle feature è essenziale per gli algoritmi basati sulle distanze e sulla discesa del gradiente, come StandardScaler standardizza a N(0,1) mentre MinMaxScaler comprime i valori nell'intervallo [0,1], e la regola fondamentale di adattare gli scaler solo sui dati di training per prevenire il leakage. Prossimamente esamineremo la codifica delle variabili categoriche con OrdinalEncoder e OneHotEncoder.

Gratis per iniziare

Impara Python con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
30
Lezioni
120

Domande Frequenti

La lezione «Scalatura delle feature: StandardScaler e MinMaxScaler» è gratuita?

Sì — il testo completo di «Scalatura delle feature: StandardScaler e MinMaxScaler» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Machine Learning Academy, passa a CoddyKit PRO. Il corso Machine Learning Academy include 4 lezioni in totale.

Cosa imparerò in «Scalatura delle feature: StandardScaler e MinMaxScaler»?

Adatterà StandardScaler e MinMaxScaler ai dati di addestramento, trasformerà separatamente i dati di test e comprenderà perché adattare il modello ai dati di test causa data leakage. Eserciti Machine Learning Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Machine Learning Academy?

Non è richiesta alcuna esperienza precedente. Machine Learning Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Scalatura delle feature: StandardScaler e MinMaxScaler»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Machine Learning Academy?

Sì. Ogni lezione Machine Learning Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Gestione dei valori mancanti: eliminare, imputare e segnalare
  2. Scalatura delle feature: StandardScaler e MinMaxScaler
  3. Codifica delle variabili categoriche: OrdinalEncoder e OneHotEncoder
  4. Combinare i passaggi con ColumnTransformer
← Torna a Machine Learning Academy