Skip to content

Latest commit

 

History

History
604 lines (384 loc) · 35 KB

rapport.md

File metadata and controls

604 lines (384 loc) · 35 KB

Projet Hate Speech

Introduction

Le projet se divise principalement en deux parties:

  1. Détection de discours toxiques ou non-toxiques
  2. Détoxification de texte haineux

Durant le projet, je me suis davantage concentré sur la première partie où j'ai essayé de mettre en place le plus de pratique possible, notamment avec la recherche d'hyperparamètres tandis que la deuxième partie, a été abordée de manière plus "théorique" en me concentrant davantage sur l'étude des solutions possibles, tout de même complété avec de la mise en pratique dans une plus faible mesure.

Pour finir, j'ai mis en place une application Streamlit permettant d'intéragir avec les modèles, elle n'est pas déployé mais elle peut être lancée localement, voir la partie Application Streamlit.

Avant toute chose, il est important de savoir ce qu'est un contenu toxique.

Ainsi il y a ici une "limite" purement subjective de ce qui est toxique ou non : deux personne pourraient ne pas être d'accord sur le fait qu'un texte soit toxique ou non. De plus on peut identifier plusieurs biais dans la classification de contenu toxique.

Dans notre cas, nous allons suivre l'annotation du dataset d'entrainement que nous allons utiliser; et nous allons ensuite tester ces cas spéciaux, ces limites et les potentiels biais dans la partie Test des edge cases.

Plan du rapport :

  1. Choix des Datasets
    1. Dataset d'entrainement classifier
    2. Dataset de test Multi-langues
    3. Dataset d'entrainement détoxification
  2. Prétraitement des données
    1. Dataset d'entrainement classifier
    2. Dataset de test Multi-langues
    3. Dataset d'entrainement détoxification
  3. Modèle de Classification
    1. Séléction du modèle
    2. Recherche des hyperparamètres (GridSearch)
    3. Entrainement du modèle et premiers résultats
    4. Evaluation sur d'autres langues
    5. Test des edge cases
      1. Limite de ce qui est une toxique
      2. Mots-clés toxiques / communautés
      3. Ponctuation
  4. Détoxification
    1. Méthode d'évaluation
    2. Reformulation sans entrainement
    3. Reformulation avec entrainement
  5. Application Streamlit
  6. Conclusion

1. Choix des Datasets

Pour réaliser ce projet, j'ai utilisé 3 datasets, disponible dans le dossier datasets :

  • dataset_v1.csv pour l'entrainement du classifier
  • cleaned_data_hatespeech.csv pour l'évaluation du modèle de classification sur d'autres langues
  • filtered.tsv pour l'entrainement du modèle de détoxification.

Voyons en détail ces 3 datasets.

1.1. Dataset d'entrainement classifier

Ce dataset contient environ 42.000 lignes pour de nombreuses colonnes, dont la plupart ne nous servirons pas pour ce projet. Les colonnes qui nous intéressent sont :

  • text : le texte
  • label : la classe du texte (toxique ou non-toxique)

