Traitement automatique du langage : classification de texte efficace et loin de la hype des IA génératives

Ionut Mihalcea
MoveNext
Published in
6 min readFeb 18, 2024
Photo by Tomas Sobek on Unsplash

Une des tâches les plus courantes en traitement automatique du langage est la classification de texte. Son application se retrouve dans de nombreux domaines comme la détection de spam, la catégorisation de contenu, la détection de la polarité, la détection des entités nommées, etc.

Dans nos travaux de veille et R&D nous cherchons à trouver les algorithmes les plus efficaces pour la classification de texte afin de pouvoir garantir à nos clients des résultats de qualité avec un coût de traitement le plus faible possible.

Le papier de recherche “Low-Resource Text Classification: A Parameter-Free Classification Method with Compressors” de l’Université de Waterloo, publié en Juillet 2023, a particulièrement attiré notre attention car il fait un pas de coté par rapport à la tendance actuelle qui privilégie l’utilisation de réseaux de neurones profonds pour la classification de texte.

Les réseaux de neurones sont très efficaces mais ils ont un coût de traitement très élevé. De plus, dans leur mise en œuvre il est souvent nécessaire d’avoir des jeux de données très volumineux pour obtenir des résultats de qualité.

Comme alternative, les auteurs de ce papier proposent une méthode basée sur un compresseur de type gZip couplé à un algorithme de classification de type k-NN (k plus proches voisins en français). Leur méthode est très efficace et a l’avantage de ne pas nécessiter de paramétrage. Elle est donc très facile à mettre en œuvre et très peu coûteuse en ressources de calcul.

Que vient faire gZip dans la classification de texte ?

Un algorithme de compression comme gZip est capable d’encoder l’information afin de réduire sa taille en éliminant les redondances. La compression est faite de façon à permettre de retrouver le texte original à partir du texte compressé. Nous parlons de compression sans perte.

D’un autre côté, un réseau de neurones spécialisé dans le langage (un LLM si vous préférez) fait de l’encodage également mais dans le but de capturer les informations linguistiques importantes. Évidemment, le but n’est pas de retrouver le texte original mais de pouvoir faire des prédictions.

Alors, vous vous demandez sûrement comment un compresseur ne capturant pas les informations linguistiques peut faire mieux qu’un réseau de neurones spécialisé dans le langage pour la classification ?

Pur hasard, ou il existe une explication rationnelle ?

Effectivement la théorie de l’information de Claude Shannon et son article “A Mathematical Theory of Communication” publié en 1948 donnent une explication rationnelle de ce phénomène. La théorie de l’information suggère que la similarité entre deux objets peut être déterminée en observant dans quelle mesure un objet peut être compressé lorsque les informations de l’autre objet sont disponibles.

Je vous ai perdu ? Pas de panique !

La mesure de similarité basée sur la compression s’appelle “Normalized Compression Distance (NCD)” et elle compare la taille des objets compressés séparément à la taille de leur compression conjointe.

Lorsque vous essayez de compresser deux objets ensemble, si ces objets sont très similaires, l’information contenue dans le premier objet peut être utilisée pour aider à compresser le second objet, réduisant ainsi la quantité d’information additionnelle nécessaire pour coder le second objet après le premier. Cela se traduit par une taille de l’information combinée qui n’est pas beaucoup plus grande que la taille de l’information la plus grande compressée seule, indiquant une forte similarité.

Inversement, si les deux objets sont très différents, peu d’informations peuvent être partagées entre eux pour aider à la compression. Dans ce cas, la taille de l’information combinée sera presque égale à la somme des tailles des deux informations compressées séparément, indiquant une faible similarité.

Avec un peu de maths ce sera encore plus clair. La fonction NCD est définie comme suit :

Normalized Compression Distance

Où :

  • C(x1) et C(x2) sont les tailles des compressions respectives de x1 et x2
  • C(x1x2) est la taille de la compression pour la concaténation de x1 et x2

L’idée de NCD vient de la complexité de Kolmogorov K(x) qui est la longueur du programme le plus court qui génère x. K(x) est théoriquement la mesure ultime de la complexité et donc de l’information de x.

Afin d’établir une distance entre l’information de deux objets, on peut utiliser E(x1, x2) comme la longueur du programme le plus court qui convertit x1 en x2.

