Préparation BAO 3
Normalisation des POS des fichiers étiquetés avec TreeTagger
La première étape de notre BAO 3 est la préparation des données. En effet, nous avons noté des différences dans l'étiquetage fait par les deux outils.
Ici, le but est d'harmoniser les étiquettes données pour les POS. Pour cela, nous avons créé un script Perl qui nous permet de normaliser les étiquettes des fichiers de sortie de la BAO 2 étiquetés par TreeTagger avec les étiquettes données par UDpipe. La méthode des expressions régulières est utilisée.
Nous conservons donc les étiquettes données par UDpipe pour la suite de ce projet. Pour une question de lisibilité, nous travaillons uniquement avec les sorties produites par le script Perl lors de la BAO 2. Nous travaillons sur les fichiers produits par TreeTagger en XML, Udpipe en XML et UDpipe au format CoNLL.
Script pour normaliser les étiquettes TT :
Fichier |
Langage |
Téléchargement |
Normalisation POS TT vers POS UD |
Perl |
|
Résultats de cette normalisation :
Fichier |
Rubrique |
Téléchargement |
newPOS_TT_XML |
3208 |
|
newPOS_TT_XML |
3210 |
|
newPOS_TT_XML |
3246 |
|
newPOS_TT_XML |
3244 |
|
Extraction de patrons morpho-syntaxiques
Dans cette première partie, nous présentons trois méthodes pour effectuer une extraction de patrons morpho-syntaxiques. Un patron morpho-syntaxique est une série de POS observée dans les données. Les patrons morpho-syntaxiques nous permettront d'observer les données linguistiques sous un nouvel angle et en contexte afin de voir ce qui peut caractériser les différentes rubriques du point de vue linguistique.
Plusieurs méthodes ont été explorées pour cette première étape : Perl/Python, XSLT/XPath et XQuery.
Solution 1 : Perl / Python
Cette première solution met en oeuvre le principe des expressions régulières. Nous avons créé un script pour chaque type de fichier (TT XML, UD XML et UD CoNLL).
En entrée de chaque programme, nous retrouvons un texte étiqueté et lemmatisé par TreeTagger ou UDpipe et une liste de POS décrivant le patron comme "DET NOUN ADJ". En sortie de chaque programme, nous obtenons une liste au format TXT avec les formes des patrons trouvés. Le nom du fichier de résultats est adapté en fonction du patron demandé.
L'utilisation d'un dictionnaire en Perl et d'une liste en Python nous permet de compter les occurrences et de trier les résultats pour voir apparaître les termes les plus présents tout en haut du fichier. Nous avons également pris la décision de normaliser les formes trouvées en les passant toutes en minuscules. Ceci nous permet de regrouper des occurrences qui pourraient être identiques mais qui sont considérées différentes en raison des majuscules. La fonction ".lower()" est utilisée en Python et la fonction "lc()" est utilisée en Perl.
Puisque nous avons compté le nombre d'occurrences en Perl, nous avons créé une fonction Python nous permettant de faire la même chose. Pour cela, nous manipulons des listes afin de compter chaque élément. Nous associons donc un terme avec le comptage de sa présence dans le fichier. Puis nous créons une nouvelle liste pour y insérer les élements qui n'ont encore jamais été rencontrés (nous évitons ainsi les doublons). Nous retournons ensuite un résultat qui est la liste nouvellement créée et inversée pour permettre un affichage similaire à Perl.
Le fonctionnement global des deux programmes est le même : nous parcourons les données et si notre patron correspond aux données observées, nous pouvons extraire la forme. Nous commençons par vérifier la correspondance du premier POS du patron aux données pour éviter des calculs inutiles.
Le script Python présente une particularité : l'utilisation d'un buffer. En effet, nous ne lisons pas les données globalement. Le buffer est une fenêtre glissante qui va parcourir nos données et récupérer les formes correspondant au patron s'il y a correspondance. Nous lisons ainsi le fichier ligne par ligne.
Les sorties créées à partir des deux programmes sont donc similaires et le temps d'execution des programmes également. Cette méthode est jugée plus simple d'utilisation que les méthodes suivantes puisque nous pouvons demander n'importe quelle longueur de patron, les programmes s'adaptent. Comme nous le verrons, les feuilles de style et requêtes XQuery doivent être retravaillées pour correspondre à la longueur des patrons souhaités.
Scripts :
Fichier |
Langage |
Téléchargement |
TT xml |
Perl |
|
UD xml |
Perl |
|
UD CoNLL |
Perl |
|
TT xml |
Python |
|
UD xml |
Python |
|
UD CoNLL |
Python |
|
Résultats :
Fichier |
Sortie |
Rubrique |
Patron |
Téléchargement |
TT XML |
Perl |
3208 |
ADP DET NOUN |
|
UD XML |
Perl |
3208 |
ADP DET NOUN |
|
UD CoNLL |
Perl |
3210 |
NOUN ADP NOUN ADP |
|
UD XML |
Perl |
3210 |
VERB DET NOUN |
|
UD XML |
Perl |
3246 |
NOUN ADJ |
|
TT XML |
Python |
3244 |
ADJ NOUN |
|
UD XML |
Python |
3244 |
NOUN ADV ADJ |
|
Solution 2 : XSLT / XPATH
Cette deuxième solution met en oeuvre la méthode des feuilles de style avec XSLT et XPath. Nous traitons uniquement le patron "NOUN ADJ" dans cette partie, les feuilles de style pour d'autres patrons sont disponibles sur le site créé pour le projet de Documents Structurés. Nous travaillons sur les sorties de la BAO 2 qui sont au format XML uniquement puisque le langage XPath va nous permettre de naviguer dans les données qui sont structurées.
Pour le patron mentionné plus haut, nous avons créé des feuilles de style permettant de générer les résultats des extractions de patrons au format TXT ainsi qu'au format HTML. Nous avons également créé des feuilles de style pour les deux types de fichiers au format XML qui sont à notre disposition : le fichier TreeTagger et le fichier UDpipe.
Nous avons créé une règle qui doit être appliquée sur les noeuds "titre" et "description". Cette règle va tester le fait que l'élément contienne le premier POS du patron. Nous testons ensuite les frères suivants pour tester l'intégralité du patron. Nous récupérons ensuite la forme pour l'affichage.
Feuilles de style :
Fichier |
Langage |
Téléchargement |
TT_html |
XSLT |
|
UD_html |
XSLT |
|
TT_txt |
XSLT |
|
UD_txt |
XSLT |
|
Résultats :
Fichier |
Rubrique |
Téléchargement |
TT_html |
3208 |
|
TT_html |
3210 |
|
UD_txt |
3208 |
|
UD_txt |
3210 |
|
Solution 3 : XQUERY
Cette troisième solution nous permet de travailler avec les requêtes du langage XQuery. Nous travaillons sur le logiciel BaseX. Comme pour la précédente solution, nous travaillons uniquement sur les fichiers XML. Nous présentons ici la requête pour le patron "DET NOUN ADJ". Les autres requêtes avec des longueurs de patrons différentes sont présentées sur le site du projet de Documents Structurés.
Le fonctionnement est le même que pour la solution précédente. Nous testons le POS du premier élément ainsi que les POS des frères suivants. Nous assemblons ensuite les formes trouvées pour l'affichage des résultats.
Requête :
Fichier |
Langage |
Téléchargement |
UD_XML |
XQUERY |
|
Résultats :
Fichier |
Rubrique |
Téléchargement |
UD_txt |
3208 |
|
UD_txt |
3210 |
|
UD_txt |
3244 |
|
Extraction de relations de dépendances
Dans cette seconde partie, nous présentons trois méthodes pour effectuer une extraction de relations syntaxiques de dépendances. Une relation de dépendance est une relation entre deux tokens, l'un est le gouverneur, l'autre le dépendant. Les relations sont les liens syntaxiques entre les mots ou tokens d'une phrase. Ici, le but est de voir les relations entre les tokens étiquetés par UDpipe. Par exemple, nous pouvons observer la relation "obj" entre deux tokens. Cela nous permettra de voir les données des différentes catégories sous un nouvel angle.
Plusieurs méthodes ont été explorées pour cette seconde étape : XSLT/XPath, XQuery et Perl/Python.
Solution 1 : XSLT / XPATH
Cette première solution pour l'extraction des relations de dépendances consiste à utiliser les feuilles de style XSLT ainsi que le langage XPath. Le fonctionnement global sera le même pour les trois solutions.
Nous commençons par voir si nous retrouvons la relation dans les données. Si c'est le cas, alors on va mémoriser la forme du dépendant, la position de la tête (gouverneur) ainsi que la position du dépendant. Ensuite, en fonction de la position de la tête par rapport au dépendant, nous recherchons dans les frères précédents ou dans les frères suivants, la position de la tête pour pouvoir en extraire la forme. Cette règle s'applique sur les noeuds "titre" et "description".
Comme pour l'extraction des patrons, nous permettons une sortie en TXT ainsi qu'en HTML. Les données en entrée sont uniquement celles provenant de l'étiquetage de UDpipe puisque c'est le seul outil qui propose ce type d'étiquetage.
Cette solution nous permet de modifier simplement les relations souhaitées, directement dans la feuille de style au niveau de la déclaration de notre paramètre. Ici, nous présentons les résultats pour la relation "obj".
Feuilles de style :
Fichier |
Langage |
Téléchargement |
UD_html |
XSLT |
|
UD_txt |
XSLT |
|
Résultats :
Fichier |
Rubrique |
Téléchargement |
UD_html |
3208 |
|
UD_html |
3246 |
|
UD_txt |
3210 |
|
UD_txt |
3244 |
|
Solution 2 : XQUERY
Pour cette deuxième solution, nous utilisons le langage XQuery via le logiciel BaseX. Le fonctionnement est très similaire à la solution évoquée plus haut. Nous pouvons également facilement modifier les relations à repérer dans les données.
Pour l'affichage, nous regroupons les résultats par fréquence et en ordre décroissant.
Requête :
Fichier |
Langage |
Téléchargement |
Relation |
XQUERY |
|
Résultats :
Fichier |
Relation |
Rubrique |
Téléchargement |
UD_txt |
obj |
3208 |
|
UD_txt |
obj |
3210 |
|
UD_txt |
subj |
3210 |
|
UD_txt |
obj |
3244 |
|
Solution 3 : Perl / Python
Pour cette troisième et dernière solution, nous avons utilisé la méthode des expressions régulières avec Perl et Python.
Nous avons tout d'abord homogénéisé les balises "titre" et "description" pour obtenir une seule et même balise qui est devenue le délimiteur pour la lecture des données. En effet, cette étape est cruciale dans la mesure où si nous n'avons pas de séparateur de phrases, le programme ira chercher les positions des têtes (gouverneurs) dans tout le fichier. Les résultats n'auraient alors aucun sens. Nous avons donc créé un script Perl permettant cette transformation. Les fichiers obtenus ont servi d'input aux programmes Perl et Python pour l'extraction des relations de dépendances.
Ensuite, le principe des deux programmes est le même que pour les autres solutions mentionnées. Nous utilisons un dictionnaire en Perl et une liste en Python pour compter la fréquence des couples tête-dépendant et pour pouvoir les afficher de manière décroissante. Comme pour l'extraction des patrons, nous normalisons les données en les passant toutes en minuscules.
En sortie de chaque programme, nous affichons à l'écran la liste des occurrences de la relation souhaitée avec la tête et le dépendant. Nous pouvons utiliser une commande bash afin d'écrire ce résultat dans un fichier TXT.
La commande bash utilisée est : perl bao3_extractRelation.pl preInput.xml obj > resultat_relation_obj_3208.txt
Script de transformation des balises "titre" / "description" en "p" (phrase) :
Fichier |
Langage |
Téléchargement |
Transformation en phrases |
Perl |
|
Scripts :
Fichier |
Langage |
Téléchargement |
UD XML |
Perl |
|
UD XML |
Python |
|
Résultats :
Fichier |
Sortie |
Relation |
Rubrique |
Téléchargement |
UD XML |
Perl |
obj |
3208 |
|
UD XML |
Perl |
obj |
3210 |
|
UD XML |
Perl |
subj |
3244 |
|
UD XML |
Perl |
subj |
3246 |
|
UD XML |
Python |
obj |
3244 |
|
UD XML |
Python |
obj |
3246 |
|
Résultats de la BAO 3
Les résultats obtenus sont identiques d'une solution à une autre.
Pour les extractions de patrons, les solutions les plus simples à manipuler sont les programmes Python et Perl car il est simple de modifier le patron souhaité. Les programmes s'adaptent aux longueurs des patrons. Les feuilles de style et requêtes doivent être retravaillées pour obtenir des patrons plus ou moins longs.
En ce qui concerne les extractions de relations de dépendances, toutes les solutions sont simples à mettre en oeuvre et à modifier. Les programmes Perl et Python nous donnent la fréquence d'apparition des couples tête-dépendant. Cela nous sera très utile pour la mise en oeuvre de la BAO 4 lorsque nous allons donner un poids aux données.