top of page

Projet 7 OpenClassrooms

Classification de tweet

La Mission

Le client veut un prototype d’un produit IA permettant de prédire le sentiment associé à un tweet. Comme il n'a pas encore de données clients, nous allons travailler sur des données Open Source.​

Ces données contiennent non seulement le tweet, mais aussi l'identifiant de l'utilisateur, le moment du post, et une étiquette binaire (sentiment négatif vs. sentiment positif).

Il a va me falloir préparer un prototype fonctionnel du modèle. Le modèle est exposé via une API déployée sur le Cloud, appelée par une interface locale qui envoie un tweet à l’API et récupère la prédiction de sentiment.

Je vais en profiter pour explorer plusieurs approches :

  • approche “Modèle sur mesure simple”, pour développer rapidement un modèle classique (ex : régression logistique) permettant de prédire le sentiment associé à un tweet.

  • approche “Modèle sur mesure avancé” pour développer un modèle basé sur des réseaux de neurones profonds pour prédire le sentiment associé à un tweet. (C’est ce modèle que je devrai déployer et montrer au client). J'essayerai avec deux word embeddings différents, et même avec un modèle de la famille des modèles BERT.


On me demande aussi, pour une présentation en interne, de mettre en oeuvre un bon exemple de démarche orientée MLOps.

Les données

Disponibles en téléchargement ici, elles représentent 1600000 tweets en anglais, avec le score du sentiment - 0 étant négatif, 2 neutre et 4 positif - un identifiant, la date, un flag et le nom de l'utilisateur :

head_dataframe.png

Las, les données ne sont jamais aussi parfaites qu'on le voudrait, et il y a toujours quelques embûches avant leur traitement - et donc fatalement des décisions à prendre. Dans notre cas particulier, on voit par exemple que "seuls" 1581466 textes de tweets sont différents :

describe_dataframe.png

Et alors ? Et bien la méfiance est de mise ! Est-ce que par exemple des textes identiques seront classés pareillement ?

La réponse est non, voici quelques graphiques :

Cela nous permet aussi de distinguer qu'il n'y a peut-être que deux scores, le 0 et le 4. Ce sera en effet bien le cas. Au final, pour les textes en doublon on ne gardera que la note majoritaire (qui au vu des exemples affichés ci-dessus semble être la note correcte), et on convertira pour avoir 0 pour "négatif" et 1 pour "positif". On s'aperçoit que nos tweets restent parfaitement distribués entre les deux catégories de sentiment :

distribpost.png

Enfin, nous ne garderons que les textes et les notes, le reste des données ne nous intéressera pas pour notre tâche.

Modélisations

Principes

Lorsqu’on entraîne un modèle d’intelligence artificielle, il existe des paramètres appelés hyperparamètres.


Ce sont des réglages “externes” au modèle : par exemple, la taille du lot d’entraînement (batch size), le taux d’apprentissage (learning rate), le nombre d’epochs, etc.


Ces hyperparamètres ne sont pas appris par le modèle : ce sont des choix que l’on doit faire AVANT l’entraînement, et leur valeur peut avoir un grand impact sur la performance finale.

La grid search (ou recherche sur grille) est une méthode systématique pour trouver les meilleurs hyperparamètres.


On définit à l’avance plusieurs valeurs possibles pour chaque hyperparamètre, puis le modèle est entraîné et évalué avec toutes les combinaisons possibles de ces valeurs.


Cela permet d’identifier la configuration qui donne les meilleurs résultats sur nos données.

Dans notre cas, le jeu de données est parfaitement équilibré : il y a autant d’exemples de chaque classe.
Dans cette situation, l’accuracy (le pourcentage de bonnes réponses) est une métrique fiable pour comparer les performances des différents modèles.


Elle va donc nous servir pour évaluer la performance des hyperparamètres lors de notre recherche sur grille. Mais nous allons utiliser plus d'une métrique, notamment pour comparer toutes les différentes architectures de modélisation que nous allons mettre en place.