Distance entre l’information de deux objets

K(x) est non calculable à cause du problème d’arrêt de Turing et par conséquent E(x1, x2) aussi. L’idée brillantissime réside dans l’utilisation de la compression pour approximer K(x).

L’Algorithme de classification

import gzip
from typing import List, Tuple

def ncd(x1:str, x2:str) -> float:
cx1 = len(gzip.compress(x1.encode()))
cx2 = len(gzip.compress(x2.encode()))
cx1x2 = len(gzip.compress(" ".join([x1, x2]).encode()))
return (cx1x2 - min(cx1, cx2)) / max(cx1, cx2)

def knn_classify(to_predict:str, reference_set:List[Tuple[str, str]], k:int=4) -> str:
distances = [(label, ncd(to_predict, text)) for (text, label) in reference_set]
distances.sort(key=lambda x: x[1])
top_classes = [x[0] for x in distances[:k]]
return max(set(top_classes), key=top_classes.count)

Imaginons que nous devons classifier des articles de blog dans certaines catégories : nous avons besoin d’un jeu de données de référence contenant des articles de blog existants et leur catégorie respective. Pour tout nouvel article de blog nous devons prédire automatiquement laquelle des catégories existantes lui correspond le mieux.

La fonction `ncd` calcule la distance de compression normalisée entre deux textes. La fonction `knn_classify` utilise la distance de compression normalisée pour trouver les k textes de référence les plus proches du texte à classifier et retourne la classe majoritaire parmi ces k textes de référence.

Testons notre algorithme sur un jeu de données de classification de texte.

import pandas as pd

reference_data_set = [
("Tips and Tricks to Organize Jupyter Notebook Data Visualizations", "DataViz"),
("The Best Data Visualization Tools", "DataViz"),
("Data Visualization with Python and Seaborn", "DataViz"),
("How To Create A Product Roadmap", "Product Management"),
("The Best Product Management Tools", "Product Management"),
("Product Management with Trello", "Product Management"),
("Escaping the Python Dependency Hell", "Python"),
("The Best Python IDEs and Code Editors", "Python"),
("I love traveling to Italy in summer", "Travel"),
("The Top Travel Blogs for your next summer trips", "Travel"),
("Le voyage de rêve en Scandinavie", "Travel"),

]

test_data_set = [
"Choosing the Right Data Visualization Tools",
"Visualizing Data with Python and Plotly",
"Great Project Roadmap techniques from the world's top Product Managers",
"Traveling to Japan: Trips and Tricks",
"Du rêve à la réalité: le voyage dans les Balkans",
]

predictions = [(to_predict,knn_classify(to_predict, reference_data_set)) for to_predict in test_data_set]
df = pd.DataFrame(predictions, columns=["Text", "Prediction"])
df

Nous observons que notre algorithme a bien classifié les textes du jeu de test. Évidemment, ce n’est qu’un exemple très simple mais l’étude démontre que sur des jeux de données de référence plus conséquents, l’algorithme est très efficace voire meilleur que certains modèles de langage.

Une autre propriété intéressante est le côté multi-langue de l’algorithme, et ce par construction, en se basant uniquement sur la redondance de l’information.

Conclusion

La complexité de l’algorithme est O(n.m) où `n` représente la taille des textes à classifier et `m` la taille du jeu de données de référence. Avec des jeux de données volumineux des problèmes de performances peuvent se poser.

Comme nous l’avons dit plus haut les compresseurs ne capturent pas des informations sémantiques ce qui implique que l’algorithme ne sera pas efficace si une compréhension fine est nécessaire. Nous avons eu à traiter ce cas par le passé dans le domaine médical et nous avons dû utiliser des modèles de langage pour arriver à nos fins.

Vous l’aurez compris, cet algorithme fonctionne sous certaines conditions et n’a pas vocation à remplacer les modèles de langage.

Malgré les limitations nous aimons beaucoup cette approche car elle met bien en évidence un des problèmes majeurs dans les projets d’intelligence artificielle : le choix de l’algorithme. Il est souvent tentant de choisir des modèles de langage car ils sont à la mode mais il est important de bien comprendre les besoins du projet et les données pour choisir l’algorithme le plus adapté, qui va conduire le plus rapidement au retour sur investissement.

--

--