Boîte à outils 3 : Extraction des patrons

L'objectif de cette étape est de réaliser, à partir des fichiers de sortie XML version Treetagger de la boîte à outils 2, une extraction terminologique. Il s'agit d'une application du traitement automatique du langage naturel qui consiste à extraire une ou plusieurs listes de termes à partir d'un corpus spécialisé. L'étape consiste alors à extraire des suites de mots, correspondant à des patrons syntaxiques prédéfinis pour, ensuite, générer des graphes. L'extraction de ces patrons peut se faire de deux manières différentes:

  1. Extraction des patrons par un script Perl
  2. Extraction des patrons par une transformation XSLT

Extraction des patrons par un script Perl

Cas des fichiers sortie Treetagger

Nous avons développé deux types de patrons, à savoir :

  1. Patron NOM-ADJ : un nom suivi d'un adjectif.
  2. Patron NOM-PREP-NOM : un nom suivi d'une préposition puis d'un nom.

Cas d'un patron NOM-ADJ

Voici le script Perl qui cherche dans le fichier XML obtenu par Treetagger le patron NOM-ADJ :


#--------------------------------------------
# le patron cherché ici est du type NOM ADJ";
#--------------------------------------------
open(FILE,"$ARGV[0]");
my @lignes=<FILE>;
close(FILE);

# nom de la rubrique 
my $rub ="$ARGV[1]";
# fichier sortie pour graphe 
if (!open (FILEOUT,">:encoding(iso-8859-1)", "./SORTIE/bao3-extract-patron-NOM-ADJ-treetagger-".$rub.".txt")) { 
    die "Pb a l'ouverture du fichier pour écriture"
	};

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[0];
		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 FILEOUT $sequence,"\n";
    }
}

close FILEOUT;

										 

Cas d'un patron NOM-PREP-NOM

Voici le script Perl qui cherche dans le fichier XML obtenu par treetagger le patron NOM-PREP-NOM :


#---------------------------------------------------
# le patron cherché ici est du type NOM PREP NOM";
#---------------------------------------------------
open(FILE,"$ARGV[0]");
my @lignes=<FILE>;
close(FILE);

# nom de la rubrique 
my $rub ="$ARGV[1]";
# fichier sortie pour graphe 
if (!open (FILEOUT,">:encoding(iso-8859-1)", "./SORTIE/bao3-extract-patron-NOM-PREP-NOM-treetagger-".$rub.".txt")) { 
    die "Pb a l'ouverture du fichier pour écriture"
  };

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[0];
		if ( $nextligne =~ /<element><data type=\"type\">PRP<\/data>
		                             <data type=\"lemma\">[^<]+<\/data>
									 <data type=\"string\">([^<]+)<\/data>
							<\/element>/) {
			my $forme=$1;
			$sequence.=" ".$forme;
			$longueur=2;
			my $nextnextligne=$lignes[1];
			if ( $nextnextligne =~ /<element><data type=\"type\">NOM<\/data>
			                                 <data type=\"lemma\">[^<]+<\/data>
											 <data type=\"string\">([^<]+)<\/data>
								   <\/element>/) {
			my $forme=$1;
			$sequence.=" ".$forme;
			$longueur=3;
			}
		}
    }
    if ($longueur == 3) {
	print FILEOUT $sequence,"\n";
    }
	
}
close FILEOUT;

										 

Cas des fichiers sortie Cordial

Le programme prend en entrée les sorties «brutes» de l’étiquetage, obtenues avec Cordial, issues de la Boîte à outils 2, et extrait, via un script Perl, les patrons mentionnés. Pour exécuter le script, il faut un fichier de motifs à extraire, contenant les patrons syntaxiques (pos.txt) et le fichier issu de Cordial. Il génère en sortie un fichier de résultats, qui affiche toutes les suites de mots correspondants aux motifs spécifiés.

Voici le code source de script Perl :


