Imagine generated using Midjourney, representing the enigma machine

Come scegliere il miglior metodo per codificare variabili categoriali

ovvero non usare one-hot encoding dappertutto.

In questo articolo esamineremo come codificare le variabili categoriali ed evitare problemi di dimensionalità.

Introduzione

Durante i colloqui per i ruoli di Data Scientist, chiedo ai candidati di completare un compito. L’obiettivo è creare un modello di Machine Learning, spesso un classificatore binario. Questa sarà una parte importante del loro lavoro quotidiano. Come parte dei passaggi per completare l’esercizio, è necessario trattare variabili categoriche.

Nella maggior parte dei casi i candidati scelgono la tecnica del one-hot encoding per trattare queste variabili.

Che cos’è il one-hot encoding

Ci sono molti libri e articoli che suggeriscono una tecnica semplice. Questa tecnica trasforma una variabile categoriale in variabili binarie. La variabile binaria indica la presenza di ciascuna categoria nel record.
Facciamo un esempio.

Utilizzando il seguente codice

import pandas as pd

df = pd.DataFrame({
    'ID': [1, 2, 3, 4, 5],
    'colour': ['black', 'yellow', 'red', 'white', 'purple']
})

possiamo creare la tabella

IDcolore
1nero
2giallo
3rosso
4bianco
5viola
Il set di dati iniziale contenente le variabili id ​​e color

Immagina di avere un set di dati semplice come quello sopra, con variabili id ​​e colore. Devi cambiare il colore in una funzione codificata a caldo. Ciò significa che vuoi trasformare il set di dati in qualcosa di simile alla tabella seguente.

IDcolore_nerocolore_giallocolore_rossocolore_biancocolore_viola
110000
201000
300100
400010
500001
Il set di dati iniziale contenente le variabili id ​​e color

Come puoi vedere, abbiamo creato 3 variabili da quella categorica iniziale. Ogni variabile rappresenta un colore, una categoria della variabile originale. Ora capisco perché questo metodo è così popolare. Se ci pensi, è una riga di codice, devi solo eseguirla

df = pd.get_dummies(df)

e tu ti occupi di tutto, vero? Sì, ma questo ha un costo, poiché non esiste un pranzo gratis .

Il costo di codificare tutto con una sola operazione

Quando si trasforma una variabile categoriale utilizzando la codifica one-hot, la maledizione della dimensionalità è il costo principale. Con questo termine ci riferiamo a vari fenomeni che insorgono quando si ha a che fare con dati organizzati in spazi ad alta dimensione.

Possiamo riassumere i principali effetti avversi come:

  • Maggiore scarsità dei dati. Questo è abbastanza intuitivo guardando l’esempio precedente. Abbiamo dovuto creare 3 variabili per rappresentare la variabile originale con 3 categorie. Immagina di avere un set di dati con milioni di record. Ha decine di variabili categoriali, ciascuna con da 10 a 100 categorie. Usando questa tecnica, puoi creare matrici di dati con molti zeri. Ogni record avrà solo una variabile che rappresenta il valore categoriale come 1. Ciò crea una cosiddetta matrice sparsa. La scarsità della matrice rende le attività di clustering e classificazione più impegnative
  • I calcoli diventano più dispendiosi in termini di risorse. A causa della maggiore complessità computazionale con più variabili.
  • L’aggiunta di più dimensioni a un modello di machine learning aumenta il rischio di overfitting . Ciò accade perché più dimensioni danno al modello più gradi di libertà. Pertanto, il modello potrebbe finire per adattare il rumore nei dati anziché il segnale effettivo.
  • Quando le dimensioni aumentano, i modelli di machine learning generalmente hanno prestazioni peggiori . Quando sono presenti più dimensioni, il modello necessita di più dati per funzionare meglio. All’aumentare del numero di dimensioni, lo spazio occupato dei dati cresce rapidamente.

Codificare Variabili Categoriali: Alternative

Quindi, quali alternative abbiamo rispetto alla codifica one-hot? Esploriamo alcuni di essi:

  • Label Encoding :
    • Descrizione : Assegniamo un numero intero a ciascuna categoria
    • Pro : consente di risparmiare spazio poiché utilizza una singola colonna
    • Contro : può introdurre relazioni ordinali dove non ne esistono
    • Esempio :
from sklearn.preprocessing import LabelEncoder

