BAO 3

Extraction de patrons morpho-syntaxiques et de relations de dépendance

Maintenant qu’on a nos contenus étiquetés, on souhaite les étudier. L’objectif de la BAO3 est d’extraire des patrons morpho-syntaxiques et des relations de dépendance. Pour cela, on va de nouveau utiliser des scripts en Perl et en Python, mais également des feuilles de styles XSLT et des requêtes XQuery. Ces deux dernières méthodes nécessitant un fichier d’entrée au format XML, on utilise le programme Perl fourni par nos professeurs pour convertir la sortie UDpipe au format XML. La sortie TreeTagger ne sera utilisée que pour les patrons mopho-syntaxiques car elle n’annote pas les relations de dépendance.

Voici les sorties UDPipe converties au format XML : Culture, Idées. Celles de TeeTagger sont disponibles dans la BAO2.

PROGRAMMES

PATRONS MORPHO-SYNTAXIQUES

LangageCommande de lancement dans le terminalProgramme commentéRésultat
Perl (TreeTagger) perl bao3-patron-TT.pl bao2_TT_pl_3246.xml NOM PRP NOM bao3-patron-TT.pl extraction-TT-patron_pl.txt
Python (TreeTagger) python3 bao3-patron-TT.py bao2_TT_py_3246.xml NOM PRP NOM bao3-patron-TT.py extraction-TT-patron_py.txt
Python avec utilisation de buffers (TreeTagger) python3 bao3-patron-TT-buffer.py bao2_TT_py_3246.xml NOM PRP NOM bao3-patron-TT-buffer.py extraction-TT-patron_py.txt
Perl (UDpipe) perl bao3-patron-UD.pl bao2_UD_pl_3246.udpipe.xml NOUN ADP NOUN bao3-patron-UD.pl extraction-UD-patron_pl.txt
Python (UDpipe) python3 bao3-patron-UD.py bao2_UD_py_3246.udpipe.xml NOUN ADP NOUN bao3-patron-UD.py extraction-UD-patron_py.txt
XSLT (TreeTagger) xsltproc NOM-PRP-NOM-TT.xsl bao2_TT_pl_3246.xml NOM-PRP-NOM-TT.xsl NOM-PRP-NOM-TT_xsl.txt
XQuery (TreeTagger) Utilisation de BaseX NOM-PRP-NOM-TT.xqy NOM-PRP-NOM-TT_xqy.txt

RELATIONS DE DEPENDANCES

LangageCommande de lancement dans le terminalProgramme commentéRésultat
Perl (UDpipe) perl bao3-relation-UD.pl bao2_UD_pl_3246.udpipe.xml obj bao3-relation-UD.pl extraction-UD-relation_pl_obj.txt
Python (UDpipe) python3 bao3-relation-UD.py bao2_UD_py_3246.udpipe.xml obj bao3-relation-UD.py extraction-UD-relation_py_obj.txt
XSLT (UDpipe) xsltproc rel-OBJ.xsl bao2_UD_pl_3246.xml rel-OBJ.xsl extraction-UD-obj_xsl.txt
XQuery (UDpipe) Utilisation de BaseX rel-OBJ.xqy extraction-UD-obj_xqy.txt

Programme PERL (patrons)

bao3-patron-TT.pl
bao3-patron-UD.pl

Ce programme prend en arguments le fichier XML étiqueté, et le patron à extraire. Après les avoir récupérés sous forme de variables, on peut lire le fichier ligne par ligne, en vidant la liste des lignes au fur et à mesure. Pour chaque ligne, on va chercher le premier élément du patron souhaité à l'aide des expressions régulières, et extraire le mot concerné dans la variable "terme". Lorsque ce premier élément a été trouvé, on peut alors chercher le deuxième élément dans la ligne suivante, et ainsi de suite jusqu'à la fin du patron. On se base donc sur la longueur du patron pour déterminer quand s'arrêter. Si le nombre de mots trouvés correspond à la longueur du patron, on peut alors ajouter le terme dans un dictionnaire regroupant tous les termes trouvés, qui va permettre de compter les occurences. Enfin, on ouvre un fichier TXT, dans lequel on va écrire le patron, le nombre d'éléments trouvés, ainsi que tous les termes extraits avec leurs occurences, triés dans l'ordre décroissant d'occurences.