Métriques

  • Pourcentage de bonnes réponses sur l’ensemble des prédictions.

    Dangereuse sur les données déséquilibrées, cette métrique est ici adéquate, justement parce que nos données sont parfaitement équilibrées.

  • Moyenne harmonique entre la précision (précision = proportion de vrais positifs parmi les positifs prédits) et le rappel (rappel = proportion de vrais positifs parmi les vrais positifs attendus).


    Si le modèle a une précision parfaite (ne se trompe jamais quand il dit “positif”), mais ne trouve que 1 tweet positif sur 100, le F1-score sera faible.
    Le F1-score n’est élevé que si les deux (précision ET rappel) sont bons.

    Cette métrique équilibre la capacité à trouver tous les cas positifs et à ne pas faire de fausses alertes

  • Probabilité que le modèle classe un exemple positif avec une probabilité plus haute qu’un exemple négatif sur tous les seuils possibles. Généralement le modèle décide qu'un tweet va être positif s'il y a plus de 50% de chances, selon lui, qu'il soit positif. Le seuil est donc de 50%. Cette métrique va plus loin que la détermination de ce simple seuil de 50%.


    Si le modèle attribue systématiquement un score plus élevé aux vrais positifs qu’aux non positifs, le ROC AUC sera de 1.0 (parfait).
    S’il se trompe au hasard, le ROC AUC sera de 0.5 (aussi mauvais qu’un pile ou face).

    Métrique très robuste, surtout quand il faut comparer des modèles ou choisir le meilleur seuil de détection.

  • Temps nécessaire pour qu’un modèle donne une prédiction à partir d’une nouvelle donnée, une fois qu’il a été entraîné.

    C'est un bon indicateur de la complexité et du poids d'un modèle.

MLFlow

Dans ce projet, nous utilisons MLflow via la plateforme DagsHub pour gérer et suivre nos expériences de machine learning de façon professionnelle et collaborative.

Qu’est-ce que MLflow ?

MLflow est un outil open source qui permet de :

  • Suivre et enregistrer toutes les expériences d’entraînement (modèles, hyperparamètres, métriques, etc.)

  • Comparer facilement les performances de différents modèles et essais

  • Centraliser les résultats pour les rendre accessibles à toute l’équipe

  • Enregistrer et versionner les modèles pour une réutilisation ou un déploiement futur

Avec MLflow, chaque fois que l’on lance un entraînement, tout est automatiquement archivé : les réglages du modèle, les scores obtenus, les fichiers du modèle, etc.


On peut ainsi revenir en arrière, rejouer un essai, ou partager précisément ce qui a permis d’obtenir tel ou tel résultat.

DagsHub : la plateforme collaborative

DagsHub est une plateforme en ligne qui offre une interface pratique pour visualiser et organiser tous les résultats suivis par MLflow, avec des fonctions collaboratives (commentaires, versioning, intégration Git…).

Grâce à DagsHub, toutes les expériences MLflow sont visibles depuis un tableau de bord centralisé.


On peut :

  • Voir et comparer toutes les métriques des modèles testés

  • Télécharger ou partager les modèles

  • Assurer une traçabilité et une transparence totale du travail scientifique

Dans un projet réel, on fait des dizaines, voire des centaines d’essais, avec différents réglages et différentes données.
Sans suivi, il est impossible de retrouver comment on a obtenu le “meilleur” modèle, ou de collaborer efficacement avec d’autres.

Avec MLflow et DagsHub :

  • Tout est archivé, documenté et comparable

  • On peut reproduire n’importe quel résultat à tout moment

  • On évite les pertes de temps et les erreurs liées à l’oubli ou à la mauvaise organisation des expériences

C’est un outil indispensable pour tout projet de data science en équipe, et il permet d’amener rigueur et professionnalisme dans la gestion du machine learning.

Modèle «classique»

Nous utiliserons une approche classique et efficace de l’apprentissage automatique appliqué au texte :
le pipeline TF-IDF + régression logistique.

  • TF-IDF (Term Frequency-Inverse Document Frequency)
    C’est une méthode de transformation des textes en valeurs numériques :
    elle calcule l’importance de chaque mot dans un texte, en tenant compte de sa fréquence dans l’ensemble du corpus.
    Cela permet de convertir les textes en matrices de nombres, exploitables par les modèles de machine learning.

  • Régression logistique
    C’est un modèle de classification supervisée qui prédit la probabilité d’appartenir à une classe (par exemple : positif / négatif).
    Il est très utilisé pour les tâches de classification binaire sur des données textuelles vectorisées.
    Pour le dire simplement, il s'agit de calculer l'équation d'une droite qui découperait nos données en deux zones distinctes.

