Une façon de transformer un texte en chiffres : chaque mot reçoit un poids d'autant plus fort qu'il est fréquent dans le document et rare dans le reste du corpus. C'est la base historique des moteurs de recherche et de la classification de texte, encore imbattable en rapidité et en transparence.
Dans un dossier de réclamations, le mot « le » apparaît partout et ne dit rien. Le mot « remboursement » n'apparaît que dans certaines : c'est lui qui caractérise ces documents.
C'est la fréquence du terme (TF, term frequency) : combien de fois « retard » apparaît dans cet avis.
La fréquence inverse (IDF, inverse document frequency) vaut le logarithme du nombre de documents divisé par le nombre de documents qui contiennent le mot. Un mot présent partout tombe près de zéro.
Le poids final est TF × IDF. Chaque document devient un vecteur, et deux documents se ressemblent si leurs vecteurs pointent dans la même direction (similarité cosinus).
Une à trois phrases par avis, de la livraison au service après-vente. Aucune étiquette n'est nécessaire : TF-IDF travaille sur le texte seul.
L'équipe qualité tape « livraison en retard » et obtient les avis les plus proches, triés par score de similarité. Sur le jeu d'exemple, les avis sur les colis arrivés avec deux semaines de retard sortent en tête.
On vérifie à la main que les 5 ou 10 premiers avis répondent bien à la requête (précision au rang k). Sur le jeu d'exemple, des avis « Livraison rapide » remontent aussi : TF-IDF voit le mot « livraison », pas le sens de la phrase.
Tout se joue dans la préparation du texte. Noms donnés pour R (text2vec) et Python (scikit-learn).
Retirer « le », « de », « et ». L'IDF les écrase déjà, mais les retirer allège la matrice. scikit-learn ne fournit une liste qu'en anglais : pour le français, il faut fournir la sienne.
Compter aussi les paires de mots (« pas satisfait », « service client »). Souvent le meilleur gain, au prix d'un vocabulaire plus gros.
Ignorer les mots trop rares (fautes de frappe) ou trop fréquents. min_df=2 ou 5 suffit en général.
Remplace la fréquence brute par 1 + log(fréquence). Un mot répété dix fois ne pèse plus dix fois plus. Utile sur les documents longs.
# Recherche dans les avis clients : TF-IDF en R
library(text2vec)
avis <- read.csv("avis_clients.csv")
# Découpage en mots, en minuscules
jetons <- itoken(avis$texte, preprocessor = tolower, tokenizer = word_tokenizer)
vectoriseur <- vocab_vectorizer(create_vocabulary(jetons))
dtm <- create_dtm(jetons, vectoriseur)
# Pondération TF-IDF : fréquent dans l'avis, rare dans le corpus
tfidf <- TfIdf$new(norm = "l2")
matrice <- fit_transform(dtm, tfidf)
cat("Avis x mots :", dim(matrice), "\n")
# Moteur de recherche : les avis les plus proches d'une requête
requete <- itoken("livraison en retard", preprocessor = tolower, tokenizer = word_tokenizer)
q <- transform(create_dtm(requete, vectoriseur), tfidf)
score <- as.numeric(as.matrix(sim2(matrice, q, method = "cosine")))
resultats <- data.frame(score = round(score, 2), avis = avis$texte)
resultats <- resultats[!duplicated(resultats$avis), ]
print(head(resultats[order(-resultats$score), ], 5), row.names = FALSE)
# Recherche dans les avis clients : TF-IDF en Python
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
avis = pd.read_csv("avis_clients.csv")
# Une ligne par avis, une colonne par mot, un poids TF-IDF dans chaque case
vectoriseur = TfidfVectorizer()
matrice = vectoriseur.fit_transform(avis["texte"])
print("Avis x mots :", matrice.shape)
# Les mots les plus rares (IDF élevé) et les plus banals (IDF faible)
idf = pd.Series(vectoriseur.idf_, index=vectoriseur.get_feature_names_out()).sort_values()
print("Mots banals :", list(idf.index[:5]))
print("Mots rares :", list(idf.index[-5:]))
# Moteur de recherche : les 5 avis les plus proches d'une requête
requete = vectoriseur.transform(["livraison en retard"])
avis["score"] = cosine_similarity(requete, matrice).ravel().round(2)
print(avis.drop_duplicates("texte").nlargest(5, "score")[["score", "texte"]].to_string(index=False))
On multiplie la fréquence du mot dans le document (TF) par le logarithme du nombre total de documents divisé par le nombre de documents qui contiennent le mot (IDF). Les bibliothèques ajoutent des variantes de lissage : scikit-learn utilise par défaut ln((1 + n) / (1 + df)) + 1, puis normalise chaque vecteur.
TF-IDF trouve les documents qui partagent les mots de la requête, vite et de façon explicable. Les embeddings trouvent aussi ceux qui disent la même chose avec d'autres mots. En pratique, beaucoup de moteurs combinent les deux (recherche hybride).
Oui. Il reste la référence rapide pour classer des milliers de textes, filtrer un corpus avant un traitement coûteux ou compléter une recherche par embeddings dans un RAG. Il ne demande ni GPU ni appel à une API.
Des vecteurs appris par un réseau de neurones, où « colis » et « paquet » sont proches. Plus pertinents, moins transparents.
Voir la fiche → le classifieur associéLe partenaire historique de TF-IDF pour classer des textes : spam, sentiment, routage de tickets.
Voir la fiche → trouver les thèmesPart des mêmes comptages de mots, mais pour regrouper les documents en thèmes sans étiquettes.
Voir la fiche →Dataistudio forme les équipes au machine learning et à l'IA, sur des cas concrets.
Nous utilisons des cookies de mesure d'audience et de suivi publicitaire pour comprendre la fréquentation du site et l'efficacité de nos annonces. Rien n'est déposé sans votre accord. En savoir plus