Le TF-IDF (Term Frequency - Inverse Docmuent Frequency) est une technique statistique largement utilisée en recherche d'information et en fouille de textes. Elle permet d'évaluer l'importance d'un terme dans un document au sein d'un corpus. L'idée centrale est qu'un mot est d'autant plus représentatif d'un document qu'il y apparaît fréquemment, mais rarement dans l'ensemble du corpus.
- Décomposition du TF-IDF
1.1 Fréquence du terme (TF)
La fréquence du terme (TF) mesure combien de fois un mot apparaît dans un document. Pour éviter un biais en faveur des documents longs, on normalise généralement cette valeur en la divisant par le nombre total de mots du document. La formule est la suivante :
TF(t, d) = (nombre d'occurrences de t dans d) / (nombre total de mots dans d)
Cependant, certains mots très communs (comme "le", "de", "et") n'apportent pas d'information sur le sujet. À l'inverse, des termes rares sont souvent plus significatifs. C'est là qu'intervient l'IDF.
1.2 Fréquence inverse de document (IDF)
L'IDF mesure la rareté d'un terme dans le corpus. Plus un mot apparaît dans peu de documents, plus son IDF est élevé, ce qui indique un fort pouvoir discriminant. La formule standard est :
IDF(t) = log( (N) / (1 + df(t)) )
Où N est le nombre total de documents et df(t) le nombre de documents contenant le terme t. L'ajout de 1 au dénominateur évite une division par zéro si le terme est absent.
Le score TF-IDF final est le produit des deux :
TF-IDF(t, d) = TF(t, d) * IDF(t)
- Implémentation en Python
Nous allons calculer le TF-IDF sur un petit corpus de quatre documents, d'abord manuellement, puis avec les bibliothèques Gensim et Scikit-learn.
2.1 Implémentation manuelle
Définisosns notre corpus :
corpus = [
"this is the first document",
"this is the second second document",
"and the third one",
"is this the first document"
]
# Découpage des phrases en listes de mots
tokenized_docs = [doc.split() for doc in corpus]
print(tokenized_docs)
Comptons les occurrences de chaque mot par document avec Counter :
from collections import Counter
doc_word_counts = [Counter(tokens) for tokens in tokenized_docs]
print(doc_word_counts)
Implémentons les fonctions TF, IDF et TF-IDF :
import math
def compute_tf(word, word_count):
"""Calcule la fréquence du terme dans un document."""
return word_count[word] / sum(word_count.values())
def compute_idf(word, doc_word_counts):
"""Calcule la fréquence inverse de document."""
nb_docs_with_word = sum(1 for count in doc_word_counts if word in count)
return math.log(len(doc_word_counts) / (1 + nb_docs_with_word))
def compute_tfidf(word, word_count, doc_word_counts):
"""Calcule le score TF-IDF."""
return compute_tf(word, word_count) * compute_idf(word, doc_word_counts)
Affichons les résultats pour chaque document :
for idx, word_count in enumerate(doc_word_counts, 1):
print(f"Document {idx} - Scores TF-IDF :")
scores = {w: compute_tfidf(w, word_count, doc_word_counts) for w in word_count}
sorted_scores = sorted(scores.items(), key=lambda x: x[1], reverse=True)
for word, score in sorted_scores:
print(f"\tMot: {word}, TF-IDF: {round(score, 5)}")
2.2 Avec Gensim
Gensim simplifie le processus en gérant le dictionnaire et le modèle :
from gensim import corpora, models
# Création du dictionnaire (mapping mot -> identifiant)
dictionary = corpora.Dictionary(tokenized_docs)
# Transformation du corpus en format sac de mots (bag-of-words)
bow_corpus = [dictionary.doc2bow(tokens) for tokens in tokenized_docs]
# Entraînement du modèle TF-IDF
tfidf_model = models.TfidfModel(bow_corpus)
# Application du modèle sur le corpus
tfidf_vectors = tfidf_model[bow_corpus]
print(tfidf_vectors)
Note : Gensim filtre automatiquement certains mots (comme les stopwords), ce qui peut réduire le nombre de termes affichés.
2.3 Avec Scikit-learn
Scikit-learn fournit une interface encore plus directe :
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer()
tfidf_matrix = vectorizer.fit_transform(corpus)
# Liste des mots du vocabulaire
print("Vocabulaire :", vectorizer.get_feature_names_out())
# Dictionnaire mot -> index
print("Mapping :", vectorizer.vocabulary_)
# Matrice TF-IDF
print("Matrice :\n", tfidf_matrix.toarray())
- Références
[1] Wikipedia - TF-IDF
[2] Scikit-learn documentation - TfidfVectorizer
[3] Gensim documentation - Models.TfidfModel