CamemBERT — détection de discours haineux en français

Classifieur binaire (non haineux / haineux) obtenu par fine-tuning de camembert-base sur FrenchHateSpeechSuperset.

Démo : Ezeck01/detecteur-discours-haineux

Résultats (jeu de test, 1 125 messages jamais vus)

Seuil de décision 0,23 (choisi sur la validation, voir plus bas).

Classe Précision Rappel F1
non haineux 0,870 0,774 0,819
haineux 0,791 0,881 0,834
macro 0,831 0,827 0,826

PR-AUC 0,901 · ROC-AUC 0,912. Matrice de confusion : 441 VN, 129 FP, 66 FN, 489 VP.

Données : un audit avant l'entraînement

Le jeu contient 42 660 lignes, mais seulement 7 499 textes distincts : plus de 80 % des lignes sont des doublons. Sans déduplication, les mêmes phrases se retrouvent à la fois en entraînement et en test, et les scores sont artificiellement gonflés. Après déduplication, les classes sont quasi équilibrées (50,7 % / 49,3 %).

Découpage stratifié : 5 249 entraînement / 1 125 validation / 1 125 test. Le test n'est utilisé qu'une fois, pour les chiffres ci-dessus.

Entraînement

  • camembert-base, 3 époques, lr 2e-5, batch 32, longueur max. 128, fp16 (GPU T4, ≈ 2 min)
  • Perte d'entropie croisée pondérée par l'inverse de la fréquence des classes
  • Meilleur checkpoint choisi sur le F1 de la classe « haineux » en validation
  • Seuil ajusté sur la validation : 0,23 maximise le F1 « haineux » (0,842 contre 0,818 au seuil implicite de 0,5). En modération, rater un message haineux coûte plus cher qu'une fausse alerte : un seuil bas privilégie le rappel.

Le seuil est stocké dans config.json (seuil_decision).

Utilisation

import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

repo = "Ezeck01/camembert-hate-speech-fr"
tok = AutoTokenizer.from_pretrained(repo)
model = AutoModelForSequenceClassification.from_pretrained(repo).eval()
seuil = model.config.seuil_decision  # 0.23

texte = "Tu es vraiment nul et tu ne vaux rien"
with torch.no_grad():
    p = torch.softmax(model(**tok(texte, return_tensors="pt")).logits, dim=1)[0, 1].item()
print("haineux" if p >= seuil else "non haineux", round(p, 2))

Limites

  • Menaces implicites : « Je vais te retrouver et tu vas le regretter » est classé non haineux (p = 0,07). Le modèle s'appuie surtout sur le vocabulaire explicite.
  • Étiquettes bruitées : le jeu mêle plusieurs sources et contient des annotations discutables (ex. « c'est dégeulasse » étiqueté haineux).
  • Corpus modeste après déduplication (7 499 textes) ; français uniquement, registre surtout informel en ligne.
  • À utiliser comme aide à la modération, avec relecture humaine, jamais comme décision automatique.

Auteur

Ezéchiel Sawadogo — M2 Langue & Informatique, Sorbonne Université · site · GitHub

Downloads last month
2
Safetensors
Model size
0.1B params
Tensor type
F32
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for Ezeck01/camembert-hate-speech-fr

Finetuned
(179)
this model

Dataset used to train Ezeck01/camembert-hate-speech-fr

Space using Ezeck01/camembert-hate-speech-fr 1

Evaluation results

  • F1 (classe haineux) on FrenchHateSpeechSuperset (dédupliqué)
    self-reported
    0.834
  • Précision (classe haineux) on FrenchHateSpeechSuperset (dédupliqué)
    self-reported
    0.791
  • Rappel (classe haineux) on FrenchHateSpeechSuperset (dédupliqué)
    self-reported
    0.881
  • F1 macro on FrenchHateSpeechSuperset (dédupliqué)
    self-reported
    0.826