Objectifs
Dans la troisième boîte à outils, l'objectif est d'extraire des patrons syntaxiques à partir des fichiers étiquetés obtenus à l'étape précédente. C'est-à-dire extraire des fichiers toutes les chaînes de mots répondant à deux patrons syntaxiques typiques en français (nom prep nom et nom adj), par exemple : "voie de normalisation" et "pays producteurs".L'étape précédente nous a fourni deux types de fichiers, nous allons essayer sur chacun de ces formats deux méthodes différentes :
- Les fichiers obtenus par Treetagger (format .xml) seront traités à l'aide d'une requête XPath intégrée à une feuille de style XSLT.
- Les fichiers étiquettés par Cordial (format .cnr) seront traités par un script perl.
Outils
Pour la première méthode :- Xpath : langage de requête sur les documents XML
- XSLT : langage de feuille de style XML
- altovaxml.exe : processeur XML en ligne de commande (permet entre autres d'associer une feuille de style XSLT à un document XML)
- extrac.pl : un script perl écrit (par JM Daube) pour faire de l'extraction de patrons
Méthode n° 1 : XPath
La première méthode consiste à partir des fichiers XML étiquetés, les associer à une feuille de style XSLT afin d'obtenir en sortie des fichiers de patrons au format texte.Une feuille de style XSLT est un document XML qui utilise des chemins XPath pour sélectionner des éléments (= des balises) dans un document XML. Nos documents taggés se présentent sous la forme :
Récupérer les bonnes catégories syntaxiques signifie donc faire un test sur la valeur des attributs type des éléments <data>.
Ainsi, dans le cas de l'extraction des patrons NOM/PREP/NOM :
- lorsqu'on trouve des éléments <element> frères successifs (commandes following-sibling et preceding-sibling)
- ayant comme fils (./) des éléments <data> dont les attributs type ont comme valeurs respectives de NOM PRP et NOM,
- on imprime en sortie (commande xsl:text suivie d'un blanc après le premier NOM et PRP, et d'un retour à la ligne après le second NOM) le contenu textuel de du troisième (prédicat [3]) élément <data> (celui qui a comme valeur d'attribut string).
Soit le template suivant :
<xsl:template match="/document/article/element">
<xsl:choose>
<xsl:when test="(./data[contains(text(),'NOM')]) and (following-sibling::element[1][./data[contains(text(),'PRP')]]) and (following-sibling::element[2][./data[contains(text(),'NOM')]])"> <xsl:value-of select="./data[3]"/><xsl:text> </xsl:text> </xsl:when>
<xsl:when test="(./data[contains(text(),'PRP')]) and (preceding-sibling::element[1][./data[contains(text(),'NOM')]]) and (following-sibling::element[1][./data[contains(text(),'NOM')]])"> <xsl:value-of select="./data[3]"/><xsl:text> </xsl:text> </xsl:when>
<xsl:when test="(./data[contains(text(),'NOM')]) and (preceding-sibling::element[1][./data[contains(text(),'PRP')]]) and (preceding-sibling::element[2][./data[contains(text(),'NOM')]])"> <xsl:value-of select="./data[3]"/><xsl:text>
</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:choose>
<xsl:when test="(./data[contains(text(),'NOM')]) and (following-sibling::element[1][./data[contains(text(),'PRP')]]) and (following-sibling::element[2][./data[contains(text(),'NOM')]])"> <xsl:value-of select="./data[3]"/><xsl:text> </xsl:text> </xsl:when>
<xsl:when test="(./data[contains(text(),'PRP')]) and (preceding-sibling::element[1][./data[contains(text(),'NOM')]]) and (following-sibling::element[1][./data[contains(text(),'NOM')]])"> <xsl:value-of select="./data[3]"/><xsl:text> </xsl:text> </xsl:when>
<xsl:when test="(./data[contains(text(),'NOM')]) and (preceding-sibling::element[1][./data[contains(text(),'PRP')]]) and (preceding-sibling::element[2][./data[contains(text(),'NOM')]])"> <xsl:value-of select="./data[3]"/><xsl:text>
</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:template>
Dernier point : la feuille de style doit spécifier le type (txt) et l'omission de la déclaration XML dans le document de sortie (par la commande xsl:output) :
<xsl:output method="text" encoding="ISO-8859-1"
omit-xml-declaration="yes"/>
>> Voir la feuille de style pour l'extraction NOM/ADJ
>> Voir la feuille de style pour l'extraction NOM/PRP/NOM
On associe enfin la feuille de style au fichier étiqueté avec altovaxml.exe, par la ligne suivante (dans l'idéal on aurait intégré cette ligne au script bao2.pl pour en faire un bao3.pl qui aurait fait le traitement : filsRSS.xml > fictag.xml > ficpatrons.txt):
altovaxml.exe -xslt1 <fsxslt> -in <docxml> -out <doctxt>
On obtient en sortie :
- 17 fichiers pour le patron NOM/ADJ >> aperçu (rubrique Cinema)
- 17 fichiers pour le patrons NOM/PRP/NOM >> aperçu (rubrique Technologies)
Méthode n° 2 : script Perl
On nous fournit un script Perl (extrac.pl) qui permet de faire de l'extraction de patrons à partir de fichiers taggés par Cordial. Sa syntaxe est la suivante : extrac.pl <filein> <patrons> <fileout>Avec : | <filein> | = un fichier taggé (format .txt) |
<patrons> | = un fichier contenant les patrons à extraire (format .txt) | |
<fileout> | = un fichier de sortie (format .txt) |
La perspective de devoir relancer 34 fois (17 fichiers x 2 patrons) le script --avec 34 renomages des arguments à la clef-- nous ayant quelque peu horrifiée et la paresse étant une qualité reconnue du programmeur (même débutant), nous avons décidé d'écrire deux petits scripts de lancement très simples qui permettent de se dispenser de cette tâche pénible. Une petite série de ctrl+C ctrl+V et voilà le travail :
- Pour l'extraction de NOM/ADJ : lanceur 1
- Pour l'extraction de NOM/PRP/NOM : lanceur 2
On obtient en sortie un répertoire resultats_cordial contenant 34 fichiers de patrons du type :
- NA-rubrique.txt >> aperçu (rubrique "Environnement sciences")
- NPN-rubrique.txt >> aperçu (rubrique "Environnement sciences")
Les patrons non pertinents trouvés (par exemple pour NA : "Christophe Colomb", "automne Deux" ou "étude mise") sont dus à plusieurs causes :
- choix des concepteurs de l'étiquetteur (étiquetter les nom/prénom comme des nom/adj)
- erreur d'étiquetage due à une ambigüité syntaxique
- erreur d'étiquetage due à une mauvaise segmentation