A Propos

Présentation

Nous avons réalisé ce projet dans le cadre de notre cours Projet Encadré de M1, Traitement automatique des langues. Nous sommes XUE Qing (Paris X) et ZHOU XiaoFang (Paris X). Nous voulons remercie à Serge FLEURY et Jean-Michel DAUBE qui nous ont beaucoup aidé pour notre projet tout au long de ce semestre.

 

Initiation du projet

nous avons travaillé sur un corpus de fils RSS téléchargé du site du journal Le Monde et le langage de programmation est Perl.

Ce projet contiendra dans l’ensemble 4 étapes:
=> BÀO1: Extraire le texte de la masse de données
=> BÀO2: Étiquetage morphosyntaxique de ce texte
=> BÀO3: Extraction de patrons morphosyntaxiques en cours
=> BÀO4: Représentation graphique des différents patrons qu’on aura extaits
La relation entre les 4 BÀO est illustrée comme suit:

BÀO 1

1. Objectif et méthode

Nous travaillons prioritairement sur le corpus de test. Nous commençons par l’écriture du script de Perl.eux rubriques numérotés respectivement en 3208 et 3210 dans le corpus de fils RSS téléchargé du site du journal Le Monde 2017. Pour réaliser cet étape de l’opération, les deux solutions suivantes sont proposées:

— Pur Perl avec l’expression régulière

— Perl avec la bibliothèque XML::RSS.

2. Éléments de base

Les fichiers d’entré sont les fils RSS et les sorties de cet étape sont un text brut ‘$fichier.txt’ et un XML ‘$fichier.xml’ qui contiennent respectivement les contenus extraits tels que le titre et la description.

3. Écriture du script en pur Perl

3.1 Perl-1

Nous travaillons prioritairement sur le corpus de test. Nous commençons par l’écriture du script de Perl.

Premièrement, pour ouvrir et fermer le fichier, on propose le script suivant:

Ensuite, pour afficher les lignes du fichier contenant le motif, on recourt au script suivant:

Dans ce script, $ARGV[0] est le motif à chercher. La boucle consistant en while et if sert à  lire ligne par ligne le fichier. Si la ligne lue contient le motif, on imprime la ligne.
Mais pour extraire le motif dans un fichier XML, il se peut qu’il existe des problèmes suivants:
—> le motif est réparti à plusieurs lignes, le programme risque de ne pas bien fonctionner.
—> le fichier n’est pas propre, il faut le nettoyer.
—> le problème d’encodage
Afin de résoudre les problèmes ci-dessus, on propose les solutions suivantes:
—> Il faut mettre les contenus du texte en une même ligne. À cet égard, nous devons rendre le texte sorti propre. Donc, il faut supprimer tous les ‘\n’ dans le texte, soit $ligne=~s/\n//. Pour les tabulation, on supprime les blanc début la balise, soit $ligne=~s/^+//. Parmi lesquels, ‘~s’ sert à remplacer, et ‘g’ est utilisé pour assurer que la lecture des lignes peut passer consécutivement. Et elle n’est pas bloquée sur place. Ensuite, on a envie de coller les lignes de gauche à droite, soit $ensemble = $ensemble. $ligne

—> Pour chercher les contenus visés entre les balises tels que <title></title> et <description> et </description>, on établie la boucle while avec l’expression régulière est illustrée ci-après:

while ($ensemble=~/<title>[^<]*?\/title>/g){
print «titre:», $1, "\n"
}

Pour extraire la description du texte, on utilise la commande suivante:

Avec les commandes ci-dessus, on fait sortir qui conforme aux expressions ([^<]*?) entre les balises ‘title’ et ‘description’ et on imprime le titre et la description


3.2 Perl-2

Objectif 1: Extraire le texte des fichiers RSS

A partir le script précédent, nous devons ajouter les contenus ci-après:
— parcourir les arborescences de répertoires.
— extraire en même temps le titre et la description de chaque item
— produire en sortie 2 fichiers qui pourraient avoir l’allure suivante: TXT et XML
— nettoyer les données.


Objectif 2: Extraire le texte de tous les fichiers RSS de l’arborescence du corpus de test, et produire 2 sorties: version TXT brut et version XML.