Ici la recherche sur grille va porter sur les hyperparamètres suivants :

  • Minimum Document Frequency


    C’est le seuil minimal (en proportion ou entier) d’apparition d’un mot pour qu’il soit conservé dans le vocabulaire du TF-IDF.

    Si un mot apparaît dans moins que cette fraction de documents (ex : 2%), il est jugé trop rare, et donc ignoré.

    Il s'agit d'éviter d’inclure des mots ultra-rares, souvent du bruit ou des fautes de frappe.

  • Maximum Document Frequency
    C’est le seuil maximal (en proportion) d’apparition d’un mot pour qu’il soit conservé.

    Si un mot apparaît dans plus que cette fraction de documents (ex : 80%), il est jugé trop fréquent, et donc ignoré.

    Il s'agit d'éliminer les mots trop courants (souvent des stopwords non gérés par défaut : “the”, “and”, etc.), qui n’apportent pas d’information discriminante.

  • La taille des n-grammes utilisés.

    (1,1) = unigrams : chaque mot séparé

    (1,2) = unigrams + bigrams : chaque mot ET toutes les paires de mots consécutifs

     

    Il s'agit ici de prendre en compte ou non des contextes, des expressions, des relations entre mots proches.

  • Paramètre de régularisation de la régression logistique (C = 1/λ).

    Plus C est petit, plus la régularisation est forte (le modèle est contraint, évite le sur-apprentissage, mais peut “sous-apprendre”).

    Plus C est grand, moins il y a de régularisation (le modèle peut s’adapter aux particularités du dataset, mais risque le sur-apprentissage).

    Il s'agit ici de trouver le bon équilibre entre biais et variance.

Réseau Neuronal Convolutif

Nous utiliserons une architecture très simple de Réseau Neuronal Convolutif. Le principe sous-jacent est simple:

Le texte entre, il est transformé en vecteurs, passé à travers des filtres qui détectent des expressions importantes, ces informations sont résumées, puis le modèle prend une décision finale : “Oui ou non ?”

De manière plus précise, l'architecture sera de ce type : 

1. Entrée
Le modèle commence par recevoir une séquence de mots (par exemple, une phrase ou un document). Chaque mot est représenté par un entier (un indice dans un vocabulaire).


2. Couche d’Embedding
Cette couche transforme chaque indice de mot en un vecteur de nombres. C’est comme traduire chaque mot dans un espace où les ressemblances entre mots sont capturées numériquement.


3. Dropout
Consiste à “oublier” aléatoirement certains éléments pendant l’apprentissage, pour que le modèle soit plus robuste et évite de sur-apprendre le jeu de données d’entraînement.

4. Deux couches Convolutionnelles (Conv1D)
Ces couches agissent comme des détecteurs de motifs sur le texte (par exemple, elles peuvent reconnaître des expressions comme “pas mal du tout” ou “très mauvais”), en appliquant plusieurs “filtres” qui explorent les sous-parties de la phrase pour identifier des séquences de mots caractéristiques.

5. Global Max Pooling
Cette étape résume l’information extraite par les filtres : pour chaque filtre, on ne retient que la valeur maximale sur toute la séquence. C’est comme demander à chaque détecteur : “as-tu vu ce motif, oui ou non ?” On obtient alors un résumé compact et robuste de tous les motifs importants détectés.


6. Couche Dense
On utilise une couche entièrement connectée qui combine toutes ces informations résumées pour apprendre des interactions plus complexes.


7. Dropout
Encore un peu de régularisation pour stabiliser le modèle.


8. Couche de sortie
Enfin, une dernière couche réduit le tout à une seule valeur comprise entre 0 et 1, qui représente la probabilité d’appartenir à la classe cible (par exemple, “positif” ou “négatif”)

Ici la recherche sur grille va porter sur les hyperparamètres suivants :

  • La taille des vecteurs de représentation dense des mots.

    Plus grand = chaque mot porte plus d’info, peut mieux capturer des subtilités sémantiques, mais risque d’overfit ou de ralentir l’apprentissage.

    Plus petit = modèle plus léger, mais parfois moins expressif.

  • Le nombre de filtres dans la couche convolutionnelle (Conv1D).

     

    Plus de filtres = modèle peut apprendre plus de motifs différents dans les séquences de texte.

     

    Trop de filtres = modèle lourd, plus lent, risque d’overfit.

  • La taille des fenêtres utilisées par la convolution (combien de mots à la fois).

     

    Petit kernel = détecte de petits motifs (ex : 2-3 mots ensemble)

     

    Grand kernel = détecte de plus longues séquences/motifs (ex : 5-7 mots)

  • La proportion de neurones “désactivés” à chaque passe (pour éviter l’overfit).

     

    Dropout haut = bon pour régulariser sur de petits datasets.

     

    Dropout bas = meilleur pour gros datasets, moins de risque d’underfit.

  • Le nombre d’échantillons traités en même temps lors d’une passe d’entraînement.

     

    Petit batch = bruit, convergence plus “fine”, mais lent.

     

    Grand batch = rapide, mieux pour grandes bases de données, mais parfois généralise moins bien.

  • Le pas de mise à jour des poids du modèle à chaque itération de l’optimiseur. C’est l’un des hyperparamètres les plus importants pour l’apprentissage profond.

    Avec un learning rate trop élevé : le modèle avance trop vite, peut “sauter” les minimums de la fonction de coût, et ne jamais converger.

    Un learning rate trop faible : le modèle apprend très lentement, peut stagner longtemps ou rester bloqué dans un minimum local.​

