1.png 2.png BaO.png 4.png 5.png


Boîte à Outils 2 - Extraction de motifs pour un patron morphosyntaxique donné



Les différents outils pour l'extraction :

		1. Perl :
			1.1. Scripts pour la sortie de Cordial
				1.1.1. solution 1 
				1.1.2. solution 2 
			1.2. Script pour traiter la sortie de Tree Tagger 

		2. XSL :
			1. Feuille de style pour traiter la sortie de Tree Tagger 
	


Structure des données étiquetées:
		Le script parcours le fichier étiqueté de Cordial qui se structure en 3 colonnes et où chaque ligne est un token différent:

			Les 3 colonnes:
				1. le token
				2. son lemme
				3. sa catégorie morphosyntaxique

			ex :
				écoulée	 écoulé	   ADJFS
				renonce	 renoncer	 VINDP3S
				l'	        le	        DETDFS

		➝ Le script doit retourner les termes lexicalisés correspondants au patron morphosyntaxique donné.
		



Script pour extraire les motifs de la sortie de Cordial - Solution 1
			
#!/usr/bin/perl
#nous travaillons avec l'output étiqueté de Cordial
binmode STDOUT, ":iso-8859-1";
#-------------------------------------------------------------------------------
open (FIC,"<:encoding(iso-8859-1)", $ARGV[0]);
open (MOTIF,"<:encoding(iso-8859-1)", $ARGV[1]);
$output_cordial=".\/output\/extraction_patrons_iso-8859-1.txt";
open my $OUTPUT, ">", $output_cordial;
# ouvrir le motif des patrons
@liste_motifs=<MOTIF>;
# print @liste_motifs;
# la liste des motifs que nous allons chercher
close(MOTIF);
#-------------------------------------------------------------------------------

my @token=();
my @etiquette=();
while (my $ligne = <FIC>) {
  next if ($ligne!~/^[^\t]+\t[^\t]+\t[^\t]+/);
  $ligne =~ s/\r//g;
  chomp($ligne); # enlever \n
  # print "$ligne\n";
  if ($ligne!~/^[^\t]+\t[^\t]+\tPCTFORTE/) { # ~/PCTFORTE/ - ponctuation forte

    @liste=split(/\t/, $ligne);
    # j'ai besoin du 1er el et du 2nd el de la liste
    push(@token , $liste[0]); #tu rajoutes l'el ) l'index 0 dans la liste @token
    push(@etiquette, $liste[2]); #3e colonne
    # quand on arrive à ponctuation forte on va traiter!
  }
  else {
    @token=();
    @etiquette=();#on purge la liste pour avoir un bon fonctionnement de push
    #print @token;
  }
}

close FIC;
close $output;
system ("iconv -f ISO-8859-1 -t UTF-8 .\/output\/extraction_patrons_iso-8859-1.txt > .\/output\/extraction_patrons_utf8.txt");

#-------------------------------------------------------------------------------

