Maintenant que nous disposons de fichiers étiquetés en parties du discours nous pouvons en extraire des patrons syntaxiques. C'est le but de cette BAO3. Il y a de nombreuses méthodes pour l'extraction de patrons selon les fichiers desquels ont extrait. En effet, avec la BAO2 nous avons obtenu des fichiers étiquetés avec Cordial au format .txt contenant des colonnes, et des fichiers étiquetés avec TreeTagger au format .xml contenant des balises. Nous allons appliquer des méthodes différentes à ces sorties.
Globalement le script contient deux parties, le parcours du dossier avec les étiquettes Cordial et l'extraction des patrons souhaités. En premier, il faut déclarer deux variables : l'une pour le dossier à parcourir et l'autre pour le fichier de patrons. L'extraction de patrons à proprement parler se fera au moyen d'une procédure.
# Le dossier ou sont enregistres les fichiers tabulaires Cordial my $directoryCordialFiles = "$ARGV[0]"; # Le nom du fichier patron fournis en premier deuxieme du script. my $fileNameInputPatron = "$ARGV[1]"; # # Fonction extract_one_file # # Cette fonction attend 2 parametres: # - le nom du fichier cordial # - le nom du fichier patron # sub extract_one_file {...}
On lance le script sur deux dossiers resultatsEtiquetageCordial_purPerl et resultatsEtiquetageCordial_xmlRss. Par conséquent dans le Terminal on traite d’abord les sorties étiquetées de pur Perl :
On obtient alors un fichier .txt qui contient les extraits correspondant au patron indiqué
Il s'agit ici d'utiliser le module XML::XPATH pour produire un script qui prend en entrée un fichier étiqueté et un fichier de patrons et produit en sortie un fichier .txt pour chaque motif recherché. Il faut lancer le script une fois pour chaque fichier, ce qui peut sembler fastidieux, mais qui permet en réalité un gain de temps. Nous avons en effet modifié ce script afin d'y inclure une boucle qui traitement automatiquement un à un tous nos fichier mais le temps de traitement est beaucoup trop long. A remarquer aussi qu'il n'est pas possible de traiter des fichiers au-dessus d'une certaine taille. La solution serait alors de morceler les fichiers trop volumineux et de les traiter séparément.
# Traiter dans une boucle chaque fichier du dossier foreach my $file(@files_de_mondossier) { if (($file=~/([^\/\.]+?)\.xml$/) && ($file!~/[Gg]lobale/)) { # récupérer le nom de la rubrique du fichier my $rubrique=$1; print "\n>>> $rubrique"; <STDIN>; # ouvrir le fichier des motifs open(PATTERNSFILE, $patterns_file) or die "can't open $patterns_file: $!\n"; # lire chaque motif du fichier de motifs pour extraire les motifs en appelant la procédure while (my $ligne = <PATTERNSFILE>){ &extract_pattern($file,$ligne, $rubrique); } # fermer le fichier des motifs close(PATTERNSFILE); } } ########################################################################################################## # définition du nom du fichier de résultats pour le motif en utilisant la fonction join my $match_file = $sousrepertoireglobal.$tag_file."_res_extract-".join('_', @tokens).".txt"; #nettoyer le nom des fichiers de sortie $match_file=~s/TAG_sortie//; $match_file=~s/.txt.xml//; définition du nom du fichier de résultats pour le motif en utilisant la fonction join my $match_file = $sousrepertoireglobal.$tag_file."_res_extract-".join('_', @tokens).".txt"; #nettoyer le nom des fichiers de sortie $match_file=~s/TAG_sortie//; $match_file=~s/.txt.xml//;
La durée du traitement varie beaucoup selon les fichiers.
Et Nous avons là encore eu quelques soucis d'encodage. En effet, certaines sorties .xml de TreeTagger n'étaient pas bien formées en raison de la persistance de codes contenant "&". Pour y remédier nous avons tenté de réappliquer la procédure "nettoietexte" au niveau de la BAO2 avant le traitement par TreeTagger sur les fichiers non étiquetés, après la procédure TreeTagger en capturant l'output de Perl system() dans une variable ou encore en ajoutant une petite boucle pour lire les lignes du fichier dont il faut extraire les patrons dans la BAO3 mais rien n'y a fait ! Les entités spéciales ""#8211;" et "& amp;" n'ont pas bougé, et en désespoir de cause nous nous sommes résignées à les modifier à la main en cas de besoin (ce problème ne concerne que 4 fichiers et les occurrences sont très peu nombreuses, mais il est sûr que pour des quantités plus importantes une solution plus pratique doit être trouvée).
Exemple de sortie :
Pour cette troisième méthode nous n'avons pas besoin de script ou de programme, il suffit de quelques ligne de requêtes XPATH pour extraire sur un fichier .xml produit par la BAO2 un tableau affichant les résultats souhaités. Pour appliquer les requêtes XPATH à notre fichier .xml il faut une feuille de style XSLT à lier au fichier XML. Il faut aussi savoir se placer dans son arborescence et pour cela il est nécessaire de modifier quelques lignes dans la feuille de style fournie car les balises dépendent de ce qu'on a choisi d'écrire dans les scripts des BAO précédentes. Ensuite, pour retrouver les formes qui correspondent à un patron donné, il faut examiner les nœuds du document en utilisant "following-sibling" et "preceding-sibling" ainsi que "contains" pour retrouver des éléments de notre patron. Ainsi pour nos patrons [NOM PRP NOM], [NOM ADJ] et [ADV ADJ], les requêtes donnent :
-------------------------------------------------------- NOM PRP NOM -------------------------------------------------------- <xsl:if test="(./data[contains(text(),'NOM')])"> <xsl:variable name="nom1" select="./data[3]/text()"/> <xsl:if test="following-sibling::element[1][./data[contains(text(),'PRP')]]"> <xsl:variable name="prep" select="following-sibling::element[1]/data[3]/text()"/> <xsl:if test="following-sibling::element[2][./data[contains(text(),'NOM')]]"> <xsl:variable name="nom2" select="following-sibling::element[2]/data[3]/text()"/> <font color="#FF0062"><xsl:value-of select="$nom1"/></font><xsl:text> </xsl:text> <font color="#00AFFF"><xsl:value-of select="$prep"/></font><xsl:text> </xsl:text> <font color="#FF0062"><xsl:value-of select="$nom2"/></font><br/> </xsl:if> </xsl:if> </xsl:if> -------------------------------------------------------- NOM ADJ -------------------------------------------------------- <xsl:choose> <xsl:when test="(./data[contains(text(),'NOM')]) and (following-sibling::element[1][./data[contains(text(),'ADJ')]])"> <font color="#FF0062"> <xsl:value-of select="./data[3]"/> </font> <xsl:text> </xsl:text> </xsl:when> <xsl:when test="(./data[contains(text(),'ADJ')]) and (preceding-sibling::element[1][./data[contains(text(),'NOM')]])"> <font color="#7AC600"> <xsl:value-of select="./data[3]"/> </font> <br/> </xsl:when> </xsl:choose> -------------------------------------------------------- ADV ADJ -------------------------------------------------------- <xsl:choose> <xsl:when test="(./data[contains(text(),'ADV')]) and (following-sibling::element[1][./data[contains(text(),'ADJ')]])"> <font color="#FF9500"> <xsl:value-of select="./data[3]"/> </font> <xsl:text> </xsl:text> </xsl:when> <xsl:when test="(./data[contains(text(),'ADJ')]) and (preceding-sibling::element[1][./data[contains(text(),'ADV')]])"> <font color="#7AC600"> <xsl:value-of select="./data[3]"/> </font> <br/> </xsl:when> </xsl:choose>
Exemple de sortie :