Mathis Hammel Profile picture
Jul 17 33 tweets 9 min read Twitter logo Read on Twitter
🧶THREAD - Un programme de 15 lignes de code Python arrive à rivaliser avec les meilleures intelligences artificielles !

Cette drôle de découverte vient d'être publiée par une équipe de chercheurs canadiens, et risque de bouleverser le monde du Machine Learning.

Explications ⤵️ "Qui gagne ?"  À gauche, un réseau de neurones ultra perfectionné avec 340 millions de paramètres  À droite, 15 lignes de Python
La classification de texte est l'un des domaines de recherche les plus actifs en intelligence artificielle : elle consiste à trier automatiquement des textes courts dans un ensemble de catégories pré-définies. Quelques phrases classées par catégorie :  Le briquet a été inventé 3 ans avant l'allumette (Histoire)  Les crocodiles ne peuvent pas tirer la langue (Nature)  Le miel ne périme jamais (Cuisine)  Les amandiers et les pêchers sont dans la même famille d'arbres (Nature)  (Instant culture inutile : toutes ces phrases sont vraies)
Pour évaluer la performance d'un modèle, on va travailler avec des datasets spécifiques.

L'un des plus connus est basé sur 1.4 millions de questions posées sur le site Yahoo Answers, réparties en 10 catégories : Plusieurs questions triées dans un tableau par catégorie. Voici par exemple les questions de la catégorie "Société" :  Comment ont été inventés les gros mots ? Comment devenir gothique ? SI DIEU NOUS A FAIT QUI A FAIT DIEU !? Est-ce que bisexuel est plus fun ? Croyez-vous en le nouvel an chinois ? Sens de la vie ?  (oui, ces questions existent vraiment dans le dataset)
L'algorithme peut donc utiliser ces données pour apprendre à quoi ressemblent les questions de chaque catégorie.

On va ensuite le mettre à l'épreuve avec 60 000 questions non-étiquetées sur lesquelles il devra prédire la catégorie. Quatre questions dont on ne connaît pas la catégorie :  Quel âge a Homer Simpson ? Quel est le budget militaire des USA ? Où puis-je acheter une quille de bowling ? Quelle est la différence entre HTML et XHTML ?
Il existe plusieurs manières de mesurer la performance d'un modèle de machine learning sur cette tâche.

La plus courante consiste à simplement calculer le taux de bonnes réponses : par exemple, un modèle qui donne 45k catégories correctes sur les 60k textes aura un score de 75%.
Cette mesure est appelée l'accuracy, ou "précision" en français.

Cependant, le mot français est peu utilisé car ambigu avec le terme anglais "precision" : Quatre cibles avec des impacts dessus :  La première a des impacts très étalés partout : low accuracy, low precision La deuxième a des impacts très groupés mais éloignés du centre : low accuracy, high precision La troisième a des impacts peu groupés, mais relativement proches du centre : high accuracy, low precision La dernière a des impacts qui se trouvent tous dans le cercle central : high accuracy, high precision
À l'heure actuelle, parmi les modèles textuels les plus performants (dits "à l'état de l'art") on retrouve notamment BERT, publié en open source par Google en 2018.

C'est un modèle immense qui compte jusqu'à 340 millions de neurones !
Face à ce titan, les chercheurs de l'université de Waterloo ont donc décidé de créer... un script tout simple de 15 lignes. Et ça a marché 😁

Regardons de plus près son fonctionnement.   import gzip   import numpy as np    for (x1, _) in test_set:       Cx1 = len(gzip.compress(x1.encode()))       distance_from_x1 = []       for (x2, _) in training_set:           Cx2 = len(gzip.compress(x2.encode()))           x1x2 = " ".join([x1, x2])           Cx1x2 = len(gzip.compress(x1x2.encode()))           ncd = (Cx1x2 - min(Cx1, Cx2)) / max(Cx1, Cx2)           distance_from_x1.append(ncd)
Dans l'algo présenté, on repère quelques opérations de la forme len(gzip.compress(x)) : c'est ici que se cache son secret.   import gzip   import numpy as np    for (x1, _) in test_set:       Cx1 = len(gzip.compress(x1.encode()))       distance_from_x1 = []       for (x2, _) in training_set:           Cx2 = len(gzip.compress(x2.encode()))           x1x2 = " ".join([x1, x2])           Cx1x2 = len(gzip.compress(x1x2.encode()))           ncd = (Cx1x2 - min(Cx1, Cx2)) / max(Cx1, Cx2)           distance_from_x1.append(ncd)
Gzip est un utilitaire de compression de fichiers basé sur le même algorithme que pour les fichiers .zip : en trouvant des motifs qui se répètent dans les données à compresser, on va pouvoir réduire la taille du fichier sans perdre d'information. Un document de 8,3Mo est compressé avec gzip et ne fait plus que 4,5Mo après compression. La décompression restaure le fichier original de 8,3Mo.
Et ce facteur de compression peut justement être utilisé pour mesurer la redondance d'information dans un texte !

