Suite de notre première partie. Nous avions utilisé une méthode de sondage pour déterminer le nombre de salons de coiffure dont le nom est un jeu de mots. Dans cette seconde partie, nous allons essayer d’utiliser une méthode d’apprentissage pour estimer ce nombre. L’idée sera d’entraîner un modèle à reconnaître si une enseigne de coiffure présente un jeu de mots ou non. C’est parti !
Jeu d’entraînement
Il faut commencer par constituer un “jeu d’entraînement” (ou training set), qui comportera des noms avec et sans jeu de mots, de manière à ce que le modèle choisi puisse construire une règle de classification. Ce jeu d’entraînement, nous allons devoir le constituer à la main. Comme je n’ai pas envie de passer mon dimanche entier à classer des noms de salons de coiffure suivant qu’ils contiennent un jeu de mots ou non (je serais obligé de mentir si on me demandait ce que j’ai fait de mon week-end à la machine à café lundi matin) je choisis de me limiter à 200 enseignes, que je vais tirer aléatoirement dans la base.
Petite remarque supplémentaire : si je tirais ces noms avec une probabilité uniforme (comme on l’a d’abord fait en première partie), ma base comporterait environ 10 enseignes avec jeu de mots contre 190 enseignes sans (puisque, d’après la première partie, le taux de salons de coiffure avec un jeu de mot vaut environ 5%). Avec simplement 10 noms comportement un jeu de mot dans notre base de références, faire classer efficacement les noms de salons par un modèle ne serait pas chose aisée… Je choisis donc d’utiliser à nouveau un tirage stratifié (comme en première partie), de manière à équilibrer les données sur lesquelles le modèle va être entraîné.
Avant de passer à la suite, je réserve 50 noms parmi mes données d’entraînement que j’utiliserai uniquement pour tester la qualité de mon modèle. Le modèle sera donc entraîné sur 150 noms de salons, parmi lesquels environ 50% présentent un jeu de mot (je nomme ces données “jeu de développement”).
Une nécessaire sous-estimation
Il va s’agir de choisir un classificateur d’apprentissage qui présente de bonnes performances sur des données issues de Natural Language Processing (NLP). Le but est que notre modèle soit capable de reconnaître un jeu de mots similaire à ceux qui sont contenus dans le jeu de développement. Des noms similaires à une enseigne contenue dans le jeu de test devraient être correctement classés si les différences sont mineures (quelques lettres, l’ordre, une préposition en plus ou en moins, etc.). Par exemple, si le jeu de développement contient “FAUT TIFF HAIR”, il est bien possible que “FAUTIF HAIR” ou “FAUT TIF HAIRS” soient correctement classés. A fortiori, tous les noms strictement identiques à ceux du jeu de développement seront correctement classés. Par contre, on ne peut pas raisonnablement s’attendre à ce que le modèle soit capable de reconnaître un jeu de mots très différent de ceux qui seront contenus dans cette base de données.
Finalement, il faut s’attendre à ce que cette façon de procéder aboutisse à une sous-estimation du nombre de salons de coiffure avec jeu de mots. Pour le vérifier, on pourra comparer avec l’intervalle de confiance établi en première partie.
Le choix du modèle
J’utilise l’excellent librairie python scikit-learn, que j’utilise pour tester différents types de classificateurs. Bien souvent en machine learning, il s’agit de tester rigoureusement différents modèles et différents choix de paramètres comparativement les uns aux autres. Dans notre cas, je cherche simplement un classificateur suffisamment performant pour aboutir à une conclusion à peu près robuste. Je me contente donc de quelques essais à la main pour effectuer mon choix de modèle. J’effectue ensuite un petit grid search pour tester différents choix de paramètres. Dans le cas du choix de modèle comme du grid search, j’utilise une validation croisée pour choisir le meilleur modèle. Mon classificateur final est donc :
vectorizer = TfidfVectorizer(ngram_range=(1, 3), analyzer='char',
use_idf=False, stop_words=["SARL", "SAS", "SA"])
clf = Pipeline([
('vec', vectorizer),
('clf', SGDClassifier(loss="hinge", penalty="l2")),
])
clf.fit(docs_train, y_train)
Je peux enfin tester la performance de mon modèle sur le jeu de test de 50 noms que j’ai mis de côté :
|
Classé “avec jeu de mots” |
Classé “sans jeu de mots” |
Sans jeu de mots |
17 |
7 |
Avec jeu de mots |
11 |
15 |
Par ailleurs, le jeu de test contenait 26 noms avec jeu de mots. L’estimation issue du modèle donne 22 noms avec jeu de mots, ce qui est cohérent avec le fait qu’on s’attend à obtenir une sous-estimation.
Petits tests à la main
Avant de faire tourner le classificateur sur l’ensemble de la base, j’effectue quelques petits tests à la main, avec des noms d’enseigne inventés. Comme prévu “CREA TIFFS”, “FAUT TIFF HAIR” et “FAUX TIFF HAIR”, proches de certains noms du jeu de développement, sont bien reconnus comme présentant un jeu de mot . “HAIR DRESSER” et “COIFFURE JEAN MICHEL” sont également correctement classés, en tant que noms ne présentant pas de jeu de mots. Je teste ensuite “LA CHAMBRE A HAIR”, “VOLT HAIR” et “LE SAVOIR F HAIR” (merci au tumblr lolcoiffeurs pour les idées !), sans grand espoir car ces jeux de mots me semblent trop éloignés de ceux présents dans le jeu d’entraînement. Et pourtant, les trois sont bel et bien reconnus comme jeux de mots ! Mon dernier test, “DE MECHE AVEC VOUS”, n’est lui pas correctement reconnu. Cela ne m’étonne pas outre mesure, car le nom de salon qui s’en approchait le plus dans mon jeu d’entraînement était “MECH EN LOOK”, qui ne contenait même pas le mot “MECHE” en entier. Finalement, je suis plutôt agréablement surpris des performances du modèle (comme souvent en learning , même si dans notre cas, le modèle et son ambition sont très modestes).
Les résultats
En exécutant notre classificateur sur toute la base des noms de salons, on obtient une valeur d’estimation de :
916, soit 3% de coiffeurs (contre environ 5% par la méthode par sondage)
présentant un jeu de mots dans leur enseigne. Ce chiffre correspond à l’estimation basse obtenue par sondage en partie 1. Ceci est cohérent avec notre remarque faite plus haut : ce chiffre obtenu par apprentissage est une sous-estimation du nombre total.
Dernière remarque : ce modèle est valable uniquement pour les enseignes de salons de coiffure. On pourrait appliquer une méthode similaire pour déterminer le nombre de jeu de mots parmi les enseignes d’un autre secteur (les boulangeries par exemple), en changeant le training set et en ajustant le modèle. Mais trouver une méthode générale pour reconnaître ce qui constitue ou non un jeu de mots en français serait une autre paire de manches !
Note 1 : L’image-titre est issue d’une note de Boulet, qui possède un blog bd très sympa que je vous encourage à aller voir !
Note 2 : en échangeant à propos de cet article, on m’a fait remarquer que notre définition du jeu de mot n’incluait pas par exemple le cas d’un jeu de mot “pour initié” sur le quartier dans lequel est situé la boutique ou sur le nom des entrepreneurs. Je précise donc que notre définition recouvre plus ou moins les jeux de mots “compréhensibles par tous” 😉