#!/usr/bin/perl
#----------------------------------
# Ouverture des fichiers en lecture
#----------------------------------
open (FICTAG, $ARGV[0]) or die ("probleme sur ouverture de la sortie CORDIAL...");
open (FICPOS, $ARGV[1]) or die ("probleme sur ouverture du fichier des patrons...");
open (FILEOUT,">",$ARGV[2]) or die ("probleme sur ouverture du fichier résultat...");
#-----------------------------------------
# on stocke les patrons dans une liste....
#-----------------------------------------
my @listedespatrons=();
while (my $lignepos = <FICPOS>) 
{
    chomp($lignepos);
    push(@listedespatrons,$lignepos);
}
close(FICPOS);
#---------------------------
# Initialisation des listes
#--------------------------
my @malignesegmentee = ();
my @listedetokens = ();
my @listedelemmes = ();
my @listedepos = ();
#-------------------------------------------
# Lecture du fichier de tags ligne par ligne
#-------------------------------------------
while (my $ligne = <FICTAG>) {
    #----------------------------------------------------------------------------------
    # On ne s'occupe pas des lignes qui ne respectent pas la modèle mot tab mot tab mot
    #----------------------------------------------------------------------------------
    if ($ligne =~ /^[^\t]+\t[^\t]+\t[^\t]+$/) {
	#-------------------------------------------
	# Suppression du caractère de saut de ligne
	chomp($ligne);
	#-------------------------------------------
	# Remplissage des listes
	@malignesegmentee = split(/\t/, $ligne);
	push(@listedetokens, $malignesegmentee[0]);
	push(@listedelemmes, $malignesegmentee[1]);
	push(@listedepos, $malignesegmentee[2]);
	#-------------------------------------------
    }
}
close(FICTAG);
#-----------------------------------
# on va maintenant parcourir les POS
# et les TOKENS en //
#----------------------------------------------------------------------------------------
# 1. on cree une liste tmp des POS que l'on va parcourir en supprimant le premier element 
#    a chaque fois
#----------------------------------------------------------------------------------------
my @tmplistedespos=@listedepos;
my $indice=0;
my $i=0;
while (my $a =shift(@tmplistedespos)) 
{
	foreach my $patron (@listedespatrons) 
	{
	
	#-----------------------------------
	# on segmente le patron pour connaitre
	# son premier element
	my @listedeterme=split(/\#/,$patron);
	#-----------------------------------
	# on teste si l'element courant POS correspond au premier element du patron...
	if ($a=~/$listedeterme[0]/) 
	{
	    # si c'est OK...
	    # on regarde maintenant s'il y a correspondance pour la suite...
	    my $verif=0;
	    for (my $i=0;$i<=$#listedeterme-1;$i++) 
		{
			if ($tmplistedespos[$i]=~/$listedeterme[$i+1]/) { 
				#Le suivant est bon aussi...
				$verif++ ;
			}
			else {
				# ici : $tmplistedespos[$i] differe de $listedeterme[$i+1]...
			}
		}
		#------------------------------------------------------------------------
		# si verif est egal au nb d'element du patron c'est qu'on a tt reconnu... 
		# on imprime les tokens en // aux POS : astuce $indice permet de garder le 
		# le // entre POS et TOKEN....
		#------------------------------------------------------------------------
		if ($verif == $#listedeterme) { 
	
		#print "Correspondance sur $patron \n";
		for (my $i=0;$i<=$#listedeterme;$i++) 
		{
			print FILEOUT $listedetokens[$indice+$i]," ";
			
			
		}
		print FILEOUT "\n";

	    }
	}
    }
    $indice++;
    # on avance dans la liste des POS et des TOKEN en //
}
close(FILEOUT);

										

Résultats d'exécution de programme Perl d'extraction des différents patrons issus de Treetagger et Cordial

Nous présentons les différents fichiers de sortie de l'exécution des programmes par rubrique

Rubrique NOM-ADJ Treetagger NOM-PREP-NOM Treetagger Cordial
A la Une fichier-1-1 fichier-1-2 fichier-1-3
International fichier-2-1 fichier-2-2 fichier-2-3

Extraction des patrons par une transformation XSLT

Il s'agit d'extraire les patrons sur les sorties au format XML de l'étiquetage effectué précédemment via Treetagger, issues de la Boîte à outils Série 2. Nous avons utilisé une requête XPath dans une feuille de style XSLT pour construire la liste des patrons visés.

Voici la feuille de style XSLT pour l'extraction du patron NOM-ADJ :


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
exclude-result-prefixes="xs" 
version="3.0">
	<xsl:output method="html" encoding="UTF-8"/>
	<xsl:template match="/">
		<html>
		<head>
				<title>Extraction patron NOM-ADJ</title>
			</head>
			<body bgcolor="#81808E">
				<table align="center" width="50%" bgcolor="white" bordercolor="#3300FF" border="1">
					<tr bgcolor="black">
						<td width="90%" valign="top">
							<font color="white">
								<h1>Extraction de patron <font color="red">
										<b>NOM</b>
									</font>
									<font color="blue">
										<b>ADJ</b>
									</font>
								</h1>
							</font>
						</td>
					</tr>
					<tr>
						<td>
							<blockquote>
								<xsl:apply-templates select="./PARCOURS/ETIQUETAGE/file/element"/>
							</blockquote>
						</td>
					</tr>
				</table>
			</body>
		</html>
	</xsl:template>
	<xsl:template match="element">
		<xsl:choose>
			<xsl:when test="(./data[contains(text(),'NOM')]) and (following-sibling::element[1][./data[contains(text(),'ADJ')]])">
				<font color="red">
					<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="blue">
					<xsl:value-of select="./data[3]"/>
				</font>
				<br/>
			</xsl:when>
		</xsl:choose>
	</xsl:template>
</xsl:stylesheet>

										

Voici un extrait du résultat de la transformation XSLT



Cliquer sur le lien pour visualiser le résultat total de la transformation XSLT sortie fichier HTML

Liens vers les scripts Perl :

extract-patron-cordial.pl
extract-patron-NOM-ADJ-treetagger.pl
extract-patron-NOM-PREP-NOM-treetagger.pl