Présentation des techniques de NLP, Bag of words, TFIDF, modélisations supervisées et non-supervisées pour prédiction des tags automatiques sur les questions Stackoverflow
2. Analyse des métriques,
sélection du modèle et mise
en place d’une API.
SÉLECTION DU MEILLEUR MODÈLE
Contexte et problématique
de l’analyse.
Accès aux données.
PROBLÉMATIQUE
Nettoyage et analyse
exploratoire.
CLEANING ET ANALYSE EXPLORATOIRE
Développement des
modèles supervisés et non
supervisés.
MODÉLISATIONS
2
Sommaire
4. 4
Système de suggestion de tags pour Stackoverflow
LA PROBLÉMATIQUE :
Développer un algorithme de Machine Learning
destiné à assigner automatiquement plusieurs tags
pertinents à une question Stackoverflow.
Stackoverflow est un site de questions / réponses
créé en 2008, basé sur un système de votes.
INTERPRÉTATION :
Les procédés utilisés devront se baser sur des
techniques de NLP (Natural Language
Programming) et de classification multi-labels afin
de pouvoir prédire plusieurs tags sur des données
textuelles complexes.
5. 5
Accès aux données via StackExchange Explorer
STACKEXCHANGE EXPLORER:
Les données ont été captées via l'outil d’export de
données Stackexchange Explorer, qui recense un
grand nombre de données authentiques de la
plateforme d’entraide.
Pour avoir des données de bonne qualité à
exploiter, des critères ont été appliqués :
• Minimum 1 réponse
• 5 commentaires minimum
• 20 vues
• Un score (votes) supérieur à 5
6. 6
Accès aux données via StackExchange Explorer
REQUÊTES SQL POUR CAPTER LES DONNÉES:
Les données concernant les questions Stackoverflow ont été
extraites par période de 12 mois et concernent la période 2009
à 2020. Au total 103 234 questions seront analysées.
Des fichiers CSV ont été exportés et un dataset spécifique
couvrant la période est créé sur la plateforme Kaggle.
Ces données seront ensuite exploitées via Python et le code
versionné dans un repostory GitHub pour suivre les évolutions.
7. DATA CLEANING ET EDA
Connaître les datas : Nettoyage des données et analyse exploratoire
8. 8
Evolution des données Stackoverflow dans le temps
- Evolution constante de la base de questions du site de 2010 à 2014
- A partir de 2014, le nombre de nouvelles questions posées baisse jusqu’à aujourd’hui (base de connaissance étendue)
- En moyenne, 8 600 nouvelles questions sont posées chaque année.
9. 9
Analyse de la taille des titres de questions
Les modélisations portent sur les
variables « Title » et « Body » des
questions importées.
Il est donc important de vérifier la
distribution de la taille de ces
variables.
10. 10
Analyse de la taille des titres de questions
Les titres (Title) comptent en
moyenne 51 caractères.
Les bornes s’étalent entre 13 et 150
caractères.
La majorité des titres comptent entre
35 et 60 caractères.
11. 11
Distribution du nombre de caractères de Body
Pour le corps du texte des questions
(Body), la majorité des questions
compte moins de 4000 caractères.
En revanche, certaines questions
sont très longues – ici plus de 31 000
caractères.
Le jeu de données a donc été filtré
pour ne conserver que les questions
dont Body compte moins de 4000
caractères.
Après filtrage, il reste 94 202
questions soit 91% du volume initial.
12. 12
La variable à prédire : Les tags de questions
Pour la variable Tags issue de StackExchange, chaque tag
est enfermé dans des balises < >. Il est donc nécessaire
de supprimer ces balises pour créer ensuite des listes de
Tags.
Le jeu de données compte à ce stade :
16 050 tags uniques
13. 13
Les 40 tags les plus populaires de la base
Certains tags sont très confidentiels
et ne représentent que peu de
questions.
En revanche, dans les 40 tags les
plus populaires, C++, C# et Java
occupent le top 3.
On retrouve sans surprise les
principaux langages de
programmation dans cette liste des
tags populaires.
14. 14
Evolution des top tags dans le temps
On peut remarquer une évolution des
Tags préférés qui suit la tendance des
modes de codage.
En effet, en 2016 par exemple, Javascript
est devenu le tag le plus populaire et
restera dans le top 3 jusqu’en 2020, tout
comme Python.
15. 15
Nuage de mots des 500 premiers Tags
Afin de visualiser plus
facilement les 500 tags les
plus populaires, nous
pouvons projeter un words
cloud coloré.
Ici, la taille et les couleurs
des mots nous permet de
voir facilement les plus
populaires.
16. 16
Combien de tags par question ?
Nos modèles étant basés sur des
classifications multi-labels, il est
nécessaire de vérifier la distribution du
nombre de tags par question.
La majorité des questions compte donc
3 tags et en moyenne entre 2 et 4 tags
sont attribués.
17. 17
Combien de tags par question ?
A ce stade, les questions sont à
nouveau filtrées.
Sont conservées uniquement les
questions qui comportent au moins 1
tag parmi les 50 meilleurs. Les autres
tags restant sont supprimés.
Le jeu de données compte 83 239
questions après filtrage.
19. 19
Elimination du code et balises HTML
LES BALISES <CODE>:
Une des spécificités de Stackoverflow est de pouvoir partager du
code dans les questions posées.
Ces balises « polluent » le texte avec des termes spécifiques. Tout leur
contenu est donc éliminé avec les méthodes findAll() et replace_with()
de la librairie BeautifulSoup.
LES BALISES HTML :
Dans la variable Body récupérée par extraction, le texte est en
langage HTML.
Nous récupérons donc uniquement le texte brut grâce à la méthode
get_text() de BeautifulSoup.
20. Les liens de type http et
https sont supprimés ainsi
que tous les nombres grâce
aux expressions régulières.
LIENS ET NOMBRES
En premier lieu, suppression
de tous les mots autres que
les noms communs et noms
propres avec Spacy.
POS TAGGING
Tous les mots obtenus sont
convertis en minuscules et
les caractères unicodes (type
Emoji par exemple) sont
supprimés.
CASE NORMALIZATION
Toute la ponctuation ainsi
que les espaces
supplémentaires sont
supprimés grâce aux
expressions régulières.
PONCTUATION, ESPACES
20
Les étapes importantes du Data Cleaning (Body)
1 2 3 4
21. 21
Le texte cleané après ces premières opérations
Ces étapes de nettoyage du texte ont pour effet de
supprimer tous les termes qui ne seront pas utiles à nos
modélisations.
On constate à présent que nous obtenons une suite de
noms identifiés par POS tagging sans ponctuation, sans
nombre et tout en minuscule.
22. Création d’une liste des
mots de chaque document
(ici c’est une tockenisation
simple, les phrases ne sont
pas conservées)
TOCKENISATION
Les mots les plus communs de la
langue Anglaise sont supprimés
grâce à la librairie NLTK.
SUPPRESSION DES STOP WORDS
Mise en forme à la racine de
chaque mot (Lemme) pour
amener chaque terme à sa
forme dictionnaire. (NLTK)
LEMMATISATION
22
Les étapes importantes du Data Cleaning (Body)
5 6 7
23. 23
Le texte cleané après ces dernières opérations
La suite de mots a laissé place à des listes de mots qui
sont à présent sous leur forme « racine », au singulier par
exemple et sans les mots les plus communs.
Ces listes pourront ensuite entrer dans des traitements de
preprocessing pour être converties en matrices de
fréquences de termes.
24. 24
Analyse des tokens obtenus dans la variable Body
les documents contiennent 20
tokens (médiane) et la majorité se
situe sous les 50 tokens.
En moyenne les 2000 mots les plus
communs, apparaissent 960 fois
dans le corpus. Certains mots sont
utilisés plus de 46 000 fois.
Ces termes très fréquents seront
filtrés avant l’entrainement des
modèles.
25. 25
Nuage de mots des 500 mots les plus populaires de Body
On remarque ainsi
facilement les mots les plus
représentés dans le corpus.
Code, function, error, file …
26. 26
Nettoyage des titres de questions
CRÉATION D’UNE FONCTION TEXT_CLEANER:
Toutes ces étapes de nettoyage sont inscrites dans une fonction Python utilisant les
modules NLTK, SpaCy et les expressions régulières. Cette fonction sera également
utilisée dans le nettoyage des textes envoyés à l’API.
29. 29
Latent Derelicht Allocation - LDA
Pour les modèles non-supervisés, la
variable Tags n’est pas utilisée.
Les modèles utilisent des méthodes
de classifications probabilistes pour
affecter chaque document à un (ou
plusieurs) topics.
LDA utilise deux valeurs de
probabilité : 𝑃 𝑤𝑜𝑟𝑑 𝑡𝑜𝑝𝑖𝑐𝑠 et
𝑃 𝑡𝑜𝑝𝑖𝑐𝑠 𝑑𝑜𝑐𝑢𝑚𝑒𝑛𝑡𝑠 calculées sur
la base d’une attribution initiale
aléatoire.
Ces calculs sont répétés pour
chaque mot dans chaque document
jusqu’à convergence de l’algorithme.
30. 30
LDA avec la librairie spécialisée Gensim
Pour traiter nos données textuelles
dans des algorithmes de Machine
Learning, nous devons les convertir
en données numériques.
Preproccessing LDA avec Gensim :
• Bag of words : Dictionnaire des
termes du corpus.
• Matrice de fréquence des termes
des documents.
• Filtrer les mots qui apparaissent
dans plus de 60% des documents.
31. 31
LDA avec la librairie spécialisée Gensim
En d’autres termes, chaque mot du document est associé à un identifiant et la fréquence d’apparition de chacun des termes est
calculé dans une matrice.
La fonction filter_extremes() nous permet de filtrer les données qui sont très fortement représentées dans les documents.
32. 32
LDA – Fixer le nombre de topics idéal
Pour LDA, il est nécessaire de
fixer en paramètre du modèle le
nombre de topics à créer
(num_topics).
Une itération du modèle avec
num_topics compris entre 1 et 81
a donc été réalisée en calculant
le score de cohérence.
Le meilleur score est obtenu avec
31 Topics, notre modèle LDA sera
donc entrainé avec ce
paramètre.
33. 33
LDA – Visualisation des résultats avec PyLDAvis
Grâce à la bibliothèque PyLDAvis, il est
possible de visualiser les topics créés sur le
premier plan factoriel ainsi que les 30 mots
les plus représentatifs de chaque topic.
On voit par exemple ici que le topic 5
semble regrouper les problématiques
HTML.
Certains topics sont très proches, voir se
superposent.
34. 34
LDA – Affecter les tags « predits » à chaque question
LDA n’a pas de méthode de prédiction. Afin
d’affecter des tags aux documents en
fonction des topics créés, il est nécessaire
de créer une matrice Topic/Tags en réalisant
une multiplication matricielle des matrices
Document/Topic et Document/Tag.
Matrice Document/Topic : Obtenue avec la
méthode get_document_topic() de Gensim.
Matrice Document/Tag : Obtenue avec
Multilabel_Binarizer des tags.
Le détail de ces calculs est disponible dans le Notebook en annexe.
35. Synthèse LDA
LDA permet d’attribuer des topics à
chaque document grâce à des calculs
probabilistes.
Les topics créés sont difficilement
interprétables et parfois très proches.
Il n’existe pas de méthode de prédiction
(algorithme non-supervisé) et les calculs
d’attribution de tags sont fastidieux et
imprécis.
Les métriques obtenues sur les scores
de Jaccard et F1 sont faibles. Ils serviront
de baseline.
36. 36
Non-negative Matrix Factorization - NMF
PREPROCESSING :
Pour tous les modèles suivants, le même preprocessing est
appliqué :
• TfidfVectorizer : La matrice de fréquence de termes est ici
créée avec la méthode TfidfVectorizer() de Scikit-Learn.
Ainsi, la fréquence d’apparition des mots sera pondérée
avec un indicateur de similarité (l’inverse de la proportion
de document qui contient le terme)
37. 37
Non-negative Matrix Factorization - NMF
LE MODÈLE :
La factorisation matricielle non-négative est un
modèle linéaire-algébrique qui factorise des
vecteurs de grande dimension dans une
représentation de faible dimension (similaire à
l’analyse en composante principale).
Ce modèle ne peut pas être scoré. Nous allons
donc appliquer le même nombre de topics que
la LDA pour comparaison et projeter les topics
calculés.
38. 38
Les topics calculés avec NMF
En observant les projections des 12 premiers
topics, on s’aperçoit que un mot est
caractéristique et plus représentatif de chaque
catégorie.
Le topic 8 par exemple semble traiter des bases
de données mais pour le topic 7, les
regroupement sont moins facilement
interprétables.
39. Synthèse NMF
NMF n’est pas scorable. Ses
performances sont difficilement
comparables.
Les topics créés sont difficilement
interprétables, tout comme LDA.
Il est difficile d’estimer le nombre de
topics idéal à créer.
NMF, comme LDA, ces modèles non
supervisés ne sont pas suffisamment
adaptés à la problématique des tags
Stackoverflow.
41. Prédictions sur le test split
avec le modèle entrainé sur
les meilleurs paramètres.
PRÉDICTIONS
Création d’un jeu
d’entrainement et d’un jeu
de test (30% des données).
SPLIT DES DONNÉES
Recherche des meilleurs
hyper-paramètres avec une
grille de recherche et
validation croisée (5 splits).
GRIDSEARCHCV
Entrainement sur les
données du train split avec
les meilleurs paramètres de
la GridSearchCV.
ENTRAINEMENT
41
Méthodologie appliquée aux modèles supervisés
1 2 3 4
Calcul des score F1, Jaccard,
Accuracy, Precision et Recall
pour séléctionner ensuite le
modèle avec les meilleures
métriques.
CALCUL DES MÉTRIQUES
5
42. 42
Les métriques principales calculées
Cette métrique combine la précision et le rappel.
Elle est plus intéressante que l’Accuracy car le
nombre de vrais négatifs n’est pas pris en
compte.
F1 Score
𝐹1 𝑠𝑐𝑜𝑟𝑒 = 2
𝑝𝑟𝑒𝑐𝑖𝑠𝑖𝑜𝑛 ∗ 𝑟𝑒𝑐𝑎𝑙𝑙
(𝑝𝑟𝑒𝑐𝑖𝑠𝑖𝑜𝑛 + 𝑟𝑒𝑐𝑎𝑙𝑙)
𝑝𝑟𝑒𝑐𝑖𝑠𝑖𝑜𝑛 =
𝑇𝑃
𝑇𝑃 + 𝐹𝑃
𝑟𝑒𝑐𝑎𝑙𝑙 =
𝑇𝑃
𝑇𝑃 + 𝐹𝑁
L’indice de Jaccard est une mesure de similarité
entre 2 ensembles d’objets. Elle représente le
cardinal de l’intersection divisé par le cardinal
de l’union.
Jaccard
𝐽 𝐴, 𝐵 =
|𝐴 ∩ 𝐵 |
|𝐴 ∪ 𝐵 |
43. 43
Régression Logistique avec OneVsRestClassifier
Le modèle de régression logistique est entrainé
avec le classifier One Versus Rest. Cet
estimateur utilise la méthode de pertinence
binaire afin d’entrainer un classifier pour chaque
étiquette.
Grâce à une grille de recherche avec validation
croisée, les meilleurs paramètres sont estimés et
les métriques calculées avec la meilleure
combinaison sur le jeu de test.
Suite à la transformation inverse du
Multilabel_Binarizer nous pouvons visualiser les
premières prédictions :
44. 44
Algorithme des fôrets aléatoires (RandomForest)
ONE VERSUS REST :
Ici encore, les hyper-paramètres sont testés
dans une GridSearch avec Cross-validation sur
un échantillon du train set.
- Max_depth : Profondeur maximale de l’arbre
- Min_sample_leaf : Nombre minimum
d’échantillons dans un nœud feuille.
Les prédictions obtenues varient
comparativement au modèle de régression
logistique :
45. 45
RandomForest avec Classifier Chains
CLASSIFIER CHAINS :
Un second modèle de RandomForest a été
testé avec la méthode ClassifierChains. Dans ce
cas chaque modèle fait une prédiction dans
l'ordre spécifié en utilisant toutes les
fonctionnalités disponibles fournies au modèle
mais également les prédictions des modèles
précédents.
Les prédictions obtenues sont de nouveau
différentes du précédent modèle
RandomForest.
Les métriques obtenues seront analysées au
moment de la sélection du modèle final.
46. 46
Réseau de neurones simple avec Keras
MODÈLE DE DEEP LEARNING:
Enfin, un dernier modèle supervisé a été testé.
Une pile linéaire de couches complétement
connectées.
Le nombre de neurones en entrée correspond
au nombre de termes de la matrice de
fréquence (579).
Le nombre de neurones en sortie correspond
au nombre de tags soit 50.
Le modèle est entrainé avec 20 époques et il
est également possible de visualiser les
premières prédictions :
47. Synthèse modèles
supervisés
Ces modèles permettent d’obtenir
directement des tags prédits en sortie.
Les métriques sont donc globalement
bien meilleures que celle des modèles
non-supervisés.
Les temps d’entrainement sont en
revanche beaucoup plus important.
Selon les modèles, le taux de non prédit
est très variable.
49. 49
ANALYSE DES MÉTRIQUES:
En se basant sur les scores F1 et Jaccard,
les 2 meilleurs modèles sont :
• Le réseau de neurones
• La régression logistique.
Cependant, le taux de non-prédit de
ces modèles est élevé : entre 21 et 30%
de questions sans prédictions.
Le modèle RandomForest avec Classifier
Chains retourne des métriques proches
mais avec un taux de non prédit quasi
nul.
Il est donc à mon avis préférable de
sélectionner ce modèle pour obtenir un
maximum de prédictions correctes.
50. Une API a été développée en
Python (Flask et Swagger) afin de
pouvoir tester un modèle pré-
entrainé.
La documentation est disponible
en ligne sur Heroku à l’adresse :
https://stackoverflow-ml-
tagging.herokuapp.com/apidocs/
Tester le modèle
en ligne
50