Pré-traitements

On peut travailler avec les données brutes, mais on peut aussi choisir de procéder à des traitements avant l'entraînement des modèles.

Le nettoyage : nous avons utilisé un script de nettoyage pour supprimer tout ce qui peut polluer l’analyse : mentions (@utilisateur), hashtags, URLs, caractères spéciaux, etc.

On a fait tourner un entraînement avec ce seul traitement, mais on l'a aussi cumulé avec un autre, la lemmatization et la tokenization avancée (avec spaCy) pour un troisième modèle entraîné.

Détermination de la taille du vocabulaire

Avant de choisir la taille du vocabulaire à utiliser pour le modèle, il est essentiel de comprendre combien de mots “couvrent” l’essentiel du corpus, pour ne pas surcharger inutilement notre modèle et ne prendre que les mots les plus significatifs. Nous avons utilisé le tokenizer pour compter tous les mots uniques présents dans les textes, et déterminer combien de fois chacun apparaît. On a classé les mots par fréquence, puis calculé, de manière cumulative, la proportion totale des occurrences représentée par les mots les plus fréquents (par exemple, le mot le plus courant peut représenter 5% du corpus, les deux plus courants 8%, etc.) On trace la courbe “nombre de mots vs % de couverture”, qui montre combien de mots il faut inclure pour couvrir une grande partie du corpus.

En général, une toute petite partie du vocabulaire couvre l’immense majorité des occurrences (loi de Zipf).

Ici, on cherche à déterminer combien de mots sont nécessaires pour atteindre 95% ou 90% de la couverture (c’est-à-dire pour que 95% ou 90% des mots du corpus soient reconnus par le modèle). Cela nous permettra d'établir de manière raisonnée le paramètre num_words. Un exemple. Avant prétraitement, le corpus contient 690487 mots différents.

RNBrut95cover.png
RNBrut90cover.png