le = LabelEncoder()
df['Label_Encoded'] = le.fit_transform(df['colour'])
IDcoloreEtichetta_codificata
1nero0
2giallo4
3rosso2
4bianco3
5viola1
Esempio di set di dati di LabelEncoder
  • Encoding ordinale :
    • Descrizione : le variabili ordinali hanno un ordine logico, quindi possiamo usare la codifica ordinale invece della codifica delle etichette.
    • Pro : mantiene la natura ordinale della variabile
    • Contro : Non adatto per variabili nominali
    • Esempio : Diciamo che i colori sono in ordine alfabetico e hanno una classifica.
df['colour'].astype('category').cat.codes
IDcoloreOrdinale_codificato
1nero0
2giallo4
3rosso2
4bianco3
5viola1
Esempio di set di dati con Encoding ordinale
  • Encoding della frequenza (o conteggio) :
    • Descrizione : le categorie si rappresentano attraverso le loro occorrenze o il conteggio della frequenza.
    • Pro : mantiene gestibile la forma del set di dati.
    • Contro : Collisioni in cui categorie diverse hanno la stessa frequenza.
    • Esempio :
df['Frequency_Encoded'] = df['colour'].map(df['colour'].value_counts())
IDcoloreFrequenza_codificata
1nero1
2giallo1
3rosso1
4bianco1
5viola1

Esempio di set di dati della codifica di frequenza

Nota : in questo esempio, tutti i colori appaiono solo una volta, quindi la frequenza è 1 per tutti.

  • Codifica target (valore medio) :
    • Descrizione : il valore medio del valore target per la categoria sostituisce la categoria.
    • Pro : acquisisce informazioni sulla relazione tra la categoria e la variabile di destinazione.
    • Contro : rischio di perdita di dati; non adatto per set di dati con un numero limitato di osservazioni.
    • Esempio :
# Python snippet for target encoding
df['Target_Encoded'] = df['colour'].map(df.groupby('colour')['target'].mean())
IDcolorebersaglioTarget_Encoded
1nero1010.0
2giallo2015.0
3rosso3030.0
4bianco4040.0
5viola5050,0
6giallo1015.0
  • Hashing :
    • Descrizione : utilizza una funzione hash per assegnare un numero a diverse categorie. Lo chiamiamo trucco dell’hashing.
    • Pro: utile per gestire molte categorie; larghezza fissa, riducendo la complessità.
    • Contro : collisioni in cui diverse categorie vengono mappate sullo stesso hash.
    • Esempio :
df['Hashed_Value'] = df['colour'].apply(lambda x: hash(x) % 5)
IDcoloreValore_hashed
1nero1
2giallo3
3rosso0
4bianco0
5viola4
Esempio dataset con funzione di hashing
  • Leave-One-Out Encoding:
    • Mi piace usare questo metodo per codificare una categoria, perché mostra la connessione alla variabile target. Per evitare data leakage, troviamo il valore medio del target per una particolare categoria, senza includere il valore target della riga corrente.
    • Pro : riduce il rischio rispetto alla codifica target.
    • Contro : Il calcolo è più intenso.
    • Esempio : in questo esempio aggiungiamo una variabile target
import pandas as pd

df = pd.DataFrame({
    'ID': [1, 2, 3, 4, 5, 6],
    'colour': ['black', 'yellow', 'red', 'white', 'purple', 'yellow'],
    'target': [10, 20, 30, 40, 50, 10]
})
IDcoloretarget
1nero10
2giallo20
3rosso30
4bianco40
5viola50
6giallo10
Il set di dati di input per il Leave-One-Out encoding
def loo_encode(row, df, column, target):
    temp_df = df[df[column] == row[column]]
    temp_df = temp_df[temp_df.index != row.name]
    if temp_df.empty:
        return df[target].mean()
    else:
        return temp_df[target].mean()

df['LOO_Encoded'] = df.apply(loo_encode, args=(df, 'colour', 'target'), axis=1)
IDcoloretargetLOO_Codificato
1nero1026.666667
2giallo2010.000000
3rosso3026.666667
4bianco4026.666667
5viola5026.666667
6giallo1020.000000
La tabella risultato

Spunti di riflessione

Quando si sceglie un metodo di codifica, considerare il tipo di dati (nominali o ordinali), il tipo di modello (ad albero o lineare) e qualsiasi potenziale problema (fuga di dati, relazioni indesiderate). Durante i colloqui, mostrare la conoscenza di queste tecniche può far risaltare un candidato. Dimostra che comprendono bene l’ingegneria delle funzionalità.

Se ti e’ piaciuto questo articolo potrebbe anche piacerti questo:


Pubblicato

in

da

Tag: