Créer un nuage de tags avec Lucene

Dans cet article, je présente une solution afin de générer un nuage de tags (ou nuage de mots clefs) à partir d’un flux de données textuelles. Pour l’exemple, il s’agit de titres d’articles stockés dans un fichier texte.

Le but est d’afficher les mots ou expressions de 2 ou 3 termes les plus fréquents dans les titres. Tous les termes ou expressions ne sont pas à conserver dans le nuage de tag. Une des étapes consiste en un filtrage selon des règles définies dans fichiers de règles : suppression des mots vides (je, le, pour, …), suppression des expressions commençant ou se terminant par un mot vide (”ne mange”, “termes les”, …), suppression des nombres, …

Les étapes nécessaires à la mise en œuvre de cette solution sont :

  • Etape 1 : indexation des titres dans Lucene
  • Etape 2 : extraction des termes ou expressions de l’index
  • Etape 3 : filtrage des termes ou expressions
  • Etape 4 : affichage du nuage en PHP

Les 3 premières étapes sont réalisées en java avec Lucene et donne comme résultat un fichier de termes ou expressions retenues dans le nuage de tags avec leur fréquence d’apparition.

La 4ème étape est réalisée en PHP et exploite le fichier résultat des étapes précédentes afin de mettre en forme le nuage de tags.

Pourquoi utiliser Lucene (étapes 1 et 2) ?

La génération du nuage de tags nécessite 2 étapes que Lucene est à même de réaliser : analyser et découper le texte servant à générer le nuage de tags et indiquer la fréquence d’apparition de chaque mot ou expression.