Les version TreeTagger et UDpipe de ce programme sont identiques, la seule différence se trouve dans les expressions régulières, qui prennent en compte la structure du fichier XML.

Programme PYTHON (patrons)

bao3-patron-TT.py
bao3-patron-UD.py

Ce programme prend en arguments le fichier XML étiqueté, et le patron à extraire. Après les avoir récupérés sous forme de variables, on crée une liste contenant les lignes du fichier. Tant que cette liste est plus longue que le patron, on reproduit le processus suivant : pour chaque élément du patron, on le cherche dans la ligne correspondante à l'aide des expressions régulières : la première ligne pour le premier élément, la deuxième ligne pour le deuxième élément, etc. Si l'élément est trouvé, on l'ajoute dans la variable "terme", et quand la longueur du terme est égale à la longueur du patron, on l'ajoute dans le dictionnaire. Si on ne trouve pas d'élément du patron, on s'arrête pour ne pas chercher la suite inutilement. Ensuite, on peut supprimer la première ligne de la liste, et on recommence avec la suivante. Une fois tous les termes correspondant au patrons extraits, on va trier le dictionnaire dans l'ordre décroissants des occurences, avant d'écrire dans un fichier TXT, le patron, le nombre total d'éléments trouvés, ainsi que les termes avec leurs occurences.

Les version TreeTagger et UDpipe de ce programme sont identiques, la seule différence se trouve dans les expressions régulières, qui prennent en compte la structure du fichier XML.

Programme PYTHON avec buffers (patrons)

bao3-patron-TT-buffer.py

Ce programme prend en arguments le fichier XML étiqueté, et le patron à extraire. Après les avoir récupérés sous forme de variables, on crée un buffer, qui va contenir la forme et le tag de chaque élément trouvé du patron. On peut ensuite lire le fichier ligne par ligne. Pour chaque ligne, on commence par supprimer la premier élément du buffer, avant de chercher le premier élément du patron dans la ligne à l'aide des expressions régulières. Si on le trouve, on récupère le tag et la forme dans la ligne, et on les ajoute à la fin du buffer. S'il n'a pas été trouvé, on remet le buffer à zéro, prêt à contenir un nouveau terme. Ensuite, pour chaque élément du patron, si l'élément correspond au tag de l'élément du même indice dans le buffer, on récupère le terme, sinon on sort de la boucle. La variable booléenne "ok" reste vraie si tous les éléments correspondent. Dans ce cas, on peut ajouter le terme final au dictionnaire. Enfin, une fois ce processus terminé avec toutes les lignes du fichier, on va trier le dictionnaire dans l'ordre décroissants des occurences, avant d'écrire dans un fichier TXT, le patron, le nombre total d'éléments trouvés, ainsi que les termes avec leurs occurences.

XSLT (patrons)

NOM-PRP-NOM-TT.xsl

Cette feuille de style XSLT doit être associée au fichier XML étiqueté. Elle extrait le patron NOM PRP NOM, mais peut facilement être adaptée pour d'autres patrons. On cherche tous les noeuds "élément", qui correspondent à des lignes contenant les informations de chaque mot. Pour chaque élément, on va chercher si son premier noeud "data" (qui correspond au POS) contient "NOM", si ce même noeud de l'élément suivant contient "PRP", et si le noeud du deuxième élément suivant contient "NOM". Si ces trois conditions sont remplies, alors on va récupérer la valeur du troisième noeud "data" de chacun de ces trois éléments, qui correspond à la forme du mot. On les formate en les séparant par des espaces et en ajoutant un saut de ligne à la fin. Si on veut trouver un patron différent, il suffit de modifier la condition, et le nombre de valeurs récupérées en fonction de la longueur du patron.

XQuery (patrons)

NOM-PRP-NOM-TT.xqy

Cette requête XQuery doit être utilisée dans un environnement comapatible, par exemple sur le logiciel BaseX. Elle extrait le patron NOM PRP NOM, mais peut facilement être adaptée pour d'autres patrons. Pour chaque noeud "élément", on commence pas créer des variables "frere1" et "frere2", qui vont permettre de retrouver facilement les deux éléments suivants. Si le premier noeud "data" de l'élément sur lequel on est contient "NOM", celui de l'élément suivant contient "PRP", et celui du deuxième élément suivant contient "NOM", alors on récupère la valeur du troisième noeud "data" de chacun de ces trois éléments, qui correspond à la forme du mot. Si on veut trouver un patron différent, il suffit de modifier la condition, et le nombre de valeurs récupérées en fonction de la longueur du patron.

Programme PERL (relations)

bao3-relation-UD.pl

Ce programme prend en arguments le fichier XML étiqueté, et la relation à extraire. Après les avoir récupérés sous forme de variables, on peut lire le fichier phrase par phrase, en définissant la balise p comme délimiteur. On va ensuite séparer chaque phrase en mots en séparant le texte sur les sauts de ligne, puisque chaque ligne correspond à l'annotation d'un mot. Ainsi, pour chaque mot appartenant à une même phrase, on va chercher la relation souhaitée à l'aide des expressions régulières. Le mot sur lequel se trouve la relation est le dépendant. On a besoin de trouver le gouverneur pour avoir la relation entière. On récupère donc la position du dépendant et sa forme, mais aussi la position du gouverneur, qui est écrite avec la relation. Si la position du gouverneur est inférieure à celle du dépendant, cela signifie qu'il se trouve avant. On cherche donc, toujours avec les expressions réguières, la ligne correspondant à cette position parmi les mots composant la phrase avant le dépendant, et on récupère sa forme, qu'on ajoute avec celle du dépendant dans le dictionnaire. Si la position du gouverneur est supérieure à celle du dépendant, on faire de même en cherchant parmi les mots de la phrase se trouvant après. On va ensuite trier le dictionnaire par ordre d'occurences et écrire chaque relation et sa fréquence dans un fichier TXT.

Programme PYTHON (relations)

bao3-relation-UD.py

Ce programme prend en arguments le fichier XML étiqueté, et la relation à extraire. Après les avoir récupérés sous forme de variables, on commence par instancier deux buffers, qui vont servir à stocker, pour le premier, tous les mots et leur position d'une même phrase, et pour le deuxième, la forme du dépendant et la position du gouverneur de la relation. Pour chaque ligne dans le fichier, si la ligne correspond à un noeud "item", on cherche avec les expressions régulières tous les noeuds "a", et on récupère leur contenu dans la variable "fields", à partir de laquelle on va extraire la position et la forme du mot, qu'on va mettre dans le premier buffer sous forme de dictionnaire. On extrait également la relation, et si elle correspond à celle qu'on souhaite extraire, alors on ajoute la forme du dépendant et la position du gouverneur dans le deuxième buffer. Enfin, si la ligne lue correspond à la fin d'une phrase, on récupère la forme du gouverneur à l'aide de sa position dans le premier buffer, et on ajoute les formes du dépendant et du gouverneur dans le dictionnaire. On remet ensuite les deux buffers à zéro, pour recommencer avec la phrase suivante. Une fois toutes les relations trouvées, on trie le dictionnaire par ordre d'occurences, et on écrit chaque relation et sa fréquence dans un fichier TXT.

XSLT (relations)

rel-OBJ.xsl

Cette feuille de style XSLT doit être associée au fichier XML étiqueté. Elle extrait la relation OBJ, mais peut facilement être adaptée pour d'autres patrons. Pour chaque noeud "p", qui correspond à une phrase, on cherche les noeuds "item", qui contiennent les informations de chaque mot. Pour chaque item, on va chercher si son 8ème noeud "a" (qui correspond aux relations de dépendance) contient "obj". Si c'est le cas, alors on va récupérer les positions du dépendant et du gouverneur, respectivement dans le premier et le 7ème noeud "a". Si la position du gouverneur est inférieure à celle du dépendant, sur lequel on se trouve, on va chercher la forme de l'élément qui se trouve à cette position parmi les frères précédents, puis celle du dépendant, et on les affiche dans l'ordre. Dans le cas contraire, on fait de même en cherchant le gouverneur parmi les éléments frères suivants, et on les affiche dans l'autre sens. Si on veut trouver une relation différente, il suffit de modifier le nom de la relation dans la condition.