J'ai compressé 1000 caractères de la page Wikipédia "réseaux de neurones artificiels" et 1000 caractères aléatoires, voici les résultats respectifs : L'article Wikipédia se compresse en 536 octets, alors que le texte aléatoire occupe 882 octets après compression.
On peut donc constater qu'un texte en français contient davantage de redondance (= moins d'entropie) qui permet de le compresser plus efficacement.

De même, la concaténation de deux textes se compressera plus facilement si les deux textes sont similaires : La concaténation de l'article Pizza et Tomate se compresse en 950 octets, alors que la concaténation des articles Pizza+Clown occupe 1030 octets.
En se basant sur cette observation, on peut donc mettre en place un système capable de calculer une sorte de "distance sémantique" entre deux textes !

La formule ci-dessous est celle qui est utilisée par les chercheurs dans leur article : NCD(x,y) = (C(xy) - min(C(x), C(y))) / max(C(x), C(y))
Cette formule provient de concepts théoriques comme la distance de Kolmogorov conditionnelle et l'information algorithmique mutuelle.

Sûrement des concepts inventés par les chercheurs pour se la péter en soirée, mais je vais vous montrer qu'on peut la comprendre facilement. De la notation compliquée sur un papier de recherche en anglais
Considérons que l'on veut comparer la similarité de deux textes x1 et x2. On note C(x) la taille d'un texte x après compression.

Pour simplifier les choses, on va dire que la distance est comprise entre 0 et 1, et que C(x1)≥C(x2).
Penchons-nous sur deux cas extrêmes :
Cas 1 - x1 et x2 sont extrêmement similaires : les infos de x2 sont entièrement contenues dans x1.
Ajouter x2 après x1 ne change pas la taille du fichier compressé.

Les deux textes sont très proches, on souhaite donc que leur distance soit 0. Information parfaitement redondante : C(x1+x2) = C(x1)
Cas 2 - x1 et x2 sont radicalement différents : compresser x1+x2 ensemble ne permettra pas de gagner de place par rapport à la compression des deux textes séparément.

Ici, on veut donner une distance élevée (donc 1) à cette paire de textes. Information parfaitement exclusive : C(x1+x2) = C(x1)+C(x2)
Bien sûr, ces deux cas sont extrêmes et ne se produisent pas en pratique, mais à l'aide de ces deux points de référence il est maintenant possible de mettre en place une fonction affine qui donne la distance en fonction de C(x1+x2) : Une droite dont l'équation affine est la suivante : dist(x1, x2) = (C(x1+x2)-C(x1))/C(x2)
L'équation de la droite ci-dessus correspond en fait exactement à celle utilisée par les chercheurs de l'université de Waterloo !

La seule différence est l'utilisation des fonctions min et max, qui permettent d'échanger potentiellement x1 et x2 pour s'assurer que C(x1)≥C(x2). NCD(x,y) = (C(xy) - min(C(x), C(y))) / max(C(x), C(y))
Avec cette formule, on peut maintenant créer un puissant classificateur : pour trouver la catégorie d'un texte x1 inconnu, on va chercher le texte x2 parmi le dataset d'entraînement qui s'en approche le plus.

Il est probable que la catégorie de x1 soit la même que x2. Plusieurs textes sont comparés avec le texte "Quelle est la meilleure équipe de basketball ?" : le texte avec la distance la plus proche est "Où a été inventé le basket ?" dans la catégorie Sport. Il est donc probable que le texte que l'on cherche à classifier fasse partie de la catégorie Sport.
En pratique, les résultats sont impressionnants : sur un benchmark comprenant 13 modèles récents, cet algorithme parvient à se classer sur le podium à plusieurs reprises, et même en première place sur de nombreux datasets non-anglais !
Et même si BERT semble tout de même plus efficace que notre technique magique à base de gzip, cette dernière présente 3 avantages majeurs :