sub extract {
  # liste -> scalaire
  my $token_as_string=join(" ", @token);
  my $etiquette_as_string=join(" ", @etiquette);
  # print $token_as_string;
  # print $etiquette_as_string;
  # -> 2 scalaires
  foreach my $motif ( @liste_motifs) {
    print "voici motif", $motif, "\n";
    print "voici étiquettes " , $etiquette_as_string , "\n";
    # my $rep=<STDIN>;
    chomp($motif); #enlève le \n
    # chq ligne donnée par la personne qui a créé ce fichier
    my $compteur_espace_avant=0;
    while ($etiquette_as_string=~/$motif/g){
      # ballader le motif qu'on a lu sur la chaine des étiquettes
      my $avant = $`; # var spéciale, concordancier tout ce qu'il y a avant
      while ($avant=~/ /g){
        $compteur_espace_avant++;
      }
      my $espace_motif=0;
      while ($motif =~ / /g){
        $espace_motif++; # le nombre d d'espace dans le motif N AD = 1 espace
      }
      my $total_espace= $compteur_espace_avant+$espace_motif;
      print $OUTPUT "@token[$compteur_espace_avant..$total_espace]\n"; #[A..Z] (de ça à ça) index qui sélectionne le motif
      print "@token[$compteur_espace_avant..$total_espace]\n\n"; #[A..Z] (de ça à ça) index qui sélectionne le motif
    }
  }
}
			
		


			
Le script de divise en deux parties:
	1. Une partie  d'ouverture et lecture des fichiers, d'instanciation des sorties et qui nous permet d'identifier les phrases du fichier .cnr
	2. Une fonction "extract" qui est appelée dans la première partie

Les arguments et les sorties du script :
	➝ input: output_étiqueté_de_cordial.cnr + fichier_de_patrons.txt
	➝ output: motifs_extraits_iso-8859-1.txt  + motifs_extraits_utf-8.txt

Partie 1 :
	➝ Ouverture, lecture et nettoyage du fichier étiqueté.
	➝ Instanciation d'une variable qui stocke les motifs (écrits dans fichier_de_patrons.txt) recherchés
	➝ Parcours du fichier jusqu'à rencontrer une ponctuation forte "PCTFORTE" qui se situe dans la 3ème colonne
		➝ Reconnaissance d'une phrase.
			➝ Je stocke les tokens dans une liste : @token
			➝ Je stocke les étiquettes dans une liste : @etiquettes

Partie 2 :
	➝ Définition de la fonction "extract"
	➝ Création d'une chaîne de caractère en intercalant un espace entre chaque élément de la liste @token
	➝ Création d'une chaîne de caractère en intercalant un espace entre chaque élément de la liste @etiquette
		➝ Boucle while qui permet de balader le motif sur la chaîne de caractère afin d'en extraire les correspondances.
			➝ Nous accédons aux termes lexicalisés par un système de calcul d'index reposant sur le comptage des espace entre chaque élément.
			
		




Script pour extraire les motifs de la sortie de Cordial - Solution 2
			
open(FILE,"$ARGV[0]");
my @lignes=<FILE>;
close(FILE);
while (@lignes) {
    my $ligne=shift(@lignes);
    chomp $ligne;
    my $sequence="";
    my $longueur=0;
    if ( $ligne =~ /^([^\t]+)\t[^\t]+\t$ARGV[1]/) {
	    $sequence.=$1;
	    $longueur++;
	    my $indice=1;
	    my $stop=1;
	    while (($indice < $#ARGV) and ($stop == 1)) {
	       my $nextligne=$lignes[$indice-1];
	          if ( $nextligne =~ /^([^\t]+)\t[^\t]+\t$ARGV[$indice+1]/) {
		            $sequence.=" ".$1;
		            $longueur++;
	              }
      	    else {
      		      $stop=0;
      	     }
	     $indice++;
	    }
	  if ($longueur == $#ARGV) {
	    print $sequence,"\n";
	 }
  }
}


			
		


			
Le script se compose d'une seule partie principale.
	➝ 2 fichiers donnés en argument : $ARGV[0] le fichier à parcourir, $ARGV[1] le fichier contenant le patron morphosyntaxique à extraire
	➝ Structure générale du script : while {   if {  while{ if{} else{} }   if {}} }  }

Déroulement du script:
	➝ Stocke en mémoire chaque ligne du fichier à parcourir dans une liste @lignes
	➝ Ouverture de la boucle principale
		➝ lecture ligne par ligne en stockant le premier argument de la ligne @lignes dans une variable $ligne
		➝ Suppression du retour à la ligne grâce à chomp
		➝ Instanciation de 2 variables $sequence et $longueur qui vont être remplies.
			➝ Condition : test sur la 3ème colonne (donc sur la catégorie morphosyntaxique)
			➝ Recherche du motif sur la 3ème colonne, il doit correspondre au premier motif donné en argument.
				➝ boucle while : tant que la variable $indice est inférieure à la valeur du plus grand Indice de la liste ARGV et $stop == 1 nous continuons.
					➝ Nous passons à la ligne suivante
					➝ Condition : si nous trouvons le second motif donné en argument dans la 3ème colonne
						➝ Alors nous concaténons les 2 motifs trouvés et stockons la concaténation dans la variable $séquence
						➝ Si non, $stop=0 et nous arrêtons
					➝ Condition : si la valeur de la variable $longueur (un entier) est égale au plus grand indice de la variable $ARGV alors nous avons trouvé tous les motifs que nous cherchions.
						➝ Alors nous affichons la séquence suivi d’un retour à la ligne
			
		




Script pour traiter la sortie de Tree Tagger
			
open(FILE,"$ARGV[0]");
#--------------------------------------------
# le patron cherché ici est du type NOM ADJ";
# le modifier pour extraire NOM PREP NOM
#--------------------------------------------
my @lignes=<FILE>;
close(FILE);
while (my $ligne=shift(@lignes)) {
    chomp $ligne;
    my $sequence="";
    my $longueur=0;
    if ( $ligne =~ /<element><data type=\"type\">NOM<\/data><data type=\"lemma\">[^<]+<\/data><data type=\"string\">([^<]+)<\/data><\/element>/) {
		my $forme=$1;
		$sequence.=$forme;
		$longueur=1;
		my $nextligne=$lignes[1]; #saut de ligne dans nos scripts
  		if ( $nextligne =~ /<element><data type=\"type\">ADJ<\/data><data type=\"lemma\">[^<]+<\/data><data type=\"string\">([^<]+)<\/data><\/element>/) {
  			my $forme=$1;
  			$sequence.=" ".$forme;
  			$longueur=2;
  		}
    }
    if ($longueur == 2) {
	    print $sequence,"\n";
    }
}oue
			
		


			
Le script se compose d'une seule partie principale.
	➝ 2 fichiers donnés en argument : $ARGV[0] le fichier à parcourir, $ARGV[1] le fichier contenant le patron morphosyntaxique à extraire
	➝ Structure générale du script : while {   if {  while{ if{} else{} }   if {}} }  }

Déroulement du script:
	➝ Stocke en mémoire chaque ligne du fichier à parcourir dans une liste @lignes
	➝ Ouverture de la boucle principale
		➝ 1ère condition (la boucle if contient une seconde boucle if ce qui permet d’extraire 2 motifs différents)
			➝ Nous recherchons en nous appuyant sur la structure du document XML le motif lexical correspondant au premier motif
			➝ 2ème condition
				➝ Nous recherchons en nous appuyant sur la structure du document XML le motif lexical correspondant au second motif
		➝ 3ème condition qui sort de la première boucle if qui contient elle même une seconde condition : while { if {if {} }  if{} }
			➝ Cette dernière condition vérifie que le motif extrait est bien composé de 2 éléments.
			➝ Si c’est le cas alors nous affichons la variable $sequence qui stocke en mémoire les éléments lexicaux correspondants aux catégories demandées
			
		




Feuille de style pour interroger la sortie de Tree Tagger
			
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="html"/>
    <xsl:template match="/">
        <html>
            <body bgcolor="#173653">
                <table align="center" width="50%" bgcolor="173653" bordercolor="#bad0d1" border="1">
                    <tr bgcolor="#173653">
                        <td>
                            <font color="#c86755" align="center">
                                <h1>
                                    Extraction de patron
                                    <font color="#f0b156">
                                        <b>PRP:det</b>
                                    </font>
                                    <font color="#bad0d1">
                                        <b>ADJ</b>
                                    </font>
                                    <font color="#f0b156">
                                        <b>NOM</b>
                                    </font>
                                </h1>
                            </font>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <blockquote>
                                <xsl:apply-templates select="//article"/>
                            </blockquote>
                        </td>
                    </tr>
                </table>
            </body>
        </html>
    </xsl:template>
    <xsl:template match="element">
        <xsl:choose>
            <xsl:when test="(./data[contains(text(),'PRP:det')]) and (following-sibling::element[1][./data[contains(text(),'ADJ')]]) and (following-sibling::element[2][./data[contains(text(),'NOM')]])">
                <font color="#f0b156">
                    <xsl:value-of select="./data[3]"/>
                </font>
                <xsl:text> </xsl:text>
            </xsl:when>
            <xsl:when test="(./data[contains(text(),'ADJ')]) and (following-sibling::element[1][./data[contains(text(),'NOM')]]) and (preceding-sibling::element[1][./data[contains(text(),'PRP:det')]])">
                <font color="#bad0d1">
                    <xsl:value-of select="./data[3]"/>
                </font>
                <xsl:text> </xsl:text>
            </xsl:when>
            <xsl:when test="(./data[contains(text(),'NOM')]) and (preceding-sibling::element[1][./data[contains(text(),'ADJ')]]) and (preceding-sibling::element[2][./data[contains(text(),'PRP:det')]])">
                <font color="#f0b156">
                    <xsl:value-of select="./data[3]"/>
                    <br />
                </font>
                <xsl:text> </xsl:text>
            </xsl:when>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>
			
		


			
Structure du fichier interrogé par la feuille de style XSL :

	<?xml version="1.0" encoding="utf-8" ?>
	<?xml-stylesheet type="text/xsl" href="BaO2_tree-tagger_xslt_Jade_M.xsl"?>

	<PARCOURS>
	<NOM>Jade Mekki</NOM>
	<FILTRAGE>

	<item>
	<titre><document>
	<article>
	<element><data type="type">NOM</data><data type="lemma">#VivreAvec</data><data type="string">#VivreAvec</data></element>

	<element><data type="type">PUN</data><data type="lemma">:</data><data type="string">:</data></element>

	<element><data type="type">VER:infi</data><data type="lemma">bâtir</data><data type="string">Bâtir</data></element>

	<element><data type="type">PRP</data><data type="lemma">sur</data><data type="string">sur</data></element>

	<element><data type="type">DET:ART</data><data type="lemma">le</data><data type="string">le</data></element>

	<element><data type="type">NOM</data><data type="lemma">néant</data><data type="string">néant</data></element>

	</article>
	</document>


Fichier html formé après avoir parsé le document XML avec la feuille de style XSL:

Le tableau complet peut être consulté ici