XQuery (relations)

rel-OBJ.xqy

Cette requête XQuery doit être utilisée dans un environnement comapatible, par exemple sur le logiciel BaseX. Elle extrait la relation OBJ, mais peut facilement être adaptée pour d'autres patrons. Pour chaque noeud "item" dont le 8ème noeud "a" contient "obj", on crée des variables qui contiennent la forme du dépendant, sa position, et la position de gouverneur, récupérées dans les noeuds "a" correspondants. Si la position du gouverneur est inférieure à celle du dépendant, sur lequel on se trouve, on va chercher la forme de l'élément qui se trouve à cette position parmi les frères précédents. Dans le cas contraire, on fait de même en cherchant le gouverneur parmi les éléments frères suivants. Une fois la forme du gouverneur récupérée, on peut les afficher, en groupant le résultat par relation et en comptant chaque occurence. Si on veut trouver une relation différente, il suffit de modifier le nom de la relation dans la condition.

RESULTATS

Voici les résultats obtenus pour les rubriques Culture et Idées, via les scripts Perl.

Rubrique Culture (3246)

Patron / relationFormat d'annotationRésultat
NOM ADJ TreeTagger 3246-TT-NOM-ADJ.txt
NOUN ADJ UDpipe 3246-UD-NOUN-ADJ.txt
ADJ NOM TreeTagger 3246-TT-ADJ-NOM.txt
ADJ NOUN UDpipe 3246-UD-ADJ-NOUN.txt
VER DET NOM TreeTagger 3246-TT-VER-DET-NOMtxt
VERB DET NOUN UDpipe 3246-UD-VERB-DET-NOUN.txt
NOM PRP NOM PRP TreeTagger 3246-TT-NOM-PRP-NOM-PRP.txt
NOUN ADP NOUN ADP UDpipe 3246-UD-NOUN-ADP-NOUN-ADP.txt
NOM PRP NOM TreeTagger 3246-TT-NOM-PRP-NOM.txt
NOUN ADP NOUN UDpipe 3246-UD-NOUN-ADP-NOUN.txt
PRO VER ADV TreeTagger 3246-TT-PRO-VER-ADV.txt
PRON VERB ADV UDpipe 3246-UD-PRON-VERB-ADV.txt
OBJ UDpipe 3246-UD-OBJ.txt
SUBJ UDpipe 3246-UD-SUBJ.txt

Rubrique Idées (3232)

Patron / relationFormat d'annotationRésultat
NOM ADJ TreeTagger 3232-TT-NOM-ADJ.txt
NOUN ADJ UDpipe 3232-UD-NOUN-ADJ.txt
ADJ NOM TreeTagger 3232-TT-ADJ-NOM.txt
ADJ NOUN UDpipe 3232-UD-ADJ-NOUN.txt
VER DET NOM TreeTagger 3232-TT-VER-DET-NOMtxt
VERB DET NOUN UDpipe 3232-UD-VERB-DET-NOUN.txt
NOM PRP NOM PRP TreeTagger 3232-TT-NOM-PRP-NOM-PRP.txt
NOUN ADP NOUN ADP UDpipe 3232-UD-NOUN-ADP-NOUN-ADP.txt
NOM PRP NOM TreeTagger 3232-TT-NOM-PRP-NOM.txt
NOUN ADP NOUN UDpipe 3232-UD-NOUN-ADP-NOUN.txt
PRO VER ADV TreeTagger 3232-TT-PRO-VER-ADV.txt
PRON VERB ADV UDpipe 3232-UD-PRON-VERB-ADV.txt
OBJ UDpipe 3232-UD-OBJ.txt
SUBJ UDpipe 3232-UD-SUBJ.txt