our passer à l'extraction de patrons syntaxiques! ...
Ici 3 moulinettes sont mises en place, usant de stratagèmes et techniques différentes:
Le fichier Cordial obtenu suite au passage à la moulinette BàO #2 se présente sous la forme suivante: [Token Lemma PoS]
Le programme Perl va parcourir la colonne "Part-of-Speech" et extraire les "Tokens" à chaque fois qu'il trouve un patron, ici nous avons élu le suivant: PREP DETFS NCFS.
- On va réaliser cette extraction sur des millions de mots et avec des patrons différents.
- On va extraire un certain nombre de candidats-termes (terminologies), puis on va demander à un "expert" s'ils sont corrects.
- On va chercher la longue liste des étiquettes (millions de symboles PoS). /!\ On va lire l'ensemble de la ligne PoS au préalable pour l'avoir à plat (sous forme de liste), comme les 2 autres (Token et Lemma), donc on obtient ici 3 listes.
- On va ouvrir notre fichier et parcourir la 1ère ligne, dès qu'on match une occurrence correspondant au patron qui nous intéresse:
CRAC extraction!
#!usr/bin/perl -w
L'option -w
(warning) équivaut à écrire Use::warnings
ou Use::diagnostics
qui permet d'avoir une réponse plus claire sur l'endroit du fichier où on a fait la faute.
Pour pouvoir accéder à la liste des tokens, à chaque fois qu'il y a une correspondance (=un match avec un patron), je vais transformer ma liste de PoS en scalaire, ainsi le scalaire va parcourir et trouver un match.
On a derrière une liste $suite_pos
(car on ne peut pas chercher un scalaire dans une liste)!
On match une 1ère occurrence sur la ligne. Pour obtenir une 2de sur la même ligne - si on connaît les formes situées entre les 2 patrons - en revenant avant le match, on peut retrouver l'indice de la ligne càd le rang dans la liste.
Les 3 variables prédéfinies dans Perl permettent de localiser ce qui a été reconnu (cf. Concordance).
Une autre variable prédéfinie nous permet d'obtenir la 1ère ligne d'un fichier qu'on lit ligne à ligne:
while (<FILE>) {
print $_ ; # Perl laxiste stocke la ligne lue dans la variable $_
(il l'associe par défaut)
}
@liste = split(/ /, $avant);
$#liste+1; # On obtient le nombre d'éléments de la liste!
$avant = $`;
while ($avant =~ / /g) {$NBDEBLANCS++;}
for ($k=0; $k < $longueurpatron; $k++) {
print $LISTETOKEN[$NBDEBLANCS+$k];
}
C'est une autre manière de réfléchir!
Ici, on fait l'impression dans une boucle for
qu'on initialise grâce à la valeur $k
pour déterminer la longueur d'affichage.
@liste[1..3] # TIMTOWTDI
On récupère un fichier XML taggé par Treetagger, on a défini de la même façon que pour Cordial un fichier de motifs. (/!\ Il faut un motif par ligne!)
Rappel de l'arborescence du fichier XML étiquetté avec Treetagger:
<ETIQUETAGE>
<FICHIER>
<element>
<data></data> <data></data> <data></data>
</element>
Rappels:
$#table # renvoie à l'indice du dernier élément du tableau
$#ARGV # renvoie donc à l'indice du dernier élément passé en argument au terminal
$0 # correspond au nom du script
shift @table # renvoie au premier élément du tableau en le supprimant
shift
choppe le 1er élément de la liste - d'arguments, ici - en le supprimant, on définit 2 variables contenant chacune ARGV[0]
(= fichier_taggé.xml) et ARGV[1]
(= fichier_de_motifs.txt).Rappel: @_
désigne la liste des paramètres qu'on donne à une fonction
shift @_
renvoie le premier paramètre passé à la fonction (comme on n'en a qu'un ici, renvoi de l'unique: $ligne
).On utilise des requêtes XPath:
//element # au début d'un chemin XPath sélectionne tous les nœuds <element>
//data # sélectionne tous les nœuds <data>
//element/data # sélectionne les nœuds <data> fils de <element>
//element/data[1] # récupère les nœuds <data> de type "catégorie"
Ce qu'on veut c'est se trouver au 1er élément <data>: //element/data[1]
et parmi eux le premier fils qui contient NOM:
//element/[data[@type="type"][contains(text(),"NOM")]]
On peut aussi l'écrire plus simplement comme suit: //element[contains(data[1],"NOM")]
Il est plus simple de se placer sur le père pour aller chercher les fils!
→ Solution 1 pour récupérer NOM PRP:
//element/[data[@type="type"][contains(text(),"NOM")][ancestor::data[@type="type"][contains(text(),"PRP")]]
→ Solution 2: //element[contains(data[1],"NOM")][following-sibling::element[1][contains(data[1],"PRP")]]
Rappel: L'axe ancestor::
désigne le nœud parent, tandis que preceding-sibling::
désigne le frère.
→ Pour récupérer NOM PRP NOM:
//element[contains(data[1],"NOM")][following-sibling::element[1][contains(data[1],"PRP")]][following-sibling::element[2][contains(data[1],"NOM")]]
/!\ Si on a un fichier du type " N P N ", on obtiendra en sortie un tableau avec 5 élements – et non pas 3 (le 1er et le dernier étant des éléments vides).
Cette feuille de style permet au moyen d'XSLT et de requêtes XPath d'extraire soigneusement des patrons syntaxiques d'un fichier XML treetaggé.
Une ligne de code est à ajouter manuellement dans le fichier XML pour le relier à la feuille de style.
<?xml-stylesheet type="application/xml" href="lien_vers_feuille_de_style.xsl"?>
A l'intérieur de la feuille de style, on applique les règles en alternant des balises HTML pour une sortie aérée, et des requêtes XPath naviguant dans les méandres de l'arborescence XML.
Les requêtes XPath sont les mêmes que celles définies ci-dessus pour le script Perl adapté à la sortie Treetagger, ainsi nous obtenons des patrons NOM PREP NOM.