- Sa simplicité de mise en œuvre
- Aucun pré-entraînement nécessaire
- Une bonne performance dans toutes les langues
Avant de terminer ce thread, je vous propose deux petites curiosités de code liées à ce papier.

La première est une erreur algorithmique que j'ai trouvée dans le code publié : un calcul pourrait être optimisé, voyez-vous lequel ? (indice : c'est dans les 3 dernières lignes) Les dernières lignes du script sont :  sorted_idx = np.argsort(np.array(distance_from_x1)) top_k_class = training_set[sorted_idx[:k], 1] predict_class = max(set(top_k_class), key=top_k_class.count)
On peut constater ici que le code cherche les k textes les plus proches de chaque x1 dans le jeu d'entraînement, puis trouve la catégorie majoritaire parmi ceux-ci.
On appelle ça une recherche kNN (k Nearest Neighbors). Dans ce papier en particulier, les chercheurs prennent k=2.
Pour calculer les k plus proches voisins, l'implémentation du papier de recherche va faire quelque chose comme ça (via numpy.argsort) : distances = [] for x2 in training_set:     distances.append(dist(x1, x2)) k_lowest = sorted(distances)[:k]
Cette opération est en réalité très inefficace : on appelle une fonction de tri sur un tableau gigantesque (jusqu'à 1,4 millions d'éléments pour le dataset Yahoo Answers), pour n'utiliser que les 2 premiers résultats...
En utilisant un tas binaire, structure de données spécialisée, on peut grandement améliorer la performance du calcul en ne gardant que les k meilleurs résultats au fil de l'exécution : la complexité temporelle de l'extraction passe de O(N·log(N)) à O(N·log(k)). import heapq heap=[-1]*K for x2 in training_set: 	heapq.heappushpop(h, dist(x1, x2)) return sorted(heapq)
Et en pratique ?

Sur le dataset Yahoo Answers, j'ai atteint un gain de performance de +16% avec cette optimisation, ce qui est loin d'être négligeable sur un benchmark qui demande 6 jours de calcul !
(La technique gzip est très lente car on doit calculer toutes les paires)
La seconde curiosité que je voulais vous montrer concerne la taille du code : c'est rare d'avoir un papier de recherche complet qui tient en 15 lignes de code, mais peut-on aller encore plus loin ?
En utilisant quelques techniques assez sales, j'ai réussi à faire passer le script de 538 à 214 caractères (en ajoutant au passage mon optimisation algorithmique 😇)

Je vous présente le meilleur classifieur de texte au monde qui tient en un tweet :
# state-of-the-art gzip text classifier in a tweet

import gzip,heapq
g=lambda x:len(gzip.compress(x))
def classify(t):
A=g(t)
h=[(-1,)]*K
for(a,b)in train:heapq.heappushpop(h,((min(A,g(a))-g(t+b' '+a))/max(A,g(a)),b))
s=[x[1]for x in h]
return max(set(s),key=s.count)
Fin du thread, merci d'avoir tenu jusqu'au bout !
Il aurait pu être 2 fois plus court si je voulais aller droit au but, mais y'avait plein de petites digressions que je trouvais trop intéressantes. N'hésitez pas à partager ☺️
Et pour aller lire le papier de recherche complet, c'est par ici :

Merci à @Guardia_School pour son soutien sur mes activités de vulgarisation :)aclanthology.org/2023.findings-…

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Mathis Hammel

Mathis Hammel Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @MathisHammel

Jul 7
Bon, j'ai trouvé une manière de cracker le nouveau shadowban Twitter 🥳

Déroulez pour + de détails ⤵️ Image
Vous le savez peut-être, certains mots sont devenus "interdits" sur Twitter : les mentionner appliquera sur vos tweets un facteur qui pénalisera généralement votre visibilité de 80% en moyenne.
Sans surprise, parmi ces termes bannis on retrouve
ВIuеsky et Τhrеads, deux réseaux sociaux concurrents de Twitter.

