Free HTML5 Bootstrap Template by FreeHTML5.co

Boîte à Outils 3 - Extraire des patrons Morphosyntaxiques du fil RSS du Monde

La troisième Boite à Outils vise à extraire des patrons Morphosyntaxiques à partir du fichier XML annoté par Treetagger ou UDPipe grâce à la boîte à Outils 2. Le cours du Document Structuré nous propose une autre approche basé sur les fiches de styles XSLT et sur XQuery.

Le script PERL

Le script pour extraire les patrons

Le script prend comme argument le fichier étiqueté par Treetagger, ici corpus-titre-description.xml, et les POS du patron recherché selon les étiquettes de Treetagger, par exemple PRP NOM VER.

my $fileatraiter=shift @ARGV;
my @PATRON=@ARGV;
open my $input, "<:encoding(utf-8)",$fileatraiter;
my @LISTE=<$input>;
close($input);

La première étape du script consite à en récupérer les arguments grâce à shift @ARGV. On stocke le reste des arguments dans une liste que l'on nomme PATRON. Ouvrir le fichier à traiter nous permet de le lire ligne par ligne.

On regarde ensuite si le POS du mot contenu dans la ligne traitée correspond au premier element de la liste PATRON. Si c'est le cas, on stocke le mot dans la variable terme et on regarde les lignes suivante dans la limite de la taille du patron. Si l'indice de la première ligne correspond toujours à 1 c'est praceque, grâce à la méthode shift, on enlève les lignes au fur et à mesure de la liste PATRON.

Si la ligne suivante correspond toujours au PATRON, on stocke dans la variable terme la valeur type="string" du mot traité, c'est à dire le troisième groupe de capture dans notre cas.

Si le PATRON est trouvé sur l'ensemble de sa longueur, c'est que le PATRON a été trouvé. On peut donc le noter dans un dictionnaire pour en tracer la fréquence d'apparition.

La variable nbTerme nous permet de conserver une trace du nombre de patrons Morphosyntaxiques trouvés dans l'ensemble du corpus.

