Codifica delle variabili categoriche: OrdinalEncoder e OneHotEncoder
Convertirà le categorie ordinali in interi e quelle nominali in vettori one-hot, gestendo le categorie sconosciute al momento dell'inferenza.
Codifica delle variabili categoriche: OrdinalEncoder e OneHotEncoder è una lezione Machine Learning Academy gratuita su CoddyKit. Questa è la lezione 3 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é è necessaria la codifica delle variabili categoriche
I modelli di machine learning operano su numeri, non su stringhe. Una colonna contenente valori come 'red', 'green', 'blue' non può essere fornita direttamente a uno stimatore di scikit-learn. Prima dell'addestramento deve convertire le categorie in rappresentazioni numeriche. La scelta del metodo di codifica è molto importante: una codifica inappropriata può introdurre relazioni ordinali fittizie o far esplodere la dimensionalità. Questa lezione tratta i due encoder più importanti: OrdinalEncoder per le categorie ordinate e OneHotEncoder per quelle non ordinate.
import pandas as pd
df = pd.DataFrame({
'size': ['small', 'medium', 'large', 'medium'],
'color': ['red', 'blue', 'green', 'red'],
'price': [10.5, 20.0, 15.0, 18.5]
})
print(df.dtypes)
# size and color are 'object' (string) — must be encoded before modellingCategorie ordinali e nominali
Non tutte le variabili categoriche sono uguali. Le categorie ordinali hanno un ordine significativo: small < medium < large oppure bad < fair < good < excellent. Le categorie nominali non hanno un ordine intrinseco: red, blue, green sono semplicemente etichette. Scegliere la codifica sbagliata crea relazioni false: ad esempio, codificare i colori non ordinati come 0, 1, 2 comunica al modello che blue (1) si trovi in qualche modo tra red (0) e green (2), il che non ha alcun significato. Individui sempre se una variabile è ordinale o nominale prima di codificarla.
# Ordinal: clear ordering
ordinal_example = ['low', 'medium', 'high', 'very high']
# Nominal: no meaningful ordering
nominal_example = ['cat', 'dog', 'bird']
# Wrong approach for nominal: integer encoding implies order
# 0=cat, 1=dog, 2=bird -- model thinks dog is between cat and bird
# Correct approach for nominal: one-hot encoding
# cat -> [1, 0, 0]
# dog -> [0, 1, 0]
# bird -> [0, 0, 1]OrdinalEncoder: associare un ordine agli interi
OrdinalEncoder associa ogni categoria a un intero in base a un ordine specificato. Si fornisce il parametro categories come lista di liste, dove la posizione determina l'intero assegnato. Se non si specifica l'ordine, scikit-learn assegna gli interi in ordine alfabetico, che può coincidere oppure no con l'ordine reale. Specifichi sempre esplicitamente l'ordine delle categorie per le variabili ordinali, così da garantire che il modello acquisisca la relazione corretta tra i valori.
from sklearn.preprocessing import OrdinalEncoder
import numpy as np
X = np.array([['low'], ['high'], ['medium'], ['low'], ['high']])
# Specify order explicitly: low=0, medium=1, high=2
enc = OrdinalEncoder(categories=[['low', 'medium', 'high']])
X_encoded = enc.fit_transform(X)
print('Ordinal encoded:', X_encoded.flatten())
# [0. 2. 1. 0. 2.]OneHotEncoder: variabili dummy per dati nominali
OneHotEncoder crea una colonna binaria per ogni categoria. Per una feature color con i valori red, green, blue, produce tre colonne: color_red, color_green, color_blue, dove per ogni riga esattamente una colonna vale 1 e le altre valgono 0. In questo modo si evita di implicare un ordine. Il compromesso riguarda la dimensionalità: una feature con 100 valori distinti crea 100 nuove colonne. Per impostazione predefinita, OneHotEncoder di scikit-learn elimina una categoria (codifica dummy) per evitare la multicollinearità perfetta nei modelli lineari.
from sklearn.preprocessing import OneHotEncoder
import numpy as np
X = np.array([['red'], ['green'], ['blue'], ['red']])
enc = OneHotEncoder(sparse_output=False) # dense output for readability
X_ohe = enc.fit_transform(X)
print('Categories:', enc.categories_)
print('One-hot encoded:\n', X_ohe)
# [[0. 0. 1.]
# [0. 1. 0.]
# [1. 0. 0.]
# [0. 0. 1.]]Eliminare una categoria: codifica dummy
Quando si utilizza OneHotEncoder con modelli lineari, mantenere tutte le K colonne di una variabile con K categorie introduce multicollinearità perfetta: la somma delle colonne è 1, quindi una qualsiasi colonna è una combinazione lineare delle altre. Questo rende singolare la matrice del disegno (non invertibile). Impostando drop='first' si elimina la prima categoria, lasciando K-1 colonne che descrivono completamente la variabile senza ridondanze. Per i modelli basati su alberi, mantenere tutte le K colonne non crea problemi e talvolta offre risultati leggermente migliori, quindi può utilizzare drop=None.
from sklearn.preprocessing import OneHotEncoder
import numpy as np
X = np.array([['red'], ['green'], ['blue'], ['red']])
# Drop first category to avoid multicollinearity
enc = OneHotEncoder(drop='first', sparse_output=False)
X_ohe = enc.fit_transform(X)
print('Categories kept (first dropped):', enc.get_feature_names_out())
print('Encoded:\n', X_ohe)
# Only 2 columns instead of 3Gestire le categorie sconosciute durante l'inferenza
Una difficoltà del mondo reale: durante l'inferenza può comparire una categoria che non era presente nei dati di training. Per impostazione predefinita, OrdinalEncoder e OneHotEncoder generano un errore per le categorie sconosciute. Imposti handle_unknown='ignore' in OneHotEncoder per produrre righe composte da soli zeri per i valori sconosciuti (il modello esegue la previsione senza quella feature). Per OrdinalEncoder, imposti handle_unknown='use_encoded_value' con unknown_value=-1 per segnalare esplicitamente i valori sconosciuti.
from sklearn.preprocessing import OneHotEncoder
import numpy as np
# Training data: only red and blue seen
X_train = np.array([['red'], ['blue'], ['red']])
X_test = np.array([['green']]) # Unseen at training time
enc = OneHotEncoder(handle_unknown='ignore', sparse_output=False)
enc.fit(X_train)
X_test_enc = enc.transform(X_test)
print('Unknown category encodes as all zeros:', X_test_enc)
# [[0. 0.]] -- no error, unknown silently encoded as zerosTarget encoding per feature ad alta cardinalità
Quando una feature categorica ha centinaia o migliaia di valori distinti, ad esempio codici postali o SKU di prodotto, la codifica one-hot crea una matrice di dimensioni ingestibili. Il target encoding sostituisce ogni categoria con la media della variabile target per quella categoria. In questo modo le feature ad alta cardinalità vengono compresse in una singola colonna. Il rischio è il target leakage: se si utilizza la media calcolata sulle stesse righe usate per l'addestramento, il modello memorizza gli schemi invece di generalizzare. Utilizzi sempre il target encoding cross-fold per prevenire il leakage.
import pandas as pd
import numpy as np
df = pd.DataFrame({
'city': ['NYC', 'LA', 'NYC', 'Chicago', 'LA', 'NYC'],
'churned': [1, 0, 1, 0, 1, 0]
})
# Simple (leaky) target encoding
target_mean = df.groupby('city')['churned'].mean()
df['city_encoded'] = df['city'].map(target_mean)
print(df[['city', 'city_encoded', 'churned']])
# Use cross-fold encoding in practice to avoid leakageCodifica binaria per cardinalità media
La codifica binaria è una soluzione intermedia tra la codifica ordinale e quella one-hot. Ogni codice intero viene convertito nella relativa rappresentazione binaria, producendo log2(K) colonne invece di K colonne. Ad esempio, per 8 categorie servono solo 3 colonne binarie invece di 8 colonne one-hot. Questo riduce significativamente la dimensionalità delle feature con 10–100 categorie. La libreria category_encoders fornisce BinaryEncoder, che gestisce questa trasformazione tramite un'API compatibile con scikit-learn.
# Conceptual example: binary encoding manually
# Category -> Integer -> Binary columns
categories = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
for i, cat in enumerate(categories):
binary = format(i, '03b') # 3 bits for 8 categories
print(f'{cat} -> {i} -> {list(binary)}')
# A -> 0 -> [0, 0, 0]
# B -> 1 -> [0, 0, 1]
# ...
# H -> 7 -> [1, 1, 1]
# 8 categories need only 3 columns (vs 8 with one-hot)Applicare gli encoder in ColumnTransformer
I dataset reali contengono un insieme di colonne numeriche, ordinali e nominali. ColumnTransformer applica trasformazioni diverse a colonne diverse in parallelo e concatena i risultati. Specifichi le colonne ordinali con OrdinalEncoder, quelle nominali con OneHotEncoder e quelle numeriche con StandardScaler. L'output è un'unica matrice numerica ordinata, pronta per qualsiasi stimatore di scikit-learn. Questo è il procedimento standard per la produzione con dataset di tipo misto.
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OrdinalEncoder, OneHotEncoder, StandardScaler
preprocessor = ColumnTransformer([
('num', StandardScaler(), ['age', 'income']),
('ord', OrdinalEncoder(categories=[['low', 'medium', 'high']]), ['risk_level']),
('nom', OneHotEncoder(drop='first', sparse_output=False), ['city', 'product'])
])
# Result: numeric + ordinal encoded + one-hot columns in one matrixNomi delle feature dopo la codifica
Dopo la codifica, la matrice delle feature contiene più colonne rispetto al DataFrame originale e i transformer di scikit-learn tengono traccia dei nuovi nomi. Chiami get_feature_names_out() su ColumnTransformer o OneHotEncoder per recuperare i nomi delle feature generate. Questo è essenziale per l'interpretabilità del modello: sapere quale colonna one-hot corrisponde a quale categoria originale consente di interpretare correttamente l'importanza delle feature nelle Random Forest o i valori SHAP dei modelli di gradient boosting.
from sklearn.preprocessing import OneHotEncoder
import numpy as np
X = np.array([['red', 'small'], ['blue', 'large'], ['green', 'medium']])
enc = OneHotEncoder(sparse_output=False)
enc.fit(X)
print('Feature names:', enc.get_feature_names_out(['color', 'size']))
# ['color_blue' 'color_green' 'color_red' 'size_large' 'size_medium' 'size_small']
X_enc = enc.transform(X)
print('Encoded shape:', X_enc.shape)Pipeline completa di codifica: esempio end-to-end
Ecco una pipeline completa con codifica mista. ColumnTransformer gestisce tre tipi di colonne: le feature numeriche vengono scalate, una feature ordinale viene codificata come intero con un ordine esplicito e le feature nominali diventano colonne one-hot. La pipeline viene quindi sottoposta a cross-validation: la codifica viene riadattata all'interno di ogni fold CV per prevenire il leakage. Questo procedimento funziona con qualsiasi dataset ed è pronto per il deployment dopo l'addestramento sull'intero dataset.
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OrdinalEncoder, OneHotEncoder
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
preprocessor = ColumnTransformer([
('num', StandardScaler(), ['age', 'income']),
('ord', OrdinalEncoder(categories=[['low', 'medium', 'high']]), ['risk']),
('ohe', OneHotEncoder(drop='first', handle_unknown='ignore'), ['city'])
])
pipeline = Pipeline([
('prep', preprocessor),
('clf', LogisticRegression(max_iter=500))
])
scores = cross_val_score(pipeline, X, y, cv=5, scoring='accuracy')
print('CV accuracy:', scores.mean().round(3))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: la differenza tra categorie ordinali e nominali e il motivo per cui determina la scelta della codifica, OrdinalEncoder per le variabili ordinate e OneHotEncoder per le variabili nominali, oltre a come gestire le categorie sconosciute e combinare gli encoder in una pipeline con ColumnTransformer. Prossimamente esamineremo come combinare tutti i passaggi di preprocessing con ColumnTransformer.
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 «Codifica delle variabili categoriche: OrdinalEncoder e OneHotEncoder» è gratuita?
Sì — il testo completo di «Codifica delle variabili categoriche: OrdinalEncoder e OneHotEncoder» è 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 «Codifica delle variabili categoriche: OrdinalEncoder e OneHotEncoder»?
Convertirà le categorie ordinali in interi e quelle nominali in vettori one-hot, gestendo le categorie sconosciute al momento dell'inferenza. 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 3 di 4.
Quanto tempo richiede la lezione «Codifica delle variabili categoriche: OrdinalEncoder e OneHotEncoder»?
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
- Gestione dei valori mancanti: eliminare, imputare e segnalare
- Scalatura delle feature: StandardScaler e MinMaxScaler
- Codifica delle variabili categoriche: OrdinalEncoder e OneHotEncoder
- Combinare i passaggi con ColumnTransformer