Pour réaliser les objectifs ci-dessus, nous écrivons le script suivant, et nous l’expliquerons comme suit: Pour réaliser les objectifs ci-dessus, nous écrivons le script suivant, et nous l’expliquerons comme suit:
1. my $rep =  " $ARGV[0] ";
$rep=~ s/[\/]$//;
On déclare le repertoire dans lequel on va aller chercher les fichiers à traiter et assure que le nom du répertoire ne se termine pas par un ‘/‘.
2. Déclarer les variables pour les sorties: $rubrique =  « $ARGV[1] » qui peut renvoyer aux sorties différentes, soit sortie_$rubrique.txt, soit sortie_$rubrique.xml.
3. ouvrir les fichiers en encodage utf8:
open(FILEOUT1, " >:encoding(utf8) ", " sortie_$rubrique.txt ");
close FILEOUT1;
open(FILEOUT2, " >:encoding(utf8) ", " sortie_$rubrique.xml ");
4. Trouver des informations dans les fichiers xml
— la racine: print FILEOUT2 " <PARCOURS>\n ";
— les datas extraits et traités entre les balises <FILTRAGE></FILTRAGE>: print FILEOUT2 " <FILTRAGE>\n ";
5. fermer les fichiers avec la commande close FILEOUT1; et close FILEOUT2;
Ensuite, on devons parcourir l’arborescence des fichiers.
1. la variable $path sert à supprimer le premier élément du tableau@_ et à faire le nettoyage.
my $path = shift (@_);
2. ouvrir le répertoire. La fonction opendir prend deux arguements: DIR et $path:
opendir(DIR, $path) or die « can’t open $path: $!\n »;
3. déclarer la variable @files, la fonction readdir va lire tous les contenus dans le répertoire
my @files = readdir(DIR);
4. Fermer le répertoire:  closedir(DIR);
Pour traiter tous les fichiers dans le répertoire qu’on vise, on continue le script qui consiste des boucles:
1. foreach my $file (@files) {     : déclarer la variable $file qui représente le fichier dans le tableau @files
2. passer au prochain fichier, soit au répertoire courant, soit au répertoire parent. Et construire le chemin relatif
next if $file =~ /^\.\.?$/;
$file = $path.  " / ".$file;
Si c’est un répertoire, on descend dans l’arborescence

if (-d $file) { #si c’est un repertoire
print " <NOUVEAU REPERTOIRE> ==> " ,$file, "\n ";
&parcoursarborescencefichiers($file);#recurse!
print « <FIN REPERTOIRE> ==> " ,$file, "\n" »;
Si c’est un fichier XML, on ouvre le fichier en encodage utf8 dans lequel sont stockée les données.
if (-f $file) {
if ($file =~ m/$rubrique.+\.xml$/)
{

Si c’est un fichier XML, on ouvre le fichier en encodage utf8 dans lequel sont stockée les données

if (-f $file) {
if ($file =~ m/$rubrique.+\.xml$/)
{
my $ensemble= " ";
open(FILEIN, " <:encoding(utf8) ", $file);
open(FILEOUT1, " >>:encoding(utf8) ", " sortie_$rubrique.txt ");
open(FILEOUT2, " >>:encoding(utf8) ", " sortie_$rubrique.xml ");

Ensuite, on établit un boucle ‘while’ pour lire les lignes du fichier. On supprime le dernier caractère \n ou \r pour mettre tous les lignes en une seule ligne,

while (my $ligne= <FILEIN>)
{
chomp $ligne; #$ligne=~s/^ +//;$ligne=~s/ $//;
$ensemble = $ensemble . $ligne ;
}

Deuxième boucle ‘while’ sert à sauvegarder les contenus entre les balises <title> </title>; <description> </description>
et aussi les blancs au début et ceux entre balises, si bien qu’on arrive parcourir le fichier à la recherche des titres.
while($ensemble=~ m/<item> *<title>(.*?)<\/title>.*?<description>(.*?)<\/description>.*?<\/item>/g)


3. Nettoyer le texte

while (my $ligne = <$fichier>){     # lecture ligne par ligne du fichier ouvert
chomp $ligne;
# suppression du retour à la ligne sur la ligne en cours
$ligne =~ s/\r//g;
# suppression du retour à ligne de type windows
$ligne =~ s/&#39;/’/g;
# nettoyage de certains caractères écrits sous forme d’entités
$ligne =~ s/&#34;/ »/g;
# nettoyage de certains caractères écrits sous forme d’entités

 

4. XML::RSS

Objectif:

—Extraire le texte des fichiers RSS via la bibliothèque Perl XML::RSS et produire 2 sorties: version TXT brut et version XML.

4.1 Install XML::RSS

La commande d’installation du dictionnaire XML::RSS est:
$ sudo perl -MCPAN -e ‘install XML::RSS’
En même temps, on introduit aussi un des modules de Perl Unicode::String.

 

4.2 Écriture du script

Tout d’abord, on considère l’extraction du texte d’un seul fichier RSS via le dictionnaire RSS. Le script est suivant:

Ensuite, pour parcourir tous les arborescences, il faut ajouter une boucle de parcours dans le script précédent, considérons le capture d’écran ci-dessous:

5. Script complet et résultats

Script_Perl_BAO1

Script_BAO1_XML.RSS

Resultat-BAO1/sortie_bao1_3210.txt

Resultat-BAO1/sortie_bao1_3208.txt

Resultat-BAO1/sortie_bao1_3210.xml

Resultat-BAO1/sortie_bao1_3208.xml

BÀO 2

BÀO2: Étiquetage 

1. Objectif


Le but de BÀO2 est d’étiqueter les sorites du fichier brut TXT et du fichier XML. Pour le premier, on utilise le logiciel Cordial pour l’étiquetage, tandis que pour le dernier, nous devons emprunter l’outil Treetagger. On intégre le programme d’étiquetage dans le programme construit pour la BÀO1.

2. Cordial et Treetagger


Avant d’étiqueter les sorties brutes TXT avec Cordial, nous devons convertir les fichiers en utf-8 en iso-8859-15, puisque le logiciel Cordial ne lit que les fichiers qu’en iso. Quant à l’étiquetage avec le Treetagger pour les fichiers XML, on prépare le fichier de langue et les programmes qui servent à faire fonctionner le Treetagger:
— le programme ‘tree-tagger’
— fichier de langue: ’french-oral-utf-8.par'
— ‘tokenise-utf8.pl’ est utilisé pour segmenter le fichiers en tokens.
— ‘treetagger2xml-utf-8.pl’ sert à convertir le format du fichier issu de l’étiquetage vers XML.
Ensuite, il faut mettre tout les documents concernés et les programmes dans le même répertoire.


3. Script


3.1 Capture d’écran

À propos du script inséré dans le script de BÀO1, on écrit le script suivant:

3.2 Compréhension du script


A.
On vide complètement le tableau avec les arguments suivants:
my $var1 = shift(@_);
my $var2= shift(@_);
B. Ici, il faut intégrer les programmes
— pour tokeniser le texte
— pour transformer ce dernier en XML
C. Le programme de tokenisation a besoin d’un fichier en entrée. Donc il va falloir le créer .
open (OUT, »>>:encoding(utf8)","titre_tmp.txt");
open (description, »>>:encoding(utf8)","description_tmp.txt");
D. La commande ‘system’ permet de lancer sur le système d’exploitation qu’on travaille (MacOs).
E. L’étiquetage
system(‘perl tokenise-utf8.pl titre_tmp.txt | ./tree-tagger -lemm -token -no-unknown french-oral-utf-8.par > titre_etiquette.txt’);
Ensuite, le programme suivant rajoute l’extension .xml automatiquement.
System(‘perl treetagger2xml-utf8.pl titre_etiquette.txt utf8’);
E. Ouvrir les fichiers créé en format XML pour extraire ces données et les transformer dans une chaîne de caractères pour les mettre par la suite dans le fichier globale.
open (fichierxml,"<:encoding(utf8)","titre_etiquette.txt.xml");
open (fichierxml, "<:encoding(utf8) ","description_etiquette.txt.xml");

4. Script complet et exemple du résultat

Script_bao2.pl

sortie_3208.txt titre_etiquette_3208.txt description_etiquette_3208.txt

xml-sortie_3208.xml titre_etiquette.txt_3208.xml description_etiquette.txt_3208.xml

BÀO 3

BAO3. Extraction des patrons

Le BAO3 vise à extraire des patrons à partir du fichier généré par Codial.
Il existe deux solutions proposées: pur Perl avec les expressions régulière et XML::PATH.
Les patrons syntaxiques à extraire sont:
NOM ADJ
NOM PRP NOM

1. Solution1: Avec les expressions régulières


Avec les sorties étiquetés de BAO2, nous les prenons comme les fichiers entrés. Pour extraire les patrons selon des patterns morpho-syntaxiques souhaité, soit NOM ADJ et NOM PRP NOM.
L’entrée consiste de deux fichiers:
— les textes bruts étiquetés via Cordial issues de la BAO2. Il faut prendre le bon paramétrage pour étiqueter avec Cordial permettant d’avoir forme lemme et catégorie. Sinon, il y aura des problèmes pour la lecture du fichier. Par exemple, au début, nous avons créé un fichier cordial avec une colonne ‘catégorie’ et une colonne ‘inexploitable’ par le script. Notre lancement du script est bloqué.

. À l’aide de M. Fleury, nous savons si le fichier cordial n’est pas en bonne forme, il faut modifier aussi les codes dans le script qui servent à lire et extraire les éléments de chaque ligne dans le fichier cordial. Par exemple.

Cette partie du code est très importante pour régler le problème que nous avons rencontré.
Ensuite, nous avons à nouveau étiqueté nos textes bruts avec le Cordial. Le fichier cordial s’illustre comme suit:

— un fichier contenant les motifs tels que ‘NC[^\s]+ ADJ[^\s]+’, ‘NC[^\S]+ PREP NC [^\S]+’.

2. Solution 2: avec XQuery

Pour extraire les patrons indiqués, nous construisons des requête XQuery.

3. Les fichiers et les scripts

sortie_3208_iso.cnr

sortie_3210_iso.cnr

 NC_PREP_NC_3208.txt NC-PREP-NC-3210.txt

NC-ADJ-3208.txt NC-ADJ-3210.txt

Script-extract-patron-treetagger.pl

Script-BAO3/CORDIAL.pl

BÀO 4

BAO4: Textes aux graphes

Pour visualiser en graphe les patrons syntaxiques issus de l’extraction par BAO3, le programme ‘patron2graphedemots-unix’ permet de donner les liens entre les mots entre les mots faisant des résultats en ajoutant la possibilité de se concentrer sur certains mots.
Le programme prend trois arguments: l’encodage des fichiers d’entrée, le fichier contenant les résultats de la recherche des patrons morphosyntaxiques et un fichier contenant la recherche d’un motif particulier. La commande est suivante:

Au cours de notre travail, nous avons rencontré une difficulté pour visualiser le graphe. Selon la proposition de M.Fleury, nous savons que pour le système MacOS, il faut installer la bonne version de XQuartz pour faire fonctionne le programme.

1. Graphes

1.1 Rubrique 3208


— Partron: NC-ADJ

Requête des motifs
(1) social (173 occurrences)

Dans notre fichier nommé ‘NC-ADJ-3208.txt’, il existe 5 formes lexicales qui consistes du morphème ‘social’. Ils sont ‘sociale’, ‘social’, ‘sociales’, ’socialiste’ et ‘socialistes’. Selon ce graphe, le mot ‘socialiste’ est beaucoup combiné avec le mot ‘ministre’, 36 fréquences. À partir de cela, nous supposons que les actualités dans la rubrique 3208 concernent beaucoup les socialistes. De plus, les mots ‘sécurités’ (7 occurrences), ‘démocrate’ (4 occurrences) et fédération (9 occurrences) montrent le sujet principal dans nos actualités visées.

(2) sexuel (121 occurences)

.

Nous faisons une requête sur le morphème ‘sexuel’, car cela fait aussi partie du sujet concernant le social. Selon le graphe ci-dessus, les mots ‘agression’ (9 occurrences), ‘violences’ (9 occurrences), ‘atteinte’ (10 occurrences) et ‘abus’ (14 occurrences) sont beaucoup liés au mot ‘sexuel’.

(3) gouvernement (81 occurrences)

Nous avons 7 formes lexicales concernant le mot ‘gouvernement’: gouvernement, gouvernemental, gouvernementale, progouvernemental, gouvernements, intergouvernemental, gouvernementales. Les combinaisons fréquentes sont ‘britanique’ (7 occurrences), ‘espagnol’ (6 occurrences) et ’roumain’ (6 occurrences).

1.2 Rubrique 3210

— Partron: NC-ADJ

Requêtes des tokens:
1) social (58 occurrences)

Dans la rubrique 3210, le mot ‘social’ est moins fréquent que celui dans la rubrique 3208, 58 occurrences contre 173 occurrences. La combinaison plus fréquente, c’est le mot ‘réseau’ (10 occurrences).

1) sexuel (49 occurrences)

Également, le mot ‘sexuel’ est aussi moins fréquent que celui dans la rubrique 3210. Le mot ‘agressions’ est beaucoup associé au terme ‘sexuel’.

3) gouvernement ( 125 occurrences)

Cependant, le mot ‘gouvernement’ est plus fréquent que celui dans la rubrique 3208, 125 occurrences contre 81 occurrences. Les mots combinés sont aussi différents. Les fréquents sont ‘social’ (11 occurrences), ‘fédéral’(10 occurrences) et ‘éthique’. Cela montre que le pivot du travail du gouvernement sont étroitement lié à ces domaines.

Conclusion

Notre projet a réussi à parcourir le corpus Le Monde RSS de l’année 2017 qui consiste de plusieurs répertoires en rubrique, à étiqueter les textes brutes avec le programme Cordial et les XML avec le Treetagger et à extraire les patrons NC-ADJ ET NC-PREP-NC selon les fichiers sorties des opérations précédentes. Enfin, avec le programme ‘patron2graphedemots-unix’ ,nous avons bien dessiné les graphes et établi les relations des motifs dans le corpus choisi. Ce travail nous fait comprendre le langage Perl/XQuery. Et cela nous inspire d’avoir des idées pour réaliser un projet indépendant. De plus, quant à notre projet présent, c’est très utile pour la statistique et l’analyse en linguistique.

Contact

 

 

 

Copyright © 2018.All rights reserved.