# Estrazione delle caratteristiche da testo con TF-IDF
# ---------------------------------------------------------------------
# Obiettivo: trasformare un insieme di frasi (corpus) in una matrice
# numerica che rappresenti l'importanza di ogni parola in ciascun
# documento, utilizzando la tecnica TF-IDF (Term Frequency - Inverse
# Document Frequency).

import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer

# Preparazione del corpus di testo
# Il corpus e' l'insieme dei documenti (frasi) che vogliamo analizzare.
# Sono stati aggiunti termini ripetuti ("machine", "learning", "is") e
# termini unici ("fascinating", "crucial", "deep", "subset") per
# mostrare come TF-IDF distingua le parole comuni da quelle rare.
corpus = [
    "Machine learning is fascinating and powerful.",
    "Feature engineering is crucial for machine learning.",
    "Deep learning is a subset of machine learning."
]

# Creazione del vettorizzatore TF-IDF e trasformazione del corpus
# TfidfVectorizer calcola automaticamente sia la frequenza dei termini
# (TF) sia la frequenza inversa di documento (IDF), combinandole in
# un unico punteggio per ogni parola in ogni documento.
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus)

# Esplorazione del vocabolario
# Il vocabolario contiene tutte le parole uniche individuate nel corpus,
# ciascuna associata a un indice di colonna nella matrice risultante.
feature_names = vectorizer.get_feature_names_out()
print("Vocabolario individuato:")
print(feature_names)

# Rappresentazione tabellare con pandas
# Convertiamo la matrice sparsa in un DataFrame per rendere i valori
# TF-IDF piu' leggibili, con le parole come colonne e i documenti come righe.
df_tfidf = pd.DataFrame(X.toarray(), columns=feature_names)
df_tfidf.index = [f"Documento {i + 1}" for i in range(len(corpus))]
print("\nMatrice TF-IDF:")
print(df_tfidf.round(3))

# Interpretazione dei valori TF-IDF
# Confrontiamo il peso medio delle parole che compaiono in piu' documenti
# rispetto a quelle rare, per verificare che TF-IDF penalizzi i termini comuni.
parole_comuni = ["learning", "machine", "is"]
parole_rare = ["fascinating", "crucial", "subset"]

peso_medio_comuni = df_tfidf[parole_comuni].mean().mean()
peso_medio_rare = df_tfidf[parole_rare].mean().mean()

print(f"\nPeso medio parole comuni: {peso_medio_comuni:.3f}")
print(f"Peso medio parole rare: {peso_medio_rare:.3f}")