Boîte à Outils 2

Etiquetage avec TreeTagger et UDPipe

Image

ETAPES :
1) Etiqueter le fichier xml avec TreeTagger
2) Etiqueter le fichier txt avec UDPipe

EN ENTREE :
Même entrée que pour la BAO1.

EN SORTIE :
On a six fichiers en sortie : un corpus txt contenant les titres et descriptions comme dans la BAO1, un precorpus pour l'étiquetage TreeTagger au format xml, un fichier intermédiaire après cet étiquetage (qui sert au corpus suivant), un corpus étiqueté par TreeTagger au format xml, un corpus udpipe (corpus étiqueté par UDPipe) au format conll, un corpus udpipe au format xml.
Seul les fichiers non intermédiaires qui nous seront utiles pour la suite sont montrés ci-dessous (à titre d'exemple, la rubrique peut varier)

Langage Nom de fichier Téléchargement
Perl perl-corpus-titre-description-3208.xml fichier_treetagger.xml
Perl perl-corpus-titre-description-3208.udpipe.xml fichier.udpipe.xml

SCRIPTS :
Vous pouvez également télécharger les scripts commentés de la BAO3 ci-dessous.

Langage Ligne de commande Téléchargement
Perl perl BAO2.pl dossier_arborescence rubrique BAO2.pl
Python python3 BAO2.py dossier_arborescence rubrique BAO2.py

PERL

Modification 1/3 : Nouveau sous-programme pour l'étiquetage TreeTagger
Pour que l'étiquetage TreeTagger fonctionne, il a fallu créer un precorpus xml avec un token par ligne. Ce résultat a été créé par le sous-programme 'segmentationTD' qui, à l'aide de fichiers tampons et le programme tokenise-utf8.pl offert par TreeTagger, segmente chaque titre et description qu'il reçoit en argument. Ainsi, le sous-programme 'etiquetage_TreeTagger' va utiliser ce precorpus afin de fournir un fichier xml étiqueté grâce aux programmes 'tree-tagger.exe' puis 'treetagger2xml-utf8-meilleur.pl'.

#-----------------------------------------------------------
### --- DEBUT DE LA MODIFICATION --- ###
# Trois nouveaux sous-programmes :

# Un sous-programme permettant d'avoir un token par ligne pour que TreeTagger puisse correctement annoter
# Cette segmentation sera stockée dans un fichier nommé "perl-precorpus-titre-description.xml"
sub segmentationTD{
	my ($arg1, $arg2)=@_;
	# ecriture des données textuelles dans un fichier_tampon, tokeniser ce fichier et récupérer les données
	open my $tmp1, ">:encoding(UTF-8)", "fichier_tampon1.txt";
	print $tmp1 $arg1;
	close $tmp1;
	system("perl ./Ressources_treetagger/tokenise-utf8.pl fichier_tampon1.txt > fichier_tampon2.txt");
	undef $/; #lecture globale du fichier
	open my $tmp2, "<:encoding(UTF-8)", "fichier_tampon2.txt";
	my $titresegmente=<$tmp2>
	close $tmp2;
	open my $tmp1, ">:encoding(UTF-8)", "fichier_tampon1.txt";
	print $tmp1 $arg2;
	close $tmp1;
	system("perl ./Ressources_treetagger/tokenise-utf8.pl fichier_tampon1.txt > fichier_tampon2.txt");
	undef $/; #lecture globale du fichier
	open my $tmp2, "<:encoding(UTF-8)", "fichier_tampon2.txt";
	my $descriptionsegmente=<$tmp2>
	close $tmp2;
	#on remet les choses en ordre
	$/="\n";
	return $titresegmente, $descriptionsegmente
}

# Un sous-programme qui prend en entrée le precorpus XML créé par segmentationTD
sub etiquetage_TreeTagger {
	# Etiquetage TreeTagger avec les ressources Treetagger et le precorpus xml
	system("./Ressources_treetagger/tree-tagger.exe -lemma -token -no-unknown -sgml ./Ressources_treetagger/french-utf8.par perl-precorpus-titre-description-$rubrique.xml > perl-corpus-titre-description-$rubrique");
	# Conversion du résultat TreeTagger au format xml avec un programme de conversion donné déjà créé
	system("perl ./Ressources_treetagger/treetagger2xml-utf8-meilleur.pl perl-corpus-titre-description-$rubrique UTF8");
}

Modification 2/3 Nouveau sous-programme pour l'étiquetage UDPipe
En ce qui concerne UDPipe, l'étiquetage se fait en prenant un txt en entrée dans le sous-programme 'etiquetage_UDPipe'. A l'aide des ressources UDPipe 'udpipe.exe', l'étiquetage exécuté se présente sous forme d'un conll. Pour servir aux BAOs suivantes, un conversion en xml est de plus réalisée.

# Un sous-programme qui prend en entrée un texte brut contenant un titre et une description
sub etiquetage_UDPipe {
	# Etiquetage UDPipe avec les ressources UDPipe et le corpus txt
	system("./UDpipe/udpipe-1.2.0-bin/bin-win64/udpipe.exe --tokenize --tag --parse --tokenizer=presegmented ./UDpipe/modeles/french-sequoia-ud-2.5-191206.udpipe perl-corpus-titre-description-$rubrique.txt > perl-corpus-titre-description-$rubrique.udpipe"); 
	# On lance le script "udpipe2xml-version-sans-titrevsdescription-v2.pl" qui va créer un nouveau fichier 
	# à partir du fichier udpipe qu'on vient de créer, passant du format .conll à .xml
	# Ce fichier sera utile pour nos deux prochaines boîtes à outils
	system("perl ./UDPipe/udpipe2xml-version-sans-titrevsdescription-v2.pl perl-corpus-titre-description-$rubrique.udpipe");
}

### --- FIN DE LA MODIFICATION --- ###
#-----------------------------------------------------------

Modification 3/3 : Nouvelles instructions dans le programme principal
Ces nouveaux sous-programmes doivent bien évidemment être appelés dans le programme principal pour être exécutés. De plus, les fichiers tampons sont supprimés à la fin du programme, et les fichiers créés, déplacés dans leur dossier de sortie dédié.

...
# On ferme les deux fichiers créés
close $output_txt;
close $output_xml;


### --- DEBUT DE LA MODIFICATION --- ###
# 1) Annotation du fichier perl-corpus-titre-description-$rubrique.txt par UDPipe
&etiquetage_UDPipe;

# 2) Annotation du fichier perl-precorpus-titre-description-$rubrique.xml par TreeTagger
&etiquetage_TreeTagger;

# On supprime les fichiers tampons
unlink("fichier_tampon1.txt");
unlink("fichier_tampon2.txt");
# On met les fichiers de sortie dans le dossier de sortie BAO2 dédié
move("perl-corpus-titre-description-$rubrique.txt", "BAO2") or die "Erreur 1 $!";
move("perl-precorpus-titre-description-$rubrique.xml", "BAO2") or die "Erreur 2 $!";
move("perl-corpus-titre-description-$rubrique", "BAO2") or die "Erreur 3 $!";
move("perl-corpus-titre-description-$rubrique.xml", "BAO2") or die "Erreur 4 $!";
move("perl-corpus-titre-description-$rubrique.udpipe", "BAO2") or die "Erreur 5 $!";
move("perl-corpus-titre-description-$rubrique.udpipe.xml", "BAO2") or die "Erreur 6 $!";
### --- FIN DE LA MODIFICATION --- ###

# On sort du programme
exit;

PYTHON

Modification 1/3 : Nouvelle fonction pour l'étiquetage TreeTagger
Le script Python suit exactement la même logique que le script Perl, en créant également les mêmes fichiers tampons ou intermédiaires nécessaires pour l'étiquetage TreeTagger et en appelant et exécutant les mêmes programmes via le système et les commandes bash.

# Un sous-programme qui prend en entrée le precorpus XML créé par segmentationTD
def etiquetage_TreeTagger():
	# Etiquetage TreeTagger avec les ressources Treetagger et le precorpus xml
	os.system(f"./Ressources_treetagger/tree-tagger.exe -lemma -token -no-unknown -sgml ./Ressources_treetagger/french-utf8.par python-precorpus-titre-description-{rubrique}.xml > python-corpus-titre-description-{rubrique}")
	# Conversion du résultat TreeTagger au format xml avec un programme de conversion donné déjà créé
	os.system(f"perl ./Ressources_treetagger/treetagger2xml-utf8-meilleur.pl python-corpus-titre-description-{rubrique} UTF8")

Modification 2/3 : Nouvelle fonction pour l'étiquetage UDPipe
Idem pour l'étiquetage UDPipe qui reprend la même logique du programme Perl mais en Python. Attention, comme dit dans la BAO1, ces sous-programmes sont impérativement déclarés avant la fonction principale en Python.

# Un sous-programme qui prend en entrée un texte brut contenant un titre et une description
def etiquetage_UDPipe():
	# Etiquetage UDPipe avec les ressources UDPipe et le corpus txt
	os.system(f"./UDpipe/udpipe-1.2.0-bin/bin-win64/udpipe.exe --tokenize --tag --parse --tokenizer=presegmented ./UDpipe/modeles/french-sequoia-ud-2.5-191206.udpipe python-corpus-titre-description-{rubrique}.txt > python-corpus-titre-description-{rubrique}.udpipe")
	# Comme pour perl, on lance le script "udpipe2xml-version-sans-titrevsdescription-v2.pl" 
	# pour avoir un fichier conll sous forme xml
	# Ce fichier sera utile pour nos deux prochaines boîtes à outils
	os.system(f"perl ./distrib-udpipe-1.2.0-bin/udpipe2xml-version-sans-titrevsdescription-v2.pl corpus-annotation-ud-{RUBRIQUE}.udpipe")

Modification 3/3 : Nouvelles instructions dans le programme principal
Comme pour Perl, on appelle les nouvelles fonctions créés, on supprime les fichiers tampons et on déplace les fichiers obtenus (avec la même subtilité énoncé dans la BAO1).

if __name__ == "__main__":
        ...
        with open(fichier_txt, "w", encoding="utf-8") as output_txt:
            with open(fichier_xml, "w", encoding="utf-8") as output_xml:
		...
                output_xml.write("</corpus>\n")
                
                ### --- DEBUT DE LA MODIFICATION --- ###
                etiquetage_TreeTagger()
                etiquetage_UDPipe()
                # On supprime les tampons
                os.remove("fichier_tampon3.txt")
                os.remove("fichier_tampon4.txt")
                # On met les fichiers de sortie dans le dossier de sortie BAO2 dédié
                # On s'assure que si les fichiers existent, on les supprime avant de laisser place aux nouveaux 
                # (produit une erreur sinon)
                if os.path.exists(f"./BAO2/{fichier_txt}"):
                    os.remove(f"./BAO2/{fichier_txt}")
                if os.path.exists(f"./BAO2/{fichier_xml}"):
                    os.remove(f"./BAO2/{fichier_xml}")
                shutil.move(fichier_txt, "BAO2")
                shutil.move(fichier_xml, "BAO2")
                ### --- FIN DE LA MODIFICATION --- ###