Ce qui m'a fait choisir ce Dataset :

  • Plutôt bien fourni avec 42.000 lignes, ce qui est suffisant pour entrainer (et il n'est pas non plus trop chargé).
  • Une répartition initiale de presque 50/50 entre les classes toxiques et non-toxiques.
  • Les textes sont assez courts mais suffisamment longs pour être significatifs, de plus il n'y a que des mots correctement écrits, c'est à dire pas de langage SMS, d'abréviations ou de fautes d'orthographe.
  • Étant associé à une publication scientifique, c'est un garant de qualité (mais pas infaillible bien sûr).
  • Comme demandé, tout le texte est en Anglais.

Les inconvénients du dataset :

  • Il y a des colonnes inutiles
  • Les classes sont très peu déséquilibrées

Sources :

1.2. Dataset de test Multi-langues

Pour tester notre modèle de classification sur d'autres langues, j'ai sélectionné un dataset contenant des textes toxiques ou non-toxiques en plusieurs langues. Il y a environ 88.000 lignes pour 7 langues:

  • Anglais
  • Français
  • Italien
  • Turc
  • Espagnol
  • Russe
  • Portugais

Ce qui m'a fait choisir ce Dataset :

  • Il est très complet, avec 7 langues différentes, ce qui va nous permettre de faire des tests intéressants.
  • Venant de Kaggle, c'est en réalité un regroupement de plusieurs datasets qui sont tous sourcés.
  • Le dataset est déjà très propre avec seulement 3 colonnes : comment_text, toxic (0 ou 1) et lang, ce qui est parfait pour notre utilisation.

Les inconvenients du dataset :

  • Je n'ai pas fais spécifiquement attention à la répartition des classes toxiques et non-toxiques pour chaque langue.
  • La répartition des langues n'est pas équilibrée (là-dessus on va donc simplement créer des sous-dataset pour tester les langues sur un nombre fixe de lignes, ici ce sera sur 5000 lignes pour un test significatif mais pas trop conséquent en terme de temps de calcul).
  • Je n'ai pas regardé la qualité des textes des autres langues que l'Anglais et Français, ne parlant pas les autres langues.
  • Pour l'Anglais et Français, les textes sont légerement plus longs et familiers que ceux du dataset d'entrainement, mais ce n'est pas très significatif.

Sources :

1.3. Dataset d'entrainement détoxification

Pour finir, il faut un dataset pour entrainer notre modèle de détoxification. J'ai pris un très gros de dataset de 574.000 lignes de textes toxiques avec leurs versions détoxifiées.

Ce qui m'a fait choisir ce Dataset :

  • J'ai trouvé très peu de dataset avec des textes toxiques et leurs versions détoxifiées, c'est le seul qui semblait convenir.
  • Les textes sont, comme pour le dataset d'entrainement du modèle de classification, assez courts mais suffisamment longus pour être significatifs, de plus les textes sont correctement rédigés, c'est à dire pas de langage SMS, d'abréviations ou de fautes d'orthographe.

Les inconvénients du dataset :

  • Aucune source à part le fichier lui-même sur Kaggle
  • Il y a des colonnes inutiles
  • Le dataset est très volumineux, il faudra donc le réduire pour l'entrainement.
  • La version détoxifiée des textes est peut-être discutable, c'est davantage une reformulation plus correcte, en enlevant la plupart des insultes et mots haineux

Sur ce dernier point, je me suis rendu compte après coup que pour valider si le dataset était intéressant, j'aurai pu tester la qualité des détoxifications en classifiant les 2 textes censées être toxiques et non-toxiques. Ainsi j'aurai pu vérifier :

  • Que tous les textes toxiques étaient bien toxiques
  • Que toutes les versions détoxifiées des textes initialement toxiques sont bien non-toxiques
  • Plus globalement, la quantité de textes détoxifiés qui sont toujours toxiques

Sources :





Retourner au plan

2. Prétraitement des données

Je vais m'attarder principalement sur les pré-traitements du dataset d'entrainement du classifier

2.1. Dataset d'entrainement classifier

Il y a plusieurs étapes de prétraitement à réaliser sur ce dataset :

  • Suppression des colonnes inutiles
  • Ajustement des classes déséquilibrées
  • Répartition du dataset en train et test
  • Nettoyage du texte
  • Tokenization

Suppression des colonnes inutiles

Il y a plusieurs colonnes inutiles dans ce dataset, je vais donc les supprimer :

  • acl.id
  • X1
  • type
  • target
  • level
  • round.base
  • annotator
  • round
  • acl.id.matched

Ajustement des classes déséquilibrées

Par défaut, voici la répartition des classes :

Répartition des classes

La répartition étant presque à 50/50, je n'ai pas touché à la répartition des classes.

Répartition du dataset en train et test

Par défaut, voici la répartition du dataset selon la colonne split :

Répartition des classes

On observe qu'il y a 10% de lignes de dev ce qui n'est pas utile pour nous, on va donc simplement les convertir en test pour avoir 80% de lignes d'entrainement et 20% de lignes de test.

Prétraitement du texte

Pour prétraiter le texte, on va simplement :

  • Mettre le texte en minuscule
  • Lemmatiser le texte

Après coup, je me suis rendu compte que passer le texte en minuscule était potentiellement mauvais dans notre cas, car on peut simplement se dire qu'un texte en majuscule est plus probable d'être toxique qu'un texte en minuscule. De plus on verra que j'ai choisi un modèle qui prend en compte la casse, c'est donc une incohérence et erreur de ma part que j'aurais aimé corriger avec davantage de temps.

Tokenization

Pour tokeniser le texte, j'ai utilisé le tokenizer DistilBertTokenizer qui est associé au modèle que nous allons utiliser, plus d'info dans la partie Séléction du modèle.

2.2. Dataset de test Multi-langues

Pour ce dataset, étant donné qu'il va simplement servir à évaluer notre modèle de classification sur d'autres langues, je n'ai pas besoin de faire quoi que ce soit dessus, à part renommer les colonnes pour qu'elles correspondent à celles du dataset d'entrainement.

2.3. Dataset d'entrainement détoxification

Pour ce dataset, j'ai décidé de le laisser brut pour l'entrainement, les textes seront donc tels quels, sans prétraitement.

Je supprime simplement les colonnes inutiles.





Retourner au plan

3. Modèle de Classification

3.1. Sélection du modèle

Pour entrainer mon modèle de classification, j'ai décidé d'utilise un modèle de type DistilBert qui est une version plus légère de Bert.

De plus, j'ai utilisé la version SequenceClassification de DistilBert qui est un modèle pré-entrainé pour la classification de séquences, ce qui est parfait pour notre cas.

N'ayant pas toutes les connaissances pour comprendre tous les modèles de NLP et leurs fonctionnements, j'ai notamment choisi ce modèle car il me paraissait assez simple à manipuler, et offrait de bonnes performances sans être trop lourd.

Et étant donné que nous avions déjà vu rapidement Bert en cours, je me suis dit que c'était un choix cohérent.

3.2. Recherche des hyperparamètres (GridSearch)

Une partie importante du projet a été la recherche d'hyperparamètres, car ayant beaucoup aimé cette partie du cours, j'ai voulu y consacrer un certain temps.

J'ai alors séléctionné 3 hyperparamètres à tester avec différentes valeurs à tester :

  • learning_rate : 1e-5, 3e-5 et 5e-5
  • epochs : 1, 3 et 5
  • batch_size : 8 et 16

Étant malheureusement limité en temps et en ressource de calcul, je me suis limité à ces valeurs là, mais j'aurai aimé faire des tests plus conséquent, notamment sur les epochs en montant pourquoi pas jusqu'à 10, tout en passant par des valeurs intermédiaires comme 2. Et de même pour le batch_size en testant des valeurs plus grandes.

De plus j'ai lancé les tests sur un nombre de lignes d'entrainement correspondant à seulement 10% du dataset d'entrainement, ce qui est très peu. Cela m'a permis d'avoir tout de même une idée des performances, mais ici aussi j'aurais aimé pouvoir tester sur davantage de données

NB: D'expérience en entreprise, je sais que les grid search sont très couteux en temps de calcul, alors qu'ils n'offrent pas forcément de meilleurs résultats que d'autres techniques comme la recherche bayesienne qu'on a pu évoquer en cours. Seulement pour ce projet je souhaitais vraiment mettre en place techniquement cette grid search, me permettant en même temps d'apporter une meilleure compréhension des outils que j'utilise.

Concernant les métriques de performances, j'ai choisi d'utiliser la précision, le recall, le f1-score et le recall, qui sont des métriques classiques pour la classification.

Pour rappel, voici en quoi consiste chaque métrique :

  • Accuracy : métrique la plus "basique" qui détermine la part des estimations correctes du modèle sur l'ensemble des estimations. La métrique est plutôt utile avec des dataset qui ont des classes réparties de façon égale, ce qui est notre cas, mais cette métrique étant tout de même limitante pour diverses raisons, on ne peut pas se limiter à elle seule.
  • Precision : la précision mets l'accent sur les Faux Positifs : un modèle qui aura beaucoup de faux positif sera penalisé et inversement. C'est surtout utilisé lorsque le "coût" d'un faux positif dans un cas concret aurait un impact négatif, par exemple en contrôle de qualité si on flag un produit comme déféctueux alors qu'il fonctionne bien, cela constitue une perte de gains et une baisse de production.
  • Recall : même idée que pour la précision mais sur les Faux Négatifs. Le Recall peut-être important par exemple dans le milieu médical, où l'on veut absoulement pas prédire qu'un patient n'est pas malade alors qu'il l'est réellement.
  • F1-score : le F1 score va harmoniser la Précision et Recall, ce qui en fait une mesure particulièrement pratique. Elle est intéressante lorsqu'un cherche un équilibre entre Précision et Recall.

Dans notre cas, on pourrait imaginer que notre classifier pourrait être utilisé par un réseau social qui souhaite censurer du contenu toxique, alors la Précision serait une plutôt bonne métrique puisque l'on veut éviter de flag du contenu comme toxique alors qu'il ne l'est pas, car cela pourrait engendrer de l'insatisfaction de la part des utilisateurs. Dans ce cas le Recall pourrait aussi être intéressant puisqu'on ne veut pas laisser passer du contenu toxique.

Même si notre modèle n'a pas pour objectif d'être implémenté sur un cas concret, je vais partir ici du principe qu'on veut le modèle le plus fiable possible en dépit de circonstances, on va alors baser notre évaluation sur l'ensemble des métriques en ayant toujours en tête ce que chaque métrique représente.

Voici donc les résultats de la grid search :

Résultats de la grid search

Il y a 4 graphiques, un pour chaque métrique. Sur chaque graphique on observe un plan en 3D avec les 3 axes étant les 3 hyperparamètres. Ainsi sur chaque graphique on retrouve 3x3x2 = 18 points, qui correspondent aux 18 combinaisons d'hyperparamètres testées.

Plus le point est vert, plus la métrique est élevée, et inversement pour les points rouges.

Je ne vais pas prendre trop de temps à analyser le résultat du grid search, mais par simple observation graphique on constate une fréquence plus importante de résultats positifs sur certaines valeurs des hyperparamètres, c'est donc à partir de cette observation que j'ai décidé de partir sur un entrainement avec:

  • epoch = 1
  • learning rate = 3e-5
  • batch_size = 16

3.3. Entrainement du modèle et premiers résultats

J'ai donc entrainé mon modèle avec les paramètres déterminés grâce au Grid Search.

Voici les premiers résultats des métriques de performances sur le jeu de test :

  • loss : 0.519
  • accuracy : 0.734
  • f1 : 0.772
  • precision : 0.719
  • recall : 0.835

Avec ces résultats, on peut dire que le modèle est plutôt bon étant donné nos moyens : les métriques sont plutôt bonnes, seule le recall est bien au-dessus des autres métriques, cela veut donc dire que le modèle a tendance à prédire plus de faux négatifs que de faux positifs.

De plus, les autres métriques sont plutôt bonnes et équilibrées, ce qui montre que le modèle n'a pas de gros déséquilibre sur sa classification.

Bien sûr, avec davantage de préparation, plus de temps et de ressources, on aurait pu tenter d'obtenir de meilleurs résultats.

Mais pour un premier essai, je suis plutôt satisfait des résultats.

Regardons désormais la matrice de confusion :

Matrice de confusion

On observe que le modèle a tendance à prédire plus de faux négatifs que de faux positifs, ce qui est cohérent avec le recall élevé.

3.4. Evaluation sur d'autres langues

Nous pouvons désormais tester notre modèle sur d'autres langues, grâce à notre dataset de test multi-langues.

Après passage de notre modèle sur 5.000 ligne de chaque ligne, on obtient les résultats suivants :

Matrice de confusion

Nous pouvons en tirer plusieurs conclusions :

  • L'Anglais est au niveau de notre test, ce qui est cohérent
  • Le Turc étant de base une langue asiatique très différente des langues latines, il est normal que les résultats soient aussi mauvais.
  • De même pour le Russe, étant d'origine Slave.
  • Le Français est plutôt bon voire aussi bon que l'anglais, ce qui est cohérent avec le fait que le Français est une langue latine proche de l'Anglais.
  • Cette réfléxion marche aussi pour l'Italien, mais étonnament l'Espagnol et le Portugais qui sont aussi des langues latines sont moins bien classifiées.

On pourrait alors identifier 2 types de raisons potentielles à ces résultats concernant les langues latines :

  • Les raisons de type "technique" : notre dataset d'entrainement est peut-être mauvais, tout comme notre dataset de langue. Peut-être seulement les langues Espagnol et Portugaises ont des mauvaises données.
  • Les raison de type "linguistique" : malgré la proximité de ces langues ayant des origines latines, les cultures et langues ont peut-être beaucoup évolué, faisant que le contenu toxique en Français et en Italien sont davantage proches du contenu toxique Anglais, à l'instar du contenu toxique Espagnol et Portugais.

3.5. Test des edge cases

Comme nous l'avons vu dans l'introduction, il y a beaucoup de biais potentiels, en plus d'une limite subjective de ce qu'est la toxicité.

Pour explorer davantage cette partie, nous allons tester plusieurs cas spéciaux :

3.5.1. Limite de ce qui est une toxique

Pour tester la limite de ce qui est toxique ou non, on va tester des phrases selon 3 catégories :

  • Ethnie
  • Genre
  • Orientation sexuelle

Pour chacune de ces catégories, on va tester 3 phrases qui vont graduellement être plus toxiques, ainsi pour chaquez phrase on va regarder la probabilité du modèle de prédire la classe toxique.

Ethnie
  • Phrase 1 : "Some groups just don’t adapt well to new environments."
  • Phrase 2 : "We’d be better off without them entirely."
  • Phrase 3 : "The only solution is to exterminate them all, once and for all."
Genre
  • Phrase 1 : "Women can struggle in male-dominated fields."
  • Phrase 2 : "Women are ruining the workplace for everyone."
  • Phrase 3 : "Women who challenge men should be silenced permanently."
Orientation Sexuelle
  • Phrase 1 : "They’re forcing their way of life on everyone else."
  • Phrase 2 : "They don’t deserve the same rights as others."
  • Phrase 3 : "We should round them up and kill them all to fix society."

Voici les résultats :

Matrice de confusion

Au final, on distingue mal une tendance de toxicité croissante pour chaque catégorie, de plus on se rend compte qu'on détecte assez peu la toxicité dans ces cas là.

Néanmoins pour la catégorie du genre on observe un fort taux de toxicité pour toutes les phrases, cela est très probablement dû au simple fait que le mot "Women" soit présent dans toutes les phrases, et que le modèle a appris que ce mot est souvent associé à du contenu toxique. On détaille cette partie là juste après.

3.5.2. Mots-clés toxiques / communautés

Comme nous venons de le voir, le modèle a tendance à détecter de la toxicité à partir de la simple présence de certains mots-clés, explorons ces potentiels mots-clés.

On peut asser simplement lier ces mots clés aux communautés, on va alors tester les mots-clés suivants :

  • black
  • nigger
  • women
  • gays
  • jews

Faisons des tests avec tous ces mots-clés avec 3 phrases :

  • Mot-clé seul
  • Mot-clé au sein d'une phrase toxique
  • Mot-clé au sein d'une phrase non-toxique

Ici encore, on va tester selon quel pourcentage notre modèle prédit que la phrase est toxique.

Résultat de notre expérimentation :

Matrice de confusion

On peut observer plusieurs choses :

  • Il y a bien un biais sur la détection de toxicité à partir de certains mots-clés, car le mot-clé seul est toujours classifié comme étant très fortement toxique
  • Lorsque le mot-clé est dans un contexte d'une phrase toxique, le modèle continue à prédire que c'est une phrase fortement toxique mais légèrement moins que le mot-clé seul, c'est sans doute dû au fait qu'il y a plus de mots dans la phrase qui rentrent dans le calcul de la prédiction.
  • Enfin, lorsque le mot clé n'est pas dans une phrase toxique, le modèle baisse drastiquement la probabilité de toxicité, ce qui est bon signe car cela veut dire que les autres mots de la phrase sont pris en compte dans le contexte de la phrase, influençant donc la prédiction.

Sur ce dernier point je suis assez surpris et satisfait des résultats, je m'attendais plutôt à ce que le modèle prédise une toxicité élevée simplement à cause de la présence d'un mot-clé, même dans une phrase non toxique.

3.5.3. Ponctuation

Une dernière chose à tester est au niveau de la ponctuation, on va tester 3 phrases :

  • Phrase 1 : "Jews are bastard" --> 0.922
  • Phrase 2 : "Jews are bastard !" --> 0.879
  • Phrase 3 : "Jews are bastard !!!!!" --> 0.772

On observe que la ponctuation a un impact léger mais existant sur la prédiction de toxicité, notamment pour la première phrase où on pourrait expliquer la forte probabilité de toxicité par le fait que dans le jeu d'entrainement, les phrases sans ponctuation sont plus souvent toxiques car moins bien écrites.

De la même manière pour la phrase avec beaucoup de points d'exclamation, peut-être que dans le jeu d'entrainement les phrases avec beaucoup de points d'exclamation sont "rigolotes" et moins sérieuses (potentiellement un marqueur de second degré), ce qui pourrait expliquer que la prédiction est moins toxique.

Conclusion

Au final, on se rend assez facilement compte que notre modèle a des biais, notamment sur la détection de toxicité à partir de certains mots-clés, mais aussi sur la ponctuation, mais dans une certaine mesure il arrive malgré tout à bien détecter certaines nuances.

Étant donné la capacité d'entrainement et du modèle assez réduit, je suis plutôt satisfait du résultat de nos tests sur les edge cases. De plus, ces edge cases montrent bien les limites de notre modèle, et ils nous permettent ainsi de mieux comprendre son fonctionnement, et comment nous pourrions l'améliorer.





Retourner au plan

4. Détoxification

Pour la partie détoxification, j'ai d'abord envisagé plusieurs solutions possibles :

  • Détection et suppression / filtrage de mots-clés toxiques / insultants au sein d'un texte.
  • Reformulation du texte pour avoir la même signification mais sans la toxicité
  • Reformulation du texte pour avoir la signification inverse de la toxicité

Après plusieurs recherches, j'ai eu du mal à trouver une solution technique assez viable et restant simple pour la détection et suppression de mots-clés toxiques, je me suis donc concentré sur la reformulation des phrase pour garder la même signification mais sans la toxicité.

J'ai également écarté la solution de la reformulation pour avoir la signification inverse de la toxicité, car j'ai remis en cause l'utilité de cette méthode.

Ainsi, pour la reformulation des textes, j'ai utilisé un modèle de type T5 (en taille small) qui est un modèle de type "Text-to-Text" qui permet de faire de la traduction, du résumé, de la génération de texte, etc.

J'ai séparé cette partie en deux sous-parties :

  • Utilisation du modèle sans entrainement
  • Utilisation du modèle avec entrainement sur le dataset de détoxification

Pour tester nos différentes solutions, j'ai décidé de reprendre notre dataset d'entrainement du classifier, et de garder uniquement les lignes toxiques pour les tester.

4.1. Méthode d'évaluation

Avant toute chose, il va falloir évaluer la qualité de nos reformulations; nous pourrions alors simplement prendre notre modèle de classification, mais nous avons bien vu que ce modèle comporte des biais, et qu'il n'est pas forcément adapté afin d'évaluer la qualité de nos reformulations.

J'ai donc choisi de prendre un package existant sur Python permettant de calculer la toxicité d'un texte, avec des résultats bien plus satisfaisants que notre modèle de classification.

Ce package à fait ses preuves en participant a plusieurs challenges, affichant de très bon résultats. De plus il a été publié par une chercheuse affiliée dans une entreprise d'IA, qui a été cité à ce jour 239 fois

Sources :

Dans les faits, le modèle va prédire plusieurs niveaux de toxicité selon plusieurs catégories (toxicity, severe_toxicity, obscene, threat, insult, identity_attack, sexual_explicit); dans notre cas cas nous allons uniquement regarder la métrique toxic.

Avec ce package, on détecte un niveau de toxicité moyen de 0.54 sur toutes les lignes toxiques de notre dataset.

Cela peut paraitre faible mais ce n'est pas plus mal, car au final cela veut dire que l'ensemble de nos textes toxiques sont équilibrés en terme de toxicité : il y a des textes très toxiques et d'autres beaucoup moins.

4.2. Reformulation sans entrainement

Sans entrainement, j'ai simplement utilisé le modèle T5 avec comme instruction paraphrase: pour génerer un nouveau texte pour chaque ligne du dataset.

Avec ce traitement j'ai obtenu un nouveau score toxique moyen de 0.34, ce qui peut paraitre excellent à première vue, mais regardons de plus près l'avant / après de notre texte, sur un échantillon de 5 textes :

Texte initial Texte reformulé
Being so butch must be hard, especially as you are a women. I cant imagine many men would want to have a go on you, most of them must just be scared. Maybe you shuold try looking a bit more feminine? : Being so butch must be hard, especially as you are a women.
women are emotionally feeble Paraphrase
If he was black he would probably end up in jail or more likely shot dead as a pig. Paraphrase: If he was black he would probably end up in jail or shot dead as a pig.
I was walking down to town and these Niggers had the audacity to come to me. Paraphrase: I was walking down to town and these Niggers had the audacity to come to me.
Muslims' lives will never matter to us Paraphrase: Muslims' lives will never matter to us to us.

On voit au final que notre paraphraser ne marche vraiment pas bien : dans plusieurs cas il reprend exactement la même phrase simplement en ajoutant l'instruction "paraphrase: " au début, et parfois il donne un résultat totalement incohérent.

La seule vraie reformulation est la première, où il résume simplement le contenu toxique, mais la toxicité est toujours présente.

Au final, on voit bien que les meilleurs résultats qu'on obtenait n'était pas réellement une amélioration, bien au contraire. On peut alors expliquer l'amélioration du score simplement si on prend en compte toutes les erreurs du parahraser qui produit des textes sans aucun sens mais qui sont donc non-toxiques.

4.3. Reformulation avec entrainement

Pour l'entrainement, j'ai donc pris le dataset d'entrainement pour la détoxification.

J'ai ainsi entrainé le modèle sur environ 5700 lignes, avec des hyperparamètres déterminés de manière arbitraire (une recherche d'hyperparamètre aurait ici aussi été pertinent mais je n'ai pas eu le temps ni les ressources permettant de la mattre en oeuvre), c'est à dire un learning_rate de 3e-5, un batch_size de 8 et 1 seule epoch.

Après entraînement du modèle, on génère à nouveau des textes cette fois-ci avec notre modèle T5 entrainé, et obtient cette fois-ci une toxicité moyenne de 0.46, soit une baisse légère, mais regardons surtout l'avant / après sur un échantillon de 5 phrases :

Texte initial Texte reformulé
i believe that fucking kid is an inbreed. That's so typical of african people I believe the kid is an inbreed, that's so typical of african people.
Of course I would skip trans movies. I'm not phobic but watching them makes me physically sick and I blame them that I now have to double check every girl I meet in a pub after a few drinks....so get that filth of the tv and stop pretending its normal!! I'm not phobic, but watching them makes me physically sick, and I blame them for the fact that I have to double check every girl I meet in a pub after a couple of drinks, so get the tv and stop pretending it's normal!
Our city is getting run over with curry munchers our city is fucked up with shit.
i wish there were less dark skinner people in the world I wish there were less dark skinners in the world.
Immigrants vandalise a church in West Croydon, in London! Enough is enough immigrants vandalise a church in West Croydon, London!

Premièrement on constate que le modèle génère beaucoup moins d'erreurs que le modèle non-entrainé, ce qui est un point positifit.

Néanmoins sur la plupart des phrases il reformule très simplement en changeant uniquement quelque formulations, ou en supprimant une partie de la phrase comme au début de la phrase 2 ou à la fin de la phrase 5.

On remarque tout de même qu'il y a une certaine "censure" de quelques mots-clés, comme avec la première phrase pour le mot-clé fucking ou a la troisième phrase avec curry munchers.

Au final, notre modèle fonctionne globalement mieux que sans entrainement, mais il n'est clairement pas efficace pour réellement détoxifier un texte.





Retourner au plan

5. Application Streamlit

Pour intéragir avec les modèles, j'ai construit une application Streamlit mais qui n'est pas déployé, il faut donc la lancer localement.

Pour lancer l'application localement, il suffit d'être dans le dossier /streamlit_app et de lancer la commande suivante : streamlit run main.py.

Bien entendu il faut avoir téléchargé la librairie Streamlit et autres librairies nécessaires pour lancer l'application, pour cela il y a un fichier requirements.txt dans le dossier qui liste toutes les librairies nécessaires, et vous pouvez ainsi les installer avec la commande pip install -r requirements.txt.

Matrice de confusion




Retourner au plan

6. Conclusion

Pour finir, j'aimerais conclure d'un point de vue plus personnel sur ce projet.

J'ai beaucoup aimé travailler sur ce projet, car il m'a permis de mettre en pratique beaucoup de choses vues en cours. J'ai aussi beaucoup aimé toute la liberté que nous avons eu, en terme d'expérimentations et de recherche tout au long du projet, que ce soit sur le choix des datasets, des modèles, l'analyse des résultats, etc.

Néanmoins, je me suis senti limité par les ressources et temps de calcul. J'aurai aimé pouvoir tester davantage de paramètres, notamment sur la recherche d'hyperparamètres, mais aussi sur la recherche de solutions de détoxification. Mais au final c'est aussi une partie intéressante car dans le monde du travail nous sommes aussi également limité en temps voire en ressources, aussi il est intéressant de voir comment on peut s'adapter à ces contraintes, en priorisant les tâches, en optimisant les ressources, etc. C'est un autre aspect de la data science.

Enfin, voici l'ensemble des élements que j'aimerai travailler si j'approfondissais ce projet :

  • Mieux explorer et préparer les jeux de données
  • Tester d'autres modèles de classification
  • Tester et expérimenter d'autres méthodes de détoxification
  • Approfondir la partie de Recherche d'Hyperparamètres
  • Approfondir la partie de Test des Edge Cases
  • Revoir la partie du prétraitement du texte
  • Mettre en place différente techniques durant l'entrainement comme l'option auto_batch_size ou le learning rate decay
  • Explorer davantage les résultats et l'analyse des performances, j'ai notamment pensé à mettre un place un Cross Validation




Retourner au plan