Mais une infime partie, 8147, c'est-à-dire à peine plus d'1%, permet de couvrir 90% du corpus. (J'ai donc choisi pour ce cas de figure un num_words de 10000).

Avec un embedding pré-entraîné

Avec mon embedding entraîné au sein de mon modèle, les vecteurs sont optimisés spécifiquement pour notre tâche et nos données. Mais le risque encouru est d'avoir une représentation du langage assez idiosyncratique. Or, des embeddings pré-entraînés existent déjà. Les mots y sont représentés par des vecteurs déjà optimisés sur des corpus massifs (Wikipedia, Common Crawl…).

Le modèle bénéficie alors de la sémantique générale du langage : “roi” et “reine” seront proches, “chat” et “chien” aussi, etc.

On peut remplacer notre couche d'embedding par un de ces embeddings pré-entraînés et demander à ce que les vecteurs ne soient pas modifiés par l'apprentissage, comme c'est le cas dans nos premières moutures de réseaux.

Les deux embeddings que j'ai testés sont : 
 
Embedding GloVe.twitter.27B.200d
Embedding pré-entraîné de la famille GloVe (Global Vectors), construit spécifiquement sur un corpus de plusieurs milliards de tweets (27 milliards de tokens). Chaque mot est représenté par un vecteur de 200 nombres.

  • Adapté au langage Twitter : il comprend mieux les hashtags, abréviations, emojis, expressions courantes sur Twitter.

  • Bon pour l’analyse de sentiments, le NLP “social media” ou les tâches où le style d’écriture est informel.

  • Excellent pour traiter des textes courts, familiers, ou du contenu issu des réseaux sociaux.
     

Embedding GoogleNews-vectors-negative300
Embedding Word2Vec pré-entraîné sur un corpus massif d’actualités Google News (100 milliards de mots). Chaque mot est représenté par un vecteur de 300 nombres.

  • Apte à capturer la sémantique générale de l’anglais écrit (articles de presse, documents formels).

  • ​Moins adapté au langage “parlé” ou aux abréviations, mais très performant sur un vocabulaire large et varié.

  • Très utilisé pour toutes sortes d’applications NLP, offre de très bonnes analogies (“king” – “man” + “woman” ≈ “queen”, etc.)

Réseau Neuronal Récurrent

Les réseaux convolutifs sont dédiés à la détection de motifs. Mais ces motifs sont décontextualisés. Les réseaux neuronaux récurrents, eux, permettent de travailler sur de plus longues chaînes grâce à une sorte de mémoire. Voici l'architecture de celui que nous avons mis en place :

1. Entrée

2. Embedding

3. Deux couches Bidirectional LSTM
LSTM (Long Short-Term Memory) :
C’est une couche de réseau de neurones récurrent qui est spécialiste de la mémoire des séquences. Elle est capable de garder en mémoire le contexte d’une phrase, même sur des textes assez longs, et d’oublier les informations moins importantes.

Bidirectional (bidirectionnel) :
Chaque LSTM lit la séquence dans les deux sens. Le bidirectionnel permet au modèle de tenir compte du contexte avant ET après chaque mot.(Par exemple, pour le mot “banc”, le modèle saura si on parle de poissons ou d’un banc dans un parc, selon ce qui vient après.)

La première couche LSTM bidirectionnelle traite la séquence entière et retourne pour chaque mot une information enrichie.
La seconde couche LSTM bidirectionnelle résume toute la séquence en un seul vecteur global (en prenant en compte les deux directions).

4. Couche de sortie

Ici ma grille de recherche d'hyperparamètres ne couvrira que le batch_size, le learning_rate et le nombre d'unités LSTM, c'est-à-dire la taille de la mémoire mise en jeu par nos couches LSTM : pas assez d'unités, et le modèle ne réussira pas à représenter des informations à la hauteur de la complexité du texte. Trop d'unités, et comme d'habitude plus de calculs lourds, et plus de risques de sur-apprentissage.

Modèle Transformer

Les transformers sont une famille de modèles de deep learning, apparus en 2017, qui ont révolutionné le traitement du langage naturel (NLP). Leur innovation principale : ils utilisent le mécanisme d’attention pour comprendre le contexte de chaque mot dans une phrase, peu importe sa position. Ce mécanisme permet de capturer facilement des dépendances longues, des relations complexes, et le vrai sens des phrases.

Ici nous avons utilisé DistilBERT qui est une version compacte et optimisée de BERT, un des modèles les plus célèbres, développé par Google. 

On va ici le "fine-tune" sur notre propre jeu de données, c'est-à-dire qu'on va :

 

1. Tokenizer à base de sous-mots

On utilise le tokenizer DistilBERT, qui segmente chaque texte en “sous-mots” (subwords) pour mieux gérer les mots rares ou inconnus. Cela permet de traiter efficacement les variations, fautes de frappe et néologismes, très fréquents sur les réseaux sociaux.

2. Utiliser l'embedding contextuel

Chaque séquence de texte est encodée en vecteurs grâce au modèle pré-entraîné, capable de comprendre le contexte de chaque mot dans la phrase. Contrairement à un simple embedding fixe, chaque représentation dépend des mots voisins, ce qui permet de saisir le sens subtil des phrases.

3. Fine-tuner pour la classification

Le modèle DistilBERT est ensuite “affiné” (fine-tuned) sur notre jeu de données, c’est-à-dire que ses poids sont légèrement adaptés pour la tâche de classification binaire sur nos tweets. La sortie finale est encore une fois la probabilité d’appartenir à la classe cible.

Encore une fois on met en place une grille de recherche, sur le batch_size et le learning_rate.

Performances et choix du modèle

Vient l'heure de faire un choix entre tous ces modèles, et ce choix va se baser à la fois sur la performance et le poids du modèle à instancier.

On pourra ici avoir une idée du poids du modèle grâce au temps d'inférence, mais in fine on ira vérifier la taille du fichier (que MLFlow nous permet justement de sauvegarder).

Et en parlant de MLFlow, c'est justement ce qui va pouvoir nous aider à retrouver les différentes données pour guider notre décision. On peut l'interroger grâce à un petit programme qui va rapatrier les données pertinentes et nous permettre de visualiser tout cela de manière synthétique :

Tableaures(1).png
Perfs.png
Tailles.png

La performance de DistilBERT est vraiment supérieure, sans pour autant nécessiter un énorme espace disque... On va donc mettre en place notre API avec ce modèle

L'API et l'UI

1. L'API backend (avec FastAPI)

C'est celle qui gère les prédictions, qui expose un endpoint HTTP qui accepte une requête POST avec un texte de tweet et renvoie la prédiction (classe - positif ou négatif - et les probabilités d'appartenance à chaque classe). Je l'utilise avec mon API frontend, mais je pourrais très bien l'interroger depuis n'importe quelle autre appli ou service externe.