while (my $ligne=shift @LISTE) {
	# si la ligne contenue dans $ligne correspond au premier du patron $PATRON[0]
	
	my $terme="";
	if ($ligne=~/<element><data type="type">$PATRON[0](:\w+)?<\/data><data type="lemma">[^<]+?<\/data><data type="string">([^<]+?)<\/data><\/element>/) {
		$terme=$terme.$2;
		my $longueur=1;
		my $indice=1;
		# alors il faut que je lise autant de ligne qu'il y a dans le patron et tester chaque terme du patron...
		while (($LISTE[$indice-1]=~/<element><data type="type">($PATRON[$indice])(:\w+)?<\/data><data type="lemma">[^<]+?<\/data><data type="string">([^<]+?)<\/data><\/element>/) and ($indice <= $#PATRON)) {
			$indice++;
			$terme.=" ".$3;
			$longueur++;
		}
		if ($longueur == $#PATRON + 1) {
			$dicoPatron{$terme}++;
			$nbTerme++;
		}
	}	
}
open my $fileResu,">:encoding(UTF-8)","patronMorphoSyntaxique.txt";
print $fileResu "$nbTerme éléments trouvés\n";
foreach my $patron (sort {$dicoPatron{$b} <=> $dicoPatron{$a} } keys %dicoPatron) {
	print $fileResu "$dicoPatron{$patron}\t$patron\n";
}
close($fileResu);

À la fin du traitement du fichier, on veut écrire les résultats dans un fichier texte que l'on nomme patronMorphoSyntaxique.txt. En entête, on écrit le nombre total de Patrons trouvés ( que l'on a retenu grâce à la variable nbTerme. On ecrit ensuite toutes les entrées du dictionnaire en les triant par leur clé (c'est à dire leur fréquence d'apparition).

Extrait du fichier patronMorphoSyntaxique.txt (50 premiers résultats).

23008 éléments trouvés
141	de l’Etat
108	du pays
103	de personnes
101	de prison
97	du monde
93	du gouvernement
84	de l’épidémie
81	de vaccination
81	en raison
76	de loi
74	de santé
72	en examen
70	à l’âge
67	du groupe
62	en ligne
62	du parti
61	à l’étranger
60	au sein
59	en place
58	en garde
54	du Sud
52	de sécurité
52	du président
51	en cause
51	des années
51	des droits
48	en vigueur
48	de l’intérieur
45	des mesures
43	à vue
42	de l’Union
41	de football
40	de travail
39	de l’ordre
37	avec sursis
36	du travail
34	de violences
34	des élections
34	des personnes
33	au pouvoir
33	de défense
33	de guerre
33	à cause
33	en matière
33	en cours
32	des dizaines
32	de l’homme
32	du vaccin
32	de vie

Le script pour extraire les relations

Le script prend comme le script pour extraire les patrons un argument pour le fichier étiqueté par Treetagger, ici corpus-titre-description.xml, et un autre pour la relation recherché selon les étiquettes de UDPipe, par exemple obj.

my $rep="$ARGV[0]";
my $relation="$ARGV[1]";
my %dicoRelation=();$/=""; 			
open my $IN ,"<:encoding(utf8)","$ARGV[0]";
while (my $phrase=<$IN>)

Comme dans le script récupérant les patrons Morphosyntaxiques, On doit d'abord récupérer les arguments du script depuis la liste @ARGV. Pour pouvoir lire le fichier d'entrée (corpus-titre-description.xml) paragraphe par paragraphe, il faut re définir $/ en "". On peut ensuite lire le fichier.

En lisant le fichier paragraphe par paragraphe, on peut rechercher si une des lignes du paragraphe contient la relation recherché. Si la relation est trouvée, il faut récupérer l'id du gouverneur et la forme du mot. On va ensuite comparer l'id du Gouverneur avec les lignes qui suivent si le gouverneur est avant la ligne traitée (c'est à dire que la postion du dépendant $posDep > $posGov que celle du gouverneur) ou avec les lignes précédentes dans le cas inverse. On va ainsi pouvoir récupérer la chaîne de caractère que constitue le gouverneur.

On veut ensuite mettre le patron dans un dictionnaire pour compter la fréquence d'apparition de ce patron particulier.

while (my $phrase=<$IN>) {
	my @LIGNES=split(/\n/,$phrase);	
	for (my $i=0;$i<=$#LIGNES;$i++) {
		# si la ligne lue contient la relation, on ira chercher le dep puis le gouv
		if ($LIGNES[$i]=~/<element><id>([^<]+)<\/id><data type="string">([^<]+)<\/data><data type="lemma">[^<]+<\/data><data type="type">[^<]+<\/data><data type="ID_GOV">([^<]+)<\/data><data type="relation">[^<]*$relation[^<]*<\/data><\/element>/i) {
			my $posDep=$1;
			my $posGouv=$3;
			my $formeDep=$2;
			# soit le gouv est avant le dep, soit après...
			if ($posDep > $posGouv) {				
				for (my $k=0;$k<$i;$k++) {
					if ($LIGNES[$k]=~/<element><id>$posGouv<\/id><data type="string">([^<]+)<\/data><data type="lemma">[^<]+<\/data><data type="type">[^<]+<\/data><data type="ID_GOV">[^<]+<\/data><data type="relation">[^<]+<\/data><\/element>/) {						
						my $formeGouv=$1;
						$dicoRelation{"$formeGouv $formeDep"}++;
					}
				}
			}
			else {
				for (my $k=$i+1;$k<=$#LIGNES;$k++) {
					if ($LIGNES[$k]=~/<element><id>$posGouv<\/id><data type="string">([^<]+)<\/data><data type="lemma">[^<]+<\/data><data type="type">[^<]+<\/data><data type="ID_GOV">[^<]+<\/data><data type="relation">[^<]+<\/data><\/element>/) {
						my $formeGouv=$1;
						$dicoRelation{"$formeGouv $formeDep"}++;
					}
				}
			}
		}
	}
}
close ($IN);
# on imprime la liste des couples Gouv,Dep et leur fréquence...
open my $fileResu,">:encoding(UTF-8)","relationMorphoSyntaxique.txt";
foreach my $relation (sort {$dicoRelation{$b}<=>$dicoRelation{$a}} (keys %dicoRelation)) {
	print $fileResu "$dicoRelation{$relation}\t$relation\n";
}
close($fileResu);

Pour finir, on veut inscrire les résultats dans un fichier relationMorphoSyntaxique.txt. Comme pour le script extrayant les patrons, on doit récupérer les clés et les valeurs du dictionnaire que l'on veut au préalable ordonner. On les inscrit ensuite dans le fichier.

Extrait du fichier relationMorphoSyntaxique.txt (50 premiers résultats).

7	Visualisez nombre
5	suivez progression
3	visualisez l’évolution
3	propose sélection
3	annoncé dimanche
3	recommande vaccin
3	vacciner se
3	annoncé mardi
3	l’épidémie où
2	dépasse cas
2	Vivez match
2	déclaré mardi
2	fait morts
2	focaliser nous
2	commander Station
2	obtenu droit
2	n’écarte restrictions
2	faire quoi
2	ouvert voie
2	interroge personnalité
2	prendre tête
2	ouvre voie
2	marqué Ils
2	parti Républicains
2	remporte slalom
2	dessinent plateau
2	annulés week-end
2	saisi tribunal
2	estimant qu’il
2	reste philo
2	réclame démission
2	payer millions
2	partagé vie
2	eu lieu
2	désigner candidat
2	requiert perpétuité
2	marqué vie
2	passe en
2	adopter projet
2	annoncé lundi
2	l’épidémie en
2	décembre conseil
2	bousculé mentalités
2	consacré vie
2	déclaré chef
2	durera minutes
2	fait appel
2	transformant passe
2	prendra fonctions
2	der Leyen

Projet réalisé par Eve Sauvage

En première année de Master Traitement Automatique des Langues