Un classifieur qui applique le théorème de Bayes en supposant, naïvement, que les variables sont indépendantes entre elles. Sur du texte, il suffit de compter les mots par classe. Il s'entraîne en une fraction de seconde, marche avec peu d'exemples et sert de référence à battre en classification de texte.
Un trieur de courrier expérimenté : « remboursement », « jamais reçu », « décevant » dans la même lettre, elle part directement au service réclamations.
Sur l'historique, on calcule la fréquence de chaque mot dans les avis négatifs et dans les autres. Un lissage évite qu'un mot jamais vu donne une probabilité nulle.
Pour un nouvel avis, on multiplie les probabilités de ses mots dans chaque classe, comme si chaque mot était un indice indépendant. C'est l'hypothèse naïve.
On combine ce produit avec la fréquence de chaque classe dans l'historique. La classe la plus probable l'emporte.
Une à trois phrases par avis, avec sur l'historique le sentiment déjà connu. L'objectif n'est pas de tout classer, mais d'isoler les avis négatifs pour que le service client réponde vite.
Chaque nouvel avis est marqué « négatif » ou « autre » dès sa réception. Sur le jeu d'exemple, tous les avis négatifs mis de côté sont repérés, avec environ 5 % de fausses alertes parmi les avis signalés.
Un avis négatif oublié est un client mécontent sans réponse ; une fausse alerte coûte une lecture. On suit donc d'abord le rappel (part des négatifs repérés), puis la précision (part des signalés vraiment négatifs).
Presque rien à régler : les choix portent sur la variante et la représentation du texte. Noms donnés pour R (naivebayes) et Python (scikit-learn).
Multinomial pour des comptages de mots, Bernoulli pour la présence ou l'absence d'un mot, gaussien pour des variables numériques continues.
Lissage : on ajoute un petit comptage à chaque mot pour qu'un mot absent d'une classe ne rende pas sa probabilité nulle. 1 par défaut, à tester entre 0,1 et 1.
Minuscules, ponctuation, fréquence minimale des mots : ces choix comptent plus que le modèle. Ils se règlent dans DocumentTermMatrix en R, dans CountVectorizer en Python.
# Tri des avis négatifs : Naive Bayes en R
library(tm)
library(naivebayes)
avis <- read.csv("avis_clients.csv", fileEncoding = "UTF-8")
y <- factor(ifelse(avis$sentiment == "negatif", "negatif", "autre"))
# Sac de mots : chaque avis devient un comptage de mots
corpus <- VCorpus(VectorSource(tolower(avis$texte)))
dtm <- DocumentTermMatrix(corpus, control = list(removePunctuation = TRUE))
X <- as.matrix(dtm)
set.seed(42)
idx <- sample(nrow(X), round(0.7 * nrow(X)))
# Naive Bayes multinomial, lissage de Laplace pour les mots jamais vus
modele <- multinomial_naive_bayes(x = X[idx, ], y = y[idx], laplace = 1)
pred <- predict(modele, newdata = X[-idx, ], type = "class")
print(table(prevu = pred, reel = y[-idx]))
cat("Rappel sur les négatifs :", round(mean(pred[y[-idx] == "negatif"] == "negatif"), 3), "\n")
cat("Précision sur les négatifs :", round(mean(y[-idx][pred == "negatif"] == "negatif"), 3), "\n")
# Tri des avis négatifs : Naive Bayes en Python
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
avis = pd.read_csv("avis_clients.csv")
y = (avis["sentiment"] == "negatif").astype(int) # 1 = avis à traiter
textes_train, textes_test, y_train, y_test = train_test_split(avis["texte"], y, test_size=0.3, random_state=42, stratify=y)
# Sac de mots : chaque avis devient un comptage de mots
vecto = CountVectorizer(min_df=2)
X_train = vecto.fit_transform(textes_train)
modele = MultinomialNB(alpha=1.0).fit(X_train, y_train)
pred = modele.predict(vecto.transform(textes_test))
print(classification_report(y_test, pred, target_names=["autre", "négatif"], digits=3))
# Les mots qui font le plus pencher vers « négatif »
ecart = modele.feature_log_prob_[1] - modele.feature_log_prob_[0]
print(pd.Series(ecart, index=vecto.get_feature_names_out()).sort_values().tail(8).round(2))
Parce qu'il suppose que les variables sont indépendantes les unes des autres une fois la classe connue. Sur du texte, c'est faux : « pas » et « reçu » vont souvent ensemble. Le classement final reste pourtant souvent bon, car on a seulement besoin que la bonne classe obtienne le score le plus élevé.
Naive Bayes s'entraîne plus vite et marche mieux avec très peu d'exemples. La régression logistique prend l'avantage quand les données sont plus nombreuses et donne des probabilités mieux calibrées. En pratique, on teste les deux.
C'est l'ajout d'un comptage fictif, souvent 1, à chaque mot et chaque classe. Sans lui, un mot jamais vu dans les avis négatifs donnerait une probabilité nulle et annulerait tout le produit, quel que soit le reste de l'avis.
Cherche la frontière à marge maximale entre les classes. Un peu plus lente, souvent meilleure avec beaucoup de données.
Voir la fiche → des probabilités fiablesPas d'hypothèse d'indépendance, probabilités mieux calibrées. Le choix quand le score sert à décider.
Voir la fiche → le principe de baseLa formule qui met à jour une probabilité à la lumière d'un indice. Naive Bayes l'applique mot par mot.
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