DOCUMENT STRUTURÉ ET PROJET ENCADRÉ
Solveig P. - Malik M.
2019/2020 - S2
ACCUEIL
index.xml
faux
EX.1
ex1.xml
Structurer l'information: vers une grammaire de documents
faux
EX.2
ex2.xml
DTD
faux
EX.3
ex3.xml
TEI
faux
EX.13
ex13.xml
Extraction dans les fils RSS du Monde
faux
EX.14
ex14.xml
Patrons morphosyntaxiques
faux
EX.16
ex16.xml
Un dictionnaire
faux
Bào
bao.xml
Extraction du texte, étiquetage et recherche de patrons
vrai
Bào
Présentation générale
Le travail que nous vous présentons dans cette partie de notre site internet a été effectué sur l’ensemble des fils RSS 2019 du journal Le Monde et se divise en trois parties, correspondant chacune à une « boîte à outils », qui consiste en un script écrit en Perl dans le cadre du cours de Programmation et Projet Encadré 2.
L’objectif de la boîte à outils n°1 est de récupérer, par rubrique, l’ensemble des couples titre + description de notre corpus de fils RSS.
La boîte à outils n°2 ne diffère pas beaucoup de la première. En réalité, c’est le même script qu’on a un peu peaufiné et auquel on a ajouté une étape d’étiquetage morphosyntaxique et de lemmatisation du texte.
Le script de la boîte à outils n°3 permet quant à lui de rechercher et d’extraire des patterns (par exemple un nom suivi d’un adjectif) et d’en faire de jolis graphes que nous commenterons.
./images/toolbox3.jpg
BàO 1
Afin d’exploiter le contenu des fils RSS qui constituent notre corpus, la première étape est d’en extraire le texte. Avant d’entrer dans le vif du sujet, voici d’abord un petit rappel de ce qu’est un fil RSS, extrait du site « Comment ça marche », qui en fournit une définition que nous trouvons très claire :
"Le format « RSS » (traduisez « Really Simple Syndication ») permet de décrire de façon synthétique le contenu d'un site web, dans un fichier au format XML, afin de permettre son exploitation par des tiers. Le fichier RSS, appelé également flux RSS, canal RSS ou fil RSS, contenant les informations à diffuser, est maintenu à jour afin de constamment contenir les dernières informations à publier.
Basiquement, un fil RSS est un fichier contenant le titre de l'information, une courte description et un lien vers une page décrivant plus en détail l'information. Cela permet à un site web de diffuser largement ses actualités tout en récupérant un grand nombre de visiteurs grâce au lien hypertexte permettant au lecteur de lire la suite de l'actualité en ligne."
En ce qui nous concerne, nous souhaitons extraire le texte contenu dans les balises "title" et "description" de tous les fils de chaque rubrique et écrire le résultat dans deux fichiers, respectivement aux formats texte brut et XML. Pour cela, nous avons conçu un script en Perl, langage de programmation particulièrement adapté aux tâches de NLP.
Avant de rédiger ce script, il est important de connaître l’organisation de l’arborescence qui constitue notre corpus. Nous avons d’abord un répertoire par mois, puis pour chaque mois un répertoire par jour puis pour chaque jour un fichier par rubrique. Les rubriques sont au nombre de 16 et sont caractérisées par un code numérique qui donne son nom au fichier.
Notre script prend en entrée le dossier racine de l’arborescence et le code de la rubrique. Afin d’avoir les résultats des 16 rubriques, il faut donc le lancer à 16 reprises. Voici son fonctionnement :
On commence bien sûr par ouvrir les fichiers de sortie : un fichier texte et un fichier xml. Il faut écrire le prologue du fichier xml et la balise racine, puis on appelle la fonction parcoursarborescencefichiers qui prend en paramètre le nom du dossier que nous avions passé en paramètre du script, et enfin on ferme les fichiers de sortie.
L’essentiel du script se passe dans la fonction parcoursarborescencefichiers. Comme son nom l’indique, elle permet de parcourir l’arborescence à la recherche de fichiers. Cette fonction fait appel à un procédé récursif. En effet, pour chaque fils du dossier passé en paramètre, on réapplique cette même fonction s’il s’agit d’un autre dossier et on agit comme suit s’il s’agit d’un fichier.
Grâce à une expression régulière et une boucle, on récupère le contenu de chaque balise "title" et de chaque balise "description" qu’on stocke dans des variables. Afin d’éviter les doublons, on vérifie que chaque couple ‘titre + description’ n’est pas déjà présent dans un dictionnaire que l’on a initialisé avant l’appel de la fonction. S’il est déjà présent dans le dictionnaire, on ne le traite pas et passe au couple ‘titre + description’ suivant. Sinon on l’y ajoute, on lui applique la fonction nettoyage puis on écrit les résultats (titre et description nettoyés) dans les fichiers de sortie en prenant bien garde d’ajouter les balises dans le fichier XML.
La fonction nettoyage consiste tout simplement à remplacer, à l’aide d’expressions régulières, les entités XML par les caractères correspondants et à retirer d’autres chaînes de caractères qui relèvent de langage XML et non du texte.
C’est terminé pour la BàO 1, rendez-vous un peu plus bas pour la BàO 2 !
./images/toolbox2.jpg
./docs/BAO/bao1.zip
BàO 2
Bien que le script de la BàO 1 soit opérationnel, ce n’est pas celui dont nous nous sommes servis pour extraire les données textuelles du corpus. En effet, pour le travail qui suivra dans la BàO 3, nous avons besoin d’étiqueter les mots du texte avec leurs informations morphosyntaxiques. Il nous faut donc compléter le script et c’est l’objet de notre boîte à outils n° 2 !
Nous allons utiliser deux outils d’étiquetage morphosyntaxique : TreeTagger et Talismane. Il est important de préciser que Talismane est un outil écrit intégralement en Java. Il faut donc installer Java afin de pouvoir l’utiliser. Nous souhaitons conserver le fichier au format texte brut de la BàO 1 et en créer un second, étiqueté avec Talismane. Le fichier XML comprendra quant à lui les annotations TreeTagger. Cela nous fait donc trois fichiers de sortie : un fichier .txt non étiqueté, un fichier .xml étiqueté avec TreeTagger et un fichier .txt étiqueté avec Talismane.
Pour avoir ce résultat, il nous faut d’une part ajouter une seconde étape à la fonction parcoursarborescencefichiers pour l’annotation Talismane et d’autre part ajouter une fonction etiquetage pour l’annotation TreeTagger.
Pour chaque fichier traité par la fonction parcoursarborescencefichiers, on crée une nouvelle variable qui comprendra l’ensemble des couples ‘titre + description’ du fichier (on incrémente cette variable après chaque passage d’un couple à la fonction nettoyage, en concaténant le résultat avec le contenu de la variable elle-même). Lorsqu’on a terminé de traiter un fichier, on écrit le contenu de cette variable dans un fichier temporaire que l’on soumet à Talismane. On stocke ensuite le contenu du fichier généré par Talismane dans une variable, dont on écrit le contenu dans notre fichier .txt.
Pour Talismane comme pour TreeTagger, on utilise la fonction system de Perl qui permet de lancer une commande via la console de l’OS.
La fonction etiquetage prend en paramètre un titre et une description nettoyés. Il effectue la même opération sur le titre et la description : il commence par écrire le contenu de la variable dans un fichier temporaire puis, après avoir tokenisé ce fichier grâce à un script Perl tokenise-utf8.pl (fourni par nos professeurs et lancé grâce à la fonction system), le soumet à TreeTagger. On utilise un autre script Perl, treetagger2xml-utf8.pl (également fourni par nos professeurs et lancé grâce à la fonction system), pour convertir le fichier généré par TreeTagger en fichier XML. Le contenu de ce fichier, après avoir été débarrassé de son prologue XML, est stocké dans une variable qui est renvoyée par la fonction.
Voilà pour la BàO 2 ! Il ne reste plus qu’à lancer ce script sur chacune des 16 rubriques du Monde, afin de pouvoir appliquer la BàO 3 sur les fichiers obtenus.
./images/toolbox4.jpg
./docs/BAO/bao2.zip
BàO 3
Nous voici à la dernière étape du projet qui consiste à extraire des patterns dans les fichiers étiquetés que nous avons générés avec la BàO 2.
Les patterns recherchés sont au nombre de quatre :
NOM PREP NOM PREP
VERBE DET NOM
NOM ADJ
ADJ NOM
Trois méthodes sont possibles afin d’effectuer cette tâche : la première méthode consiste à extraire les patterns dans les fichiers .txt étiqueté avec Talismane via un script Perl. Les deux autres méthodes vont quant à elles exploiter des fichiers XML (soit ceux étiquetés avec TreeTagger que nous avons générés avec la BàO 2, soit les fichiers étiquetés avec Talismane qu’il faudra donc au préalable convertir au format XML). La seconde méthode fait appel à des feuilles de styles xslt et la troisième à des requêtes Xquery (effectuées sur le logiciel BaseX). Nous n’allons parler ici que de la première méthode, mais vous trouverez tous les détails des deux autres méthodes en cliquant sur l’onglet « EX.13 ».
Deux algorithmes nous ont été proposés afin d’extraire les patterns recherchés. Le premier consiste à construire pour chaque phrase une liste de listes, chaque « sous-liste » contenant une ligne du fichier étiqueté (chaque élément de la liste est donc toujours dans cet ordre : position du token dans la phrase, token, lemme, POS, etc.). On compare chaque POS (élément d’indice 3 de chaque sous-liste) avec le premier POS du pattern et, en cas de correspondance, on récupère les POS suivants (dont le nombre dépend de la taille du pattern), puis on compare la liste de POS obtenue au pattern complet. S’il y a correspondance, on récupère les tokens correspondants (éléments d’indice 1 de chaque sous-liste).
Le deuxième algorithme distribue quant à lui les étiquettes utiles (numéro du token, token, lemme, POS) dans des listes parallèles. On crée ensuite une liste de POS temporaire sur laquelle on applique en boucle jusqu’à la vider la fonction shift qui récupère le premier élément d’une liste tout en le supprimant de ladite liste, et on incrémente une variable qui permettra de retrouver le token correspondant dans la liste des tokens. Si le POS est le même que le premier POS d’un des patterns recherchés, on compare les POS suivants avec ceux qui suivent dans le pattern (en vérifiant bien qu’on ne change pas de phrase, grâce au numéro du token dans la phrase) : on incrémente une variable s’il y a correspondance. Ainsi, si la variable est égale à l’indice du dernier terme du pattern, c’est que le match est complet et on peut récupérer les tokens correspondants.
Nous avons utilisé le second algorithme. Le script prend en paramètre un fichier étiqueté par Talismane et un fichier contenant la liste des patterns recherchés.
./docs/BAO/bao3.zip
BàO 3 (bis)
Nous pouvons ensuite passer les fichiers obtenus en paramètre de l’exécutable patron2graphe.exe afin d’obtenir des graphes qui nous permettront de visualiser les résultats. On peut ajouter un motif (sous forme d’expression régulière) en paramètre de cet exécutable. En voici quelques exemples.
Rubrique cinéma, motif « film » :
./images/graphes/graphe_film.png
Ici, on a un graphe très dense (le mot « film » étant très général et omniprésent dans une rubrique cinéma). Les résultats sont cohérents avec une cooccurrence largement dominante des adjectifs « dernier », « nouveau » et « premier » (logiquement, la mention d’un film dans un journal est une critique d’un film qui vient de sortir donc nouveau, et c’est le dernier film de son réalisateur). Les autres cooccurrences sont très variées et donnent des précisions sur le genre du film ou des appréciations qualitatives.
Rubrique culture, motif « opéra » :
./images/graphes/graphe_opera.png
On constate que l’opéra n’est pas souvent mentionné par le Monde. En effet, malgré les efforts pour populariser cet art, il reste assez réservé à une minorité. On remarque cependant que l’opéra baroque a le vent en poupe (c’est le seul genre mentionné, pas d’opéra romantique, contemporain ou classique).
THE END
./images/taf.svg