Le stemming en NLP: définition, techniques et enjeux
Qu'est ce que le stemming?
Le
stemming est une technique fondamentale en traitement automatique du langage naturel. Il consiste à réduire les mots à leur racine, appelée stem, en supprimant les suffixes et parfois les préfixes.
L’idée du stemming est de regrouper les différentes formes fléchies ou dérivées d’un mot sous une même base commune. Par exemple, les mots
manger,
mangeait et
mangerons seront ramenés à la racine
mang, tandis que
étudiant,
étudiants et
étudier deviendront
étudi. Cette approche ne cherche pas à produire un mot correct du point de vue linguistique, mais plutôt une forme simplifiée qui permet de traiter efficacement les textes.
L’intérêt du stemming est multiple, en l'occurrence:
- Il permet de réduire la variabilité lexicale en regroupant les variantes d’un même mot, ce qui diminue la taille du vocabulaire à analyser.
- Il améliore la recherche d’information : un moteurIde recherche peut ainsi retrouver un document contenant étudier même si l’utilisateur a tapé étudiants.
- Il optimise les calculs dans des modèles comme TF-IDF ou les algorithmes de clustering car les mots sont ramenés à une base commune qui reflète mieux les thèmes.
- Il offre un gain de performance, puisque moins de mots distincts signifie des index plus compacts et des calculs plus rapides.
Algorithmes de stemming: Porter, Snowball, Lancaster et Lovins
Plusieurs algorithmes de stemming ont été développés au fil du temps, les plus connus sont Porter Stemmer, Snowball Stemmer, Lancaster Stemmer et Lovins Stemmer.
Porter Stemmer
Le
Porter Stemmer, développé par
Martin Porter en 1980, est sans doute l’algorithme de stemming le plus célèbre et le plus utilisé dans les systèmes de traitement de texte. Sa conception repose sur un ensemble de règles heuristiques qui visent principalement à supprimer les suffixes courants en anglais afin de ramener les mots à une racine simplifiée.
L’approche de Porter Stemmer est séquentielle: l’algorithme applique successivement plusieurs étapes de transformation, chacune ciblant une catégorie de suffixes (par exemple -ing, -ed, -ly, etc.).
Ce qui fait la force du Porter Stemmer, c’est sa simplicité et sa rapidité. Il ne nécessite pas de dictionnaire linguistique complexe, mais uniquement un ensemble de règles bien définies. Cela le rend particulièrement adapté aux moteurs de recherche et aux systèmes d’indexation où la performance est cruciale.
Cependant, cette efficacité a un revers car le Porter Stemmer peut produire des racines tronquées qui ne correspondent pas à des mots réels et qui peuvent sembler peu lisibles. Par exemple,
relational devient
relat et
conditional devient
condit. Ces formes ne sont pas des lemmes corrects, mais elles suffisent pour un usage statistique ou pour améliorer la pertinence des recherches.
Snowball Stemmer
Le
Snowball Stemmer, également connu sous le nom de
Porter2, est une évolution directe du Porter Stemmer original. Conçu pour pallier certaines limites de son prédécesseur, il introduit une syntaxe plus claire et une architecture plus flexible, ce qui facilite son implémentation et son adaptation à différentes langues.
Contrairement au Porter Stemmer, qui était initialement centré sur l’anglais, Snowball a été pensé comme un cadre multilingu. En effet, il prend en charge plusieurs langues européennes, dont le français, l’allemand, l’espagnol et l’italien. Cette ouverture linguistique le rend particulièrement utile dans des contextes internationaux ou dans des corpus multilingues.
L’un des points forts du Snowball Stemmer est sa précision accrue. Là où Porter pouvait produire des racines tronquées peu lisibles, Snowball applique des règles plus raffinées qui tendent à générer des formes plus cohérentes. Par exemple, en anglais, les mots
running,
runner et
runs sont ramenés à run, ce qui est plus intuitif que la racine tronquée que pourrait produire Porter.
Lancaster Stemmer
Le
Lancaster Stemmer est un algorithme de stemming réputé pour son caractère particulièrement agressif. Contrairement au Porter ou au Snowball, qui appliquent des règles plus progressives et cherchent à préserver une certaine lisibilité des racines, Lancaster réduit les mots de manière beaucoup plus radicale.
Lancaster Stemmer repose sur un ensemble de règles de suppression de suffixes très étendu, et applique ces règles de façon itérative jusqu’à ce qu’aucune transformation supplémentaire ne soit possible. Cette approche permet de réduire fortement la taille du vocabulaire, ce qui est un avantage majeur dans des contextes où l’efficacité et la compacité des données priment sur la précision linguistique.
Par exemple, les mots
maximum,
maximal et
maximize sont tous ramenés à la racine
maxim, ce qui permet de les traiter comme une seule entité dans un corpus.
Lovins Stemmer
L’un des premiers algorithmes de stemming est le
Lovins Stemmer, développé en 1968 par
Julie Beth Lovins. Son principe repose sur une vaste liste de suffixes prédéfinis: l’algorithme identifie le suffixe le plus long présent dans un mot, le supprime, puis applique quelques règles de normalisation pour obtenir une racine commune. Par exemple:
national,
nationalism,
nationally deviennent
nation.
Bien qu’innovant et fondateur, le Lovins Stemmer est aujourd’hui peu utilisé, car ses résultats sont parfois incohérents et moins performants que ceux des algorithmes plus modernes comme Porter, Snowball ou Lancaster. Il reste néanmoins une référence historique incontournable dans l’évolution des techniques de réduction lexicale.
Application pratique du stemming
Méthodes d’application des algorithmes de stemming: Porter, Snowball et Lancaster
Dans cet exemple, nous allons appliquer le stemming sur le même texte en utilisant les algorithmes Porter, Snowball et Lancaster:
from nltk.stem import PorterStemmer, SnowballStemmer, LancasterStemmer
porter_stemmer = PorterStemmer()
snowball_stemmer = SnowballStemmer(language="english")
lancaster_stemmer = LancasterStemmer()
texte = "Happiness is not something ready made. It comes from your own actions."
tokens = word_tokenize(texte)
print("Porter:",[porter_stemmer.stem(token) for token in tokens])
print("Snowball:",[snowball_stemmer.stem(token) for token in tokens])
print("Lancaster:",[lancaster_stemmer.stem(token) for token in tokens])
Avant toute opération de stemming, il est indispensable de procéder à la tokenisation afin de segmenter le texte en unités lexicales. Quant à l’importation et à l’utilisation des bibliothèques nécessaires, je pars du principe que ces étapes vous sont déjà familières.
L'exécution du code précédent produit ce résultat:
Porter: ['happi', 'is', 'not', 'someth', 'readi', 'made', '.', 'it', 'come', 'from', 'your', 'own', 'action', '.']
Snowball: ['happi', 'is', 'not', 'someth', 'readi', 'made', '.', 'it', 'come', 'from', 'your', 'own', 'action', '.']
Lancaster: ['happy', 'is', 'not', 'someth', 'ready', 'mad', '.', 'it', 'com', 'from', 'yo', 'own', 'act', '.']
Dans cet exemple, on observe que Porter et Snowball produisent des résultats identiques. En effet, ils tronquent les mots (
happiness →
happi,
ready →
readi,
comes →
come) tout en gardant des racines relativement cohérentes pour un usage statistique.
En revanche, Lancaster se montre beaucoup plus agressif car il réduit fortement les mots (
made →
mad,
comes →
com,
your →
yo), ce qui diminue la taille du vocabulaire mais entraîne une perte de lisibilité et parfois de sens.
En résumé, Porter et Snowball privilégient un compromis entre rapidité et lisibilité, tandis que Lancaster vise une réduction maximale au détriment de la clarté.