Normal de vouloir éviter que les utilisateurs se barrent chez la concurrence, mais Musk n'aurait pas besoin de faire ça si Twitter était en bonne santé... Image
Read 9 tweets
Jun 22
Mini-thread pour vous expliquer cette formule magique capable de détecter si un nombre est premier⤵️
Cette chaîne de caractères assez cryptique est une expression régulière (ou regex).

C'est une manière de décrire des motifs de caractères pour qu'un ordinateur puisse les détecter dans un texte.

Commençons par un exemple plus simple :
La sous-partie en jaune nous indique qu'il faut chercher 3 un motif de la forme suivante :
- Un chiffre (caractère entre 0 et 9)
- Un autre chiffre
- Éventuellement un point ou un espace (le point d'interrogation indique que le dernier groupe est optionnel)
Read 23 tweets
May 29
THREAD #OSINT - Comment j'ai découvert un réseau d'entreprises fictives sur LinkedIn qui administre des centaines de faux profils.

La semaine dernière, j'ai reçu une invitation LinkedIn de ce profil qui m'a tout de suite paru suspect.

Je vous explique ⤵️ Profil LinkedIn de Richard ...
Pas de chance pour Richard, j'ai beaucoup travaillé sur les faux visages générés par intelligence artificielle et je sais les reconnaître en un coup d'oeil.

L'indicateur le plus évident, c'est la position des yeux : certaines IA vont toujours les placer au même endroit. Photo de profil de Richard ...
Par curiosité, je vais jeter un oeil à la page de Digitize, l'entreprise pour laquelle travaille Richard.

Et là, énorme surprise : parmi les 43 employés de l'entreprise, la quasi-totalité présente une photo de profil qui semble générée par une IA ! 6 comptes LinkedIn avec des...
Read 33 tweets
Feb 8
Je suis à Stockholm cette semaine pour la conférence @Jfokus, et j'ai décidé de participer au quiz de l'un des sponsors. Je crois que j'ai gagné 😇

Petit thread de cybersécurité appliquée dans lequel je vous explique comment j'ai fait ⤵️ @MathisHammel (moi) premier...
En voyant que le classement est basé sur la rapidité, j'ai eu envie de l'automatiser pour avoir un temps surhumain.

Mais ça, c'était avant de découvrir trois failles dans l'appli ! (restez jusqu'au bout du thread, j'ai une technique de hacking ultra puissante à vous montrer)
Avant toute chose, on doit commencer par une phase de reconnaissance : comprendre le fonctionnement du site, sa surface d'attaque, les technos utilisées côté serveur, etc.

Ici très simple, je regarde simplement les requêtes envoyées par mon ordi en faisant le quiz normalement. From which company does Kot...
Read 26 tweets
Feb 3
THREAD : Les intelligences artificielles peuvent-elles coder à notre place ?

J'ai donné 5 exercices de code à ChatGPT et GitHub Copilot, voici les résultats ⤵️ ChatGPT vs. Copilot
Pour chaque exercice, je donne à l'IA un bout de code et un commentaire pour lui expliquer ce qu'elle doit faire.

J'ai choisi des cas simples, avec des problématiques réalistes que l'on peut rencontrer dans des projets de dev.
EXERCICE 1

On commence en douceur avec un échauffement Python, la fonction doit télécharger une image puis calculer son hash. Une fonction utilitaire très classique qui s'écrit en quelques lignes. def fetchAndHashImage(url):     '''     returns the SHA512 h
Read 26 tweets
Jan 18
🌶️ Hot take (+ mini thread)

Les imposteurs dans la tech détestent les évaluations CodinGame, parce que c'est beaucoup plus facile de mentir sur un CV que sur un test de code. 1/6 Un rapport de test d'entretien CodinGame en langage Java et
Évidemment, il existe plein d'autres raisons de ne pas aimer ces tests, notamment le stress.

Mais si vous refusez toute évaluation de vos compétences en considérant qu'un CV est suffisant pour vous connaître, vous finirez dans des équipes remplies d'imposteurs.
Comprenez bien que ces évaluations sont créées pour vous mettre en difficulté et tester les limites de vos compétences : même si c'est frustrant, il est normal (voire attendu) de ne pas obtenir 100%.

La barre pour les entreprises se situe généralement à 40-60%. Un histogramme présentant la répartition des scores sur un
Read 6 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us on Twitter!

:(