FastAPI est un framework web moderne, open-source, simple et de qualité pour créer des APIs en Python rapidement.

2. L'UI frontend (avec Streamlit)

Une interface web qui permet à un utilisateur humain de dialoguer avec l'API précédente, mais pas seulement : un bouton d'alerte va permettre à l'utilisateur d'envoyer des informations à un service de recueil de données en ligne, qui à son tour pourra m'alerter en cas de signalements récurrents.

Streamlit est un framework Python open-source pour construire des applications web interactives, dédiées à la data science et au machine learning.

D'abord je télécharge les poids et le dictionnaire du modèle depuis MLFlow. Ensuite je mets en place des tests unitaires, pour veiller au bon fonctionnement des composants de mes programmes malgré l'évolution du code qui ne manquera pas d'arriver.

Je synchronise mon répertoire local avec un dépôt GitHub (principale plateforme mondiale d’hébergement, de gestion de versions et de collaboration autour du code source).

Cette plateforme me permet aussi de déclencher des actions automatiques à chaque synchronisation de mon répertoire local et du dépôt : dans un premier temps j'enclenche donc la lancée des tests unitaires, pour vérifier automatiquement que mon code fait toujours ce que j'attends de lui.

Mais comment faire pour que mon code marche aussi bien sur internet que sur mon ordinateur (sur lequel j'ai créé un environnement virtuel, avec les bonnes librairies Python, etc.) ?

Pour cela je recours à Docker, qui comme son nom laisse penser, permet de faire des conteneurs qui encapsulent un environnement minimal nécessaire à la bonne marche de mes APIs.

Mieux : les actions automatiques de GitHub me permettent aussi, à chaque révision de mon code, de reconstruire automatiquement l'image de mes conteneurs, de les stocker sur une plateforme dédiée, DockerHub, et ensuite de déployer le tout grâce à Azure.

Azure me permet aussi de recevoir les informations de tweets signalés comme mal classés par mes utilisateurs. Un des modules, Azure Insights, me permet même de mettre en place une alerte. Dans mon exemple, si trois tweets sont signalés comme étant mal classés en moins de cinq minutes, je reçois un email et un SMS.

Add a Title

Add paragraph text. Click “Edit Text” to update the font, size and more. To change and reuse text themes, go to Site Styles.

Et après ?

Le suivi, qui n'est pas mis en place dans ce projet, est évidemment crucial.

Tout d'abord il faut bien penser au fait que le bouton d'alerte peut être détourné de sa vocation première - pour alerter, par exemple, d'un souci peut-être différent que celui anticipé, comme par exemple d'un message d'erreur.

Il faudra donc, en cas de hausse significative des alertes, réagir rapidement en vérifiant le bon fonctionnement général de l'API - même si les tests unitaires sont censés déjà offrir une protection à ce niveau.

Ensuite, une collecte des tweets considérés comme mal classés et une revue par un annotateur humain semblent indispensables.

Encore une fois, une attention au volume des alertes peut être instructive. Un pic peut signaler de nouveaux usages linguistiques (argot, phénomènes sociaux récents...)

Evidemment, si on distingue des tweets véritablement mal classés ou encore de nouveaux usages importants à intégrer, on voudra réentraîner le modèle, mais attention ! Notre corpus actuel est de grosso modo 1 600 000 tweets : quelques dizaines ne feront pas la différence. Il faudra donc étiqueter les tweets au fil de l'eau, mais attendre d'avoir une base numériquement importante (en général de 0,1% à 1%, donc ici de 1600 à 16 000 tweets) pour envisager un réentraînement. On peut aussi décider de sur-représenter certains tweets pour donner plus de poids à l'ajustement du phénomène qu'ils représentent. Une fois le modèle réentraîné, on réutilise le pipeline déjà présent (GitHub, Dockerhub, Azure) pour déployer de manière simple et rapide.

bottom of page