Lucene utilise des analyzers afin d’indexer le texte. Ces analyzers ont pour rôle principal de découper le texte en « token ». Selon les analyzers utilisés les tokens sont séparés par des espaces, des ponctuations, des caractères spéciaux (#, @, …), des chiffres, …

Par exemple, pour la phrase suivante : « Parcours du Tour de France », les tokens seraient sans doute : « parcours », « du », « tour », « de » et « France ».

Dans notre nuage de tags, nous ne voulons pas uniquement des mots simples, mais également des expressions de 2 ou 3 mots. Il nous faut donc extraire toutes les combinaisons possibles de tokens de 1, 2 ou 3 mots, c’est-à-dire : « parcours », « du », « tour », « de », « France », « parcours du », « du tour », « tour de », « de France », « parcours du tour », « du tour de » et « tour de France »

Un analyzer permettant de faire cela est disponible non pas dans la distribution standard de Lucene, mais à l’adresse suivante : http://issues.apache.org/jira/browse/LUCENE-400. Inutile de récupérer cet analyzer, j’en fournie les sources modifiés afin de fonctionner avec Lucene 2.3.2

Pour une présentation plus complète de Lucene, voir mon article « Introduction à Lucene« .

Pourquoi filtrer les termes ou expressions (étape 3) ?

Dans l’exemple indiqué ci-dessus, les termes ou expressions obtenues sont : « parcours », « du », « tour », « de », « France », « parcours du », « du tour », « tour de », « de France », « parcours du tour », « du tour de » et « tour de France ». On remarque immédiatement des éléments que l’on ne souhaite pas voir apparaître dans le nuage : « du », « de », « parcours du », « du tour », « tour de », « de France » et « du tour de ». Il s’agit des mots-vides ou expression commençant ou se terminant par un mot-vide. Il reste donc les éléments suivants : « parcours », « France », « parcours du tour » et « tour de France ».

Nous pousserons le nettoyage jusqu’à supprimer les mots simples ou expressions apparaissants dans une expression constituée de plus de mots. En effet, imaginons des données à analyser contenant une ou plusieurs fois les expressions suivantes : « tour de France », « tour d’Italie » et « tour d’Espagne », mais jamais ou peu de fois les mots « tour », « France », « Italie » et « Espagne » hors de ces expressions. Sans ce nettoyage, le nuage de tags contiendrait certainement « tour », « Italie », « France » et « Espagne » (très fréquents) et sans doute mais sans certitude « tour de France », « tour d’Italie » et « tour d’Espagne » (moins fréquents). Le nuage de tags serait alors complètement faux.

Ainsi nettoyé, le nuage devient « parcours du tour » et « tour de France » et est beaucoup plus pertinent que ce que nous avions obtenu avant le filtrage.

L’algorithme de nettoyage utilisant un fichier de règles est adapté de l’algorithme décrit dans l’article « Lucene Tag Cloud Generator » de Richard Friedman.

Le fichier de règles est principalement constituer de la liste des mots vides mais commence par 5 paramètres pouvant être désactivés (en mettant les lignes en commentaires avec un #). Il s’agit de :

  • -smallwords : pour retirer les mots de 3 caractères ou moins
  • -numbers : pour retirer les nombres
  • -dashes : pour retirer les mots contenant un tiret (« – »)
  • -period : pour retirer les mots contenant un point
  • -include : pour retirer les mots ou expressions incluent dans une autre expression. J’ai mis cette option pour le principe, mais en la désactivant les résultats sont généralement très décevants.

Code source des étapes 1, 2 et 3

Le code source java est disponible ici sous forme d’un projet Eclipse. Il contient les fichiers suivants :

  • NGramAnalyzerWrapper.java et NGramFilter.java (analyzer Lucene)
  • TagCloud.java (classe principale avec l’algorithme de filtrage)
  • input.txt (les données exemples à analyser)
  • rules.txt (le fichier de règles)

Pour lancer l’analyse d’un fichier de données, l’usage est le suivant :

Etape 4 : affichage du nuage en PHP

La mise en forme du nuage de tags utilise le fichier généré par le programme précédent. Une classe PHP réalise cette mise en forme (lecture du fichier et génération du code html) et une feuille de style définie les styles d’affichage.

La classe PHP est une adaptation du code proposé dans l’article « Tagcloud Font Distributor« .

Le code source disponible ici est constitué des fichiers suivants :

  • cloud_tag.inc.php : la classe de génération du nuage de tags en html
  • tagcloud.css : la feuille de styles pour l’affichage de nuage de tags
  • cloud_tag_display.php : un script d’exemple utilisant la classe et la feuille de styles.

Résultats

Voici quelques exemples de résultats obtenus à partir du fichier de données exemple et en faisant varier quelques paramètres.

Exemple 1 : paramètres par défaut

Exemple 2 : paramètres par défaut sauf boost = 3

On remarque un plus grand nombre d’expressions de plus de 1 mot

Exemple 3 : paramètres par défaut sauf maxterm = 5 et boost = 5

On remarque des expressions jusqu’à 5 mots et presque plus de mots seuls

Stratégies de mise à jour du nuage de tags

La stratégie de mise à jour du nuage de tags dépend de plusieurs paramètres :

  • type de données (presse, forums, …)
  • la fréquence de mise à jour des données (chaque seconde, une fois par heure, une fois par jour, …)
  • le dynamisme que l’on veut donner au nuage

Par exemple, pour des données peu changeantes et en faible quantité, on peut choisir de créer le nuage sur les données des 30 derniers jours avec régénération du nuage une fois par jour. Par contre, pour des données très changeantes comme un site de presse avec des données nouvelles toutes les secondes, on peut choisir de générer le nuage sur les données de la dernière journée voir des dernières heures avec régénération du nuage chaque heure voir chaque quart d’heure.

Conclusions

Je pense que des règles de filtrage basées sur des expressions régulières pourraient être ajoutées. Par exemple, une simple règle indiquant de ne pas accepter les mots avec des points ou des tirets remplacerait les règles « -dashes » et « -period », une autre remplacerait « -number ». On pourrait mettre en place un grand nombre de règles supplémentaires comme par exemple le rejet des dates.

Je suis ouvert à toutes suggestions afin d’améliorer de la solution proposée.

One Response

  1. aris78 19 février 2011

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *