from sklearn.preprocessing import LabelEncoder

# Preparazione dei dati
# Definiamo una lista di dati categorici testuali (genere), tipico esempio
# di variabile nominale che deve essere convertita in formato numerico
# prima di essere utilizzata da un algoritmo di Machine Learning
generi = ['Male', 'Female', 'Female', 'Male']

# Creazione dell'encoder
# Istanziamo l'oggetto LabelEncoder. In questa fase l'oggetto non ha
# ancora appreso nulla: non conosce ancora le categorie presenti nei dati
label_encoder = LabelEncoder()

# Addestramento e trasformazione
# fit_transform esegue due operazioni in un unico passaggio:
# 1) fit: individua le categorie uniche e le ordina alfabeticamente
# 2) transform: assegna a ciascuna categoria un numero intero progressivo
etichette_codificate = label_encoder.fit_transform(generi)
print("Etichette codificate:", etichette_codificate)

# L'attributo classes_ mostra le categorie originali nell'ordine
# utilizzato per la codifica (ordine alfabetico crescente)
print("Classi individuate:", label_encoder.classes_)

# Mappatura leggibile e decodifica inversa
# Costruiamo un dizionario esplicito per rendere subito chiara
# la corrispondenza tra ciascuna categoria testuale e il relativo codice numerico
mappatura = dict(zip(label_encoder.classes_, label_encoder.transform(label_encoder.classes_)))
print("Mappatura classe -> numero:", mappatura)

# inverse_transform riporta i valori numerici alle etichette testuali originali
# operazione fondamentale per interpretare le predizioni di un modello
decodificato = label_encoder.inverse_transform(etichette_codificate)
print("Valori decodificati:", decodificato)

# Nota didattica: con solo due categorie l'ordine numerico non crea ambiguità,
# ma con tre o più categorie nominali (es. 'Rosso', 'Verde', 'Blu') l'ordine
# alfabetico implicito potrebbe essere erroneamente interpretato come una
# relazione d'ordine dall'algoritmo: in quei casi è preferibile OneHotEncoder