Présentation

Ce site contient l'ensemble des résultats obtenus lors la réalisation du projet du cours "Programmation et Projet encadré 2" dispensé par Serge Fleury et Jean-Michel Daube dans le cadre du master Traitement Automatique des Langues à l'INALCO.

Le projet vise à apprendre à utiliser les outils nécessaires au traitement d'un corpus composé de l'ensemble des fils RSS disponibles sur le site du journal Le Monde recueillis tous les jours de l'année 2020 à 19h. Nous avons constitué au fil du semestre 3 boîtes à outils réunissant les programmes successifs réalisés pour un traitement complet de notre corpus de travail. Ces programmes ont pour le but les tâches / les traitements suivants :

  • Extraction des données textuelles
  • Étiquetage des données extraites
  • Extraction des données étiquetées

Pour consultez chaque étape de ce projet, veuillez cliquer sur les boîtes à outils ci-dessous.

Boîte à outils n°1 : Extraction du texte


Objectif

Parcourir toute l'arborescence et extraire les contenus textuels de tous les fils (classement des textes extraits par rubrique).


Description

Le but de cette première étape est d'extraire, sur l'intégralité de l'arborescence des fils RSS, les contenus textuels pertinents pour notre projet, et de les concaténer en un seul fichier, dont on se servira pour les étapes suivantes.

Chaque fichier de sortie doit représenter le contenu d'une seule rubrique. Pour ce projet, les rubriques suivantes ont a été choisies :

  • 3208 : À la Une
  • 3210 : International
  • 3246 : Culture

Dans notre corpus de travail qui nous a été fourni, cette fois il y a deux formats disponibles – XML et TXT. Nous ne nous intéressons qu'aux fichiers XML de notre arborescence qui ont tous la même structure. Cela nous permet d'extraire les contenus de deux balises (<title> et <description>) sans problème.

Il existe plusieurs manières pour récupérer ces informations. Pour la méthode principale vue en cours, on a utilisé le langage Perl. En gros, ce programme se comporte comme la commande egrep Unix. Pour être plus précis, nous avons effectué le parcours récursif de l'arborescence pour accéder à chaque fichier, puis appliquer les traitements.

             
sub parcoursArborescence
{
   # Récupère le nom du répertoire fourni en argument de la fonction
   my $path = shift(@_);

   # Ouverture du répertoire et copie de son contenu
   opendir(my $DIRhandle, $path) or die "Can't open $path: $!\n";
   my @files = readdir($DIRhandle);
   closedir($DIRhandle);

   foreach my $file (@files)
   {
        next if $file =~ /^\.\.?$/;
        $file = $path."/".$file;
        # Si le contenu est un répertoire,
        # on rappelle la fonction de parcours
        if (-d $file)
        {
            &parcoursarborescencefichiers($file);
        }
        # Si le contenu est un fichier
        if (-f $file)
        {
            # Extraction du texte
            ...
        }
    }
}
             
          

Le traitement s'effectue à l'aide de la fonction qui intègre l'extraction par expression régulière. Les expressions régulières, étant le cœur du langage Perl, permettent de « matcher » les motifs qui nous intéressent. Cela s'avère très pratique quand on travaille sur les documents structurés !

Pour donc extraire le contenu textuel des balises <title> et <description>, on a implémenté le motif suivant :

          
            m/<item>.*?<title>(.+?)<\/title>.+?<description>(.+?)<\/description>.*?<\/item>/gs
          
        

Quand on parcourt l'ensemble du corpus, on peut mettre certaines « zones » dans les parenthèses pour les garder en mémoire. Tant que le programme rencontre des portions correspondant à ce qui est recherché, les motifs sont affectés aux variables $titre et $description. Les doublons sont évités grâce à une table de hashage dans laquelle on a rangé tous les titres rencontrés.

Ces informations sont ensuite « nettoyées » par les substitutions avec un sous-programme : on supprime les éléments inutiles (les caractères transcodés, les espaces insécables, guillemets simples dans les places d'apostrophes, etc.). Voici l'aperçu de cette fonction :

                  
sub nettoyage
{
  	my $texte = $_[0];
    $texte =~ s/^<!\[CDATA\[//;
  	$texte =~ s/\]\]>>$//;
    $texte =~ s/<.+?>//g; # supprime les succession de balises transcodées $lt; >
    $texte =~ s/&/et/g; # remplace les & par et
    $texte =~ s/ / /g; # remplace les   par des espaces 'normaux'
    $texte =~ s/&#39;/'/g; # remplace les apostrophes transcodées &#39;
    $texte =~ s/&#34;/"/g; # remplace les guillemets doubles &#34;
    $texte =~ s/ / /g; # remplace les espaces insécables par des espaces 'normaux'
    $texte =~ s/'/'/g; # remplace des guillemets simples par des apostrophes
  	return $texte;
}
                  
    		        

Le résultat nettoyé est ensuite écrit dans deux fichiers de sortie : un fichier texte et un fichier XML. Le programme se lance en mettant en argument le nom du répertoire à parcourir et l'identifiant de la rubrique qu'on souhaite traiter :

        
          perl ./BaO1/parcours-arborescence-BAO1-regex.pl 2020 3210
        
      

L'autre version du programme utilise le module Perl XML::RSS. Le principe est le même : on parcourt l'arborescence de la même façon, on traite les données de la même façon... Seulement l'extraction s'effectue différemment : avec le module on crée un parser sur le fichier et permet d'en parcourir aisément l'arborescence et extraire les contenus des balises <title> et <description>.

                  
use XML::RSS;

# Création d'un parser sur le fichier lu en paramètre
my $file = "$ARGV[0]";
my $rss = new XML::RSS;
$rss->parsefile($file);

# Exemple d'utilisation : extraction de la date
my $date=$rss->{'channel'}->{'pubDate'};
                  
               


Pour en avoir le cœur net, on a utilisé la fonctionnalité de Sublime Text – Compare Side-By-Side – pour comparer les deux sorties. Les fichiers générés par les deux méthodes sont identiques.


Scripts et résultats

Les programmes et les résultats obtenus pour chacune des trois rubriques sont disponibles ci-dessous.

Note : le temps de traitement est presque 10 fois plus long avec la méthode XML::RSS. Par contre, le script avec les expressions régulières fournit des résultats très rapidement, environ 0.4-0.3 secondes par rubrique sur notre machine. On va donc ensuite reprendre ce programme pour les BàO suivantes.

Boîte à outils n°2 : Étiquetage du texte


Objectif

Étiquetage automatique des contenus textuels extraits (Treetagger et UDpipe : annotation en morpho-syntaxe et en dépendances).


Description

Ici, la version du script élaborée dans la précédente boîte à outils a été complétée pour y ajouter une étape d'étiquetage réalisée sur les sorties. C'est grâce à l'étiquetage morpho-syntaxique et en dépendance qu'on pourra ensuite extraire des patrons morpho-syntaxiques et des relations dans la BàO 3.


TreeTagger et TreeTagger 2XML

Une procédure a été rajoutée dans le script pour effectuer l'étiquetage avec TreeTagger. Pour cela, nous avons lancé le programme grâce à la fonctionnalité system() de Perl qui permet de lancer une commande via la console de l'OS.

Le programme prend en paramètres un titre et une description récupérés et nettoyés précédemment (en format XML). Il effectue la même opération sur le titre et la description : il commence par écrire le contenu de la variable dans un fichier temporaire puis, après avoir tokenisé ce fichier grâce à un script Perl utf8-tokenize.perl, le soumet à TreeTagger.

system("perl -f ./outils/TreeTagger/cmd/utf8-tokenize.perl ./BaO2/sortie-regex_$rubrique.xml | ./outils/TreeTagger/bin/tree-tagger ./outils/TreeTagger/lib/french.par -token -lemma -sgml -no-unknown > ./BaO2/sortieTT-regex_$rubrique");

On utilise également un autre script Perl, treetagger2xml-utf8.pl, pour convertir le fichier généré par TreeTagger en fichier XML :

system("perl ./outils/TreeTagger/cmd/treetagger2xml-utf8.pl ./BaO2/sortieTT-regex_$rubrique utf8");

UDPipe

Nouveauté cette année, ce programme effectue l'étiquetage morpho-syntaxique et en dépendance et génère le résultat en format CONLL.

On le lance de la même façon que TreeTagger – via la fonction system() de Perl.

system("./outils/udpipe-master/src/udpipe --tokenize --tag --parse --tokenizer=presegmented ./outils/udpipe-master/models/french-sequoia-ud-2.5-191206.udpipe ./BaO2/sortie-regex_$rubrique.txt > ./BaO2/sortieUD-regex_$rubrique.txt");

Note : Pour que l'outil performe l'étiquetage correctement sur les élisions signalées par un apostrophe, il fallait ajouter une substitution de plus dans la procédure de nettoyage. Cette substitution remplace les caractères non standard (right single quotation mark U+2019) par un apostrophe standard typographique (U+0027).


TreeTagger vs UDPipe

Les étiquetages réalisés par TreeTaggers et par UDPipe sont assez différents en termes de format de sortie et les jeux d'étiquettes employés.

Avec TreeTagger (et bien sûr TreeTagger2XML), on obtient un résultat qu'on peut directement intégrer sous le format XML, ce qui permet ensuite d'utiliser tout un tas d'outils spécifiques aux documents XML (XPath, XSLT, XQuery, etc.).

Avec UDPipe on obtient un résultat sous format CoNLL. L'outil ne permet pas d'avoir des sorties sous format XML mais finalement cela ne pose pas de problème car les fichiers CoNLL peuvent être fouillés par d'autres manières (cf. la partie Python de BàO3). L'autre solution – transcoder le fichier CoNLL en format XML.

Les étiquetages sont difficilement comparables dans la mesure où les jeux d'étiquettes utilisés ne sont pas les mêmes. Le tagset du français de TreeTagger est constitué d'environ 33 étiquettes contre 17 étiquettes pour UDPipe (cf. le tagset universel d'après le manuel Universal Dependencies).

Les informations grammaticales et lexicales sur les catégories UDPipe sont stockées dans la colonne FEATS de la sortie CoNLL.

Enfin, contrairement à TreeTagger, la sortie UDPipe comprend les informations sur les dépendances syntaxiques.

Une rapide inspection visuelle permet de comparer les deux sorties (sans juger vraiment la qualité d'annotation bien sûr), souvent pas en faveur de TreeTagger.

Par exemple, TreeTagger reconnaît « 91 000 » comme étant deux nombres cardinaux (« 91 » et « 000 ») et UDPipe de son côté traite ce nombre comme une seule entité (malgré cet espace !).

Une autre chose que TreeTagger a du mal à faire, c'est la segmentation de « d' » et de « qu' ». L'outil les laisse souvent collés au substantif (cf. « d'uranium » dans l'exemple ci-dessous). UDPipe quant à lui fonctionne bien dans ce sens (si le caractère d'apostrophe est celui du U+0027, sinon les erreurs sont possibles).

Aperçu de la sortie UDPipe

                
# newpar
# sent_id = 3
# text = Nucléaire iranien : le stock d'uranium enrichi dépasse de cinq fois la limite autorisée.
1	Nucléaire	nucléaire	NOUN	_	Gender=Masc|Number=Sing	0	root	_	_
2	iranien	iranien	ADJ	_	Gender=Masc|Number=Sing	1	amod	_	_
3	:	:	PUNCT	_	_	1	punct	_	_
4	le	le	DET	_	Definite=Def|Gender=Masc|Number=Sing|PronType=Art	5	det	_	_
5	stock	stock	NOUN	_	Gender=Masc|Number=Sing	1	appos	_	_
6	d'	de	ADP	_	_	7	case	_	SpaceAfter=No
7	uranium	uranium	NOUN	_	Gender=Masc|Number=Sing	5	nmod	_	_
8	enrichi	enrichi	PRON	_	PronType=Int	9	obj	_	_
9	dépasse	dépas	VERB	_	Mood=Sub|Number=Sing|Person=1|Tense=Pres|VerbForm=Fin	5	acl:relcl	_	_
10	de	de	ADP	_	_	12	case	_	_
11	cinq	cinq	NUM	_	NumType=Card	12	nummod	_	_
12	fois	fois	NOUN	_	Gender=Fem|Number=Plur	9	obl:mod	_	_
13	la	le	DET	_	Definite=Def|Gender=Fem|Number=Sing|PronType=Art	14	det	_	_
14	limite	limite	NOUN	_	Gender=Fem|Number=Sing	9	nsubj	_	_
15	autorisée	autorisé	VERB	_	Gender=Fem|Number=Sing|Tense=Past|VerbForm=Part	14	acl	_	SpaceAfter=No
16	.	.	PUNCT	_	_	1	punct	_	SpacesAfter=\n
                
              

Aperçu de la sortie TreeTagger

                
<title>
<article>
<element><data type="type">NOM</data><data type="lemma">nucléaire</data><data type="string">Nucléaire</data></element>
<element><data type="type">ADJ</data><data type="lemma">iranien</data><data type="string">iranien</data></element>
<element><data type="type">PUN</data><data type="lemma">:</data><data type="string">:</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">stock</data><data type="string">stock</data></element>
<element><data type="type">NOM</data><data type="lemma">d'uranium</data><data type="string">d'uranium</data></element>
<element><data type="type">VER:pper</data><data type="lemma">enrichir</data><data type="string">enrichi</data></element>
<element><data type="type">VER:pres</data><data type="lemma">dépasser</data><data type="string">dépasse</data></element>
<element><data type="type">PRP</data><data type="lemma">de</data><data type="string">de</data></element>
<element><data type="type">NUM</data><data type="lemma">cinq</data><data type="string">cinq</data></element>
<element><data type="type">NOM</data><data type="lemma">fois</data><data type="string">fois</data></element>
<element><data type="type">DET:ART</data><data type="lemma">le</data><data type="string">la</data></element>
<element><data type="type">NOM</data><data type="lemma">limite</data><data type="string">limite</data></element>
<element><data type="type">VER:pper</data><data type="lemma">autoriser</data><data type="string">autorisée</data></element>
<element><data type="type">SENT</data><data type="lemma">.</data><data type="string">.</data></element>
</article>
</title>
                
              

Les deux outils semblent avoir des problèmes avec la détection de noms propres, mais on a quand même l'impression que TreeTagger se comporte mieux ici. Nous avons étudié les sorties pour la rubrique 3210 pour avoir une idée de ce qui se passe.

Par exemple, dans certains cas UDPipe reconnaît « Emmanuel Macron » comme PROPN, mais il y a quand même les occurrences de telles étiquettes comme DET (pour « Emmanuel », 34 fois dans 3210) et NOUN (pour « Macron », 23 fois). Sur la même rubrique, TreeTagger s'est trompé 26 fois sur «Macron» (en l'annotant comme NOM au lieu de NAM) et 17 fois sur « Emmanuel » (en le marquant comme ADJ au lieu de NAM). Pour être juste, les erreurs d'annotation du mot « Emmanuel » de TreeTagger sont liées aux problèmes de segmentations que l'on a décrit avant. Toutes les occurrences de « d'Emmanuel » et « qu'Emmanuel » sont étiquetées comme adjectifs.

Quant aux noms propres étrangers (on compare quand même la rubrique « International » ici !), la comparaison n'est pas en faveur de TreeTagger encore une fois. Par exemple, « Los Angeles » n'était quasiment pas reconnu par l'outil comme un nom propre. On peut observer les étiquettes comme ADJ ou VER. UDPipe, par contre, n'a pas fait d'erreurs avec ce mot.

Dans l'ensemble, chaque outil présente ses propres avantages. On ne pourrait bien entendu pas juger de la qualité des deux étiqueteurs simplement d'après ces quelques exemples. Idéalement, l'efficacité d'un étiqueteur devrait être mésurée en calculant la précision, le rappel et la F-mesure par rapport au « Gold Standard » (étiquetage correct, fait par un expert). Mais si le peu qui a pu être observé ici est constant tout au long des documents étiquetés, cela aura un impact sur les résultats pour l'extraction des patrons morpho-syntaxiques et des relations dans la BàO 3. On verra si c'est vrai dans la suite.


Scripts et résultats

Les programmes et les résultats obtenus pour chaque de trois rubriques sont disponibles ci-dessous.

Script Sorties TreeTagger Sorties UDPipe Sorties UDPipe (formatées en XML)
etiquetage-BAO2-regex.pl sortieTT-regex_3208.xml
sortieTT-regex_3210.xml
sortieTT-regex_3246.xml
sortieUD-regex_3208.txt
sortieUD-regex_3210.txt
sortieUD-regex_3246.txt
sortieUD-regex_3208.xml
sortieUD-regex_3210.xml
sortieUD-regex_3246.xml

Note : Les fichiers XML sont volumineux (d'environ 30-40Mo), les navigateurs peuvent avoir du mal à les afficher. Il est donc conseillé de les télécharger.

Note : Quelques lignes pour évaluer le temps de traitement ont été aussi ajoutées au programme. Cela dépend largement de la machine, mais voici nos performances : 266 secondes pour la 3208, 278 secondes pour la 3210 et 195 secondes pour la 3246. Une autre méthode d’étiquetage a été mentionnée dans le cours – l'étiquetage « à la volée ». Il n’est pas possible que cette méthode soit plus performante et rapide que celle que nous avons utilisée. Donc nous n’avons pas été tenté de la tester.

Boîte à outils n°3

Objectif

Extraction des patrons morpho-syntaxiques et relations de dépendence dans les sorties produites à l'issue de la BàO 2.


Description

Dans cette troisième étape de notre projet, nous devons construire des listes de patrons morpho-syntaxiques à partir de contenus textuels des fils RSS traités. Les patrons à extraire de chaque rubrique traitée sont : ADJ-NOM, NOM-ADJ, NOM-PREP-NOM, VERBE-DET-NOM, NOM-VERBE-ADJ et VERBE-ADV-ADJ. Quant aux relations syntaxiques en dépendance, nous allons extraire les couples dépendant-gouverneur portants les relations : obj, acl et flat:name. Les résultats d'extraction triés et décomptés sont sauvegardés dans les fichiers TXT.

Toutes ces informations linguistiques sont importantes pour comprendre les caractéristiques et sujets principaux de chaque rubrique du journal Le Monde traitée. Par exemple, les patrons comme NOM-ADJ et les autres permettront de définir les sujets principaux dans chaque domaine étudié. Évidemment que pour les rubriques « International » et « Culture » on ne trouvera pas beaucoup de mêmes séquences de mots et donc de mêmes thématiques. Pour les rubriques « À la une » et « International », par contre, elles peuvent avoir pas mal de choses en commun, à mon avis.

Parmi les relation syntaxiques à extraire j'ai choisi, par exemple, celle de flat:name qui lie très souvent les éléments composants des noms propres. J'attends d'obtenir des listes avec une sorte d'entités nommées, principalement les noms de personnes, des endroits, des entreprises... Cela peut s'avérer significatif pour caractériser les rubriques.

Plusieurs méthodes ont été mises en place pour extraire les informations linguistiques mentionnées ci-dessus. La méthode principale vue dans le cours, c'est le script Perl qui est basée en grande partie sur les expressions régulières. Ensuite nous avons vu (principellemnt sans le cadre du cours Documents Structurés) les méthodes basées sur les langages de la famille XML (XSLT et XQuery). Enfin, j'ai essayé d'effectuer les mêmes tâches avec le langage Python. Ici, on va vous présenter toutes ces différentes méthodes.


Méthode 1 : Perl via expressions régulières

J’ai apporté quelques modifications au script Perl extract_patron.pl vu en cours afin de sortir un fichier TXT par patron. Chaque fichier en sortie du script est donc nommé {patron}_{rubrique}_pl.txt. Pour cela le script boucle d’abord sur la liste des patrons (patrons.txt en paramètre de la ligne de commande), puis sur les lignes du fichier UDPipe au format CoNLL. Le reste du traitement est identique à celui vu en cours. Ce fonctionnement implique cependant de lire n fois (1 fois par patron) le fichier de sortie UDPipe ce qui dégrade peut-être les performances. Le programme donc le lance comme ceci :

perl extraction.pl fichier_etiquete.txt fichier_patrons.txt

Le script Perl pour extract_relation.pl est un peu différent de celui pour l'extraction des patrons. Contrairement à l'extraction de patrons, on travaille dans ce cas sur le fichier étiqueté par UDPipe converti en format XML. Ici on ne passe pas le fichier TXT avec la liste des relations souhaitées en argument, on passe le nom de la relation directements dans la ligne de commande:

perl extraction.pl fichier_etiquete.txt relation > sortie.txt


Méthode 2 : XSLT

La transformation produite par les feuilles de style XSLT permet d'extraire le contenu textuel des fichiers XML. Ce travail à été effectué principalement dans le cadre du cours Documents Structurés. Comme on l'a vu dans le cours, c'est possible d'extraire différents patrons morpho-syntactique en combinant l'extraction textuelle avec des conditions pour trouver la bonne séquence d'étiquettes à récupérer. La transformation se fait via xsltproc sur la ligne de commande. Pour l'ensemble de travaux j'ai utilisé la version XSLT 1.0.


Méthode 3 : XQuery

Le langage de requête XQuery permet de fouiller des fichiers XML de façon assez efficace. Il suit la structure FLWOR (for, let, where, order by, return) et ressemble un peu syntaxiquement au language SQL. Travailler sur des fichiers XML, en tant que base de données, rend l'exploration de données assez rapide. Avec l'outil Base X on peut facilement visualiser l'arborescence des fichiers XML. Cette méthode, ainsi que la précedente, a été surtout étudiée dans le cadre du cours Documents Structurés.


Méthode 4 : Python via Pyconll

J’ai réalisé l’équivalent du traitement Perl pour l’extraction des patrons en utilisant le langage Python, notamment la bibliothèque Pyconllextract_patron.py. Cependant j’ai apporté plusieurs modifications au traitement :

  • Un programme principal permettant de :
    • créer les objets rubriques (classe rubrique) ;
    • boucler sur les rubriques et sur les patrons ;
    • appeler la fonction permettant de constituer le dictionnaire à partir d’une rubrique et d’un patron : getDicoConnl() ;
    • enregistrer le résultat avec la fonction enregResult().
  • L’ajout d’une classe rubrique contenant :
    • le contenu du fichier UDPipe (utilisation de la bibliothèque Pyconll afin de créer un objet correspondant à notre fichier étiqueté ; cette bibliothèque permet de faire un parsing de notre fichier étiqueté pour faciliter l’accès aux différents attributs) ;
    • le chemin du fichier ;
    • le nom de la rubrique.
  • Le découpage du traitement en 4 fonctions :
    • getDicoConnl() : Permet de retourner un dictionnaire en fonction d’un patron et d’un objet Pyconll (fichier de sortie UDPipe). Cette fonction appelle également les fonctions getSequence() et add_dico().
    • getSequence() : Permet de retourner une séquence à ajouter au dictionnaire si elle est conforme à un patron.
    • add_dico() : Permet d’ajouter une séquence de mot au dictionnaire avec le nombre d'occurrences.
    • enregResult() : Permet d’enregistrer le résultat dans un fichier sous la forme {patron}_{rubrique}_py.txt.

Dans le script extract_relation.py la bibliothèque Pyconll est particulièrement pratique pour l’extraction des relations aussi car elle permet d’accéder directement à une relation à partir d’un ID.

Le traitement est quasiment identique à celui pour extraire les patrons sauf que nous avons ici seulement les 3 fonctions suivantes :

  • getDicoRelations() : Permet de retourner un dictionnaire en fonction d’une relation et d’un objet Pyconll (fichier de sortie UDPipe). Cette fonction utilise la fonction add_dico().
  • add_dico() : Permet d’ajouter une relation au dictionnaire avec le nombre d'occurrences.
  • enregResult() : Permet d’enregistrer le résultat dans un fichier sous la forme {relation}_{rubrique}_py.txt.


Un coup d'œil sur les résultats

Dans tous les cas, peu importe quelle méthode on utilise, cela nous permet de répondre à la question : Quels sont les termes caractéristiques de chaque rubrique ?

En observant les résultats obtenus pour le patron NOM-ADJ sur les trois rubriques différentes (récoltés via Python sur la sortie UDPipe au format CoNNL), on remarque que les rubriques « À la une » et « International » ont des terminologies proches, comparées à celle de la rubrique « Culture », comme on pouvait facilement le supposer. Cependant, la thématique la plus populaire (malheureusement) est la crise sanitaire, même pour la rubrique « Culture » c'est un sujet central. Les terminologies des rubriques « À la une » et « International » révèlent les élections présidentielles aux États-Unis très souvent. On dirait que les évènement principaux de l'année 2020, c'est l'épidémie de Covid-19 et la présidentielle américaine.

Le bouton ci-dessous montre les 20 séquences les plus fréquentes.

                
              À la une
        199 crise sanitaire
        57 réseaux sociaux
        52 épidémie due
        52 président américain
        40 assemblée nationale
        39 elections municipales
        37 violences policières
        36 chômage partiel
        34 elections américaines
        31 agressions sexuelles
        31 élection présidentielle
        30 élections municipales
        30 urgence sanitaire
        28 réseau social
        27 personnels soignants
        26 pandémie due
        26 blouses blanches
        26 commission européenne
        26 présidentielle américaine
        25 jeu vidéo
                
             
                
              International
        135 président américain
        110 crise sanitaire
        101 présidentielle américaine
        66 commission européenne
        66 élection présidentielle
        65 elections américaines
        64 réseaux sociaux
        52 cour suprême
        48 affaires étrangères
        47 sécurité nationale
        41 épidémie due
        41 banque centrale
        40 violences policières
        35 crise économique
        35 relance européen
        33 élections législatives
        28 président turc
        28 parlement européen
        27 arabie saoudite
        27 pandémie due
                
             
                
              Culture
        76 crise sanitaire
        49 sélection albums
        47 feuilleton littéraire
        46 brèves critiques
        33 art contemporain
        30 sélection musicale
        29 cinéma français
        28 réseaux sociaux
        28 moment musical
        26 série documentaire
        22 voyage immobile
        19 pause séries
        18 cœur littéraires
        17 centre national
        17 moment décisif
        17 guerre mondiale
        16 œuvres complètes
        16 rentrée littéraire
        14 crise due
        13 chaîne franco-allemande
                
             

Maintenant j'aimerais bien étudier les résultats pour la relation en dépendence flat:name. Comme je l'ai déjà constaté, c'est comme si on extrait des entités nommées ce qui pourrait être très intéressant pour l'analyse linguistique.

Sans surprise, la rubrique « À la une » contient principalement les noms des politiciens français, même si les noms de Donald Trump et Joe Biden apparaissent presque aussi souvent que le nom Emmanuel Macron. Même le nom du président de Biélorussie a été mentionné 14 fois... Et encore les rubriques « À la une » et « International » ont beaucoup en commun, mais dans la dernière on rencontre surtout les noms érangers. La rubrique « Culture » parle surtout des écrivains et écrivaines. Le seul toponyme retrouvé dans toutes les trois rubriques – New York.

Ce bouton montre les 20 noms propres les plus fréquents extraits via Perl de la sortie UDPipe au format XML.

                
              À la une
          Emmanuel Macron	108
          Donald Trump	98
          Joe Biden	76
          Monde »	51
          Edouard Philippe	51
          Jean Castex	43
          Boris Johnson	32
          Anne Hidalgo	29
          George Floyd	28
          Maïa Mazaurette	25
          Olivier Véran	25
          Gérald Darmanin	21
          Eric Dupond-Moretti	19
          Charlie Hebdo	18
          New York	16
          Samuel Paty	16
          Agnès Buzyn	16
          Didier Raoult	16
          Nicolas Sarkozy	15
          Alexandre Loukachenko	14
                
             
                
              International
          Donald Trump	284
          Joe Biden	200
          Boris Johnson	80
          George Floyd	79
          Emmanuel Macron	51
          New York	46
          Xi Jinping	33
          Jair Bolsonaro	32
          Mike Pompeo	29
          Alexandre Loukachenko	29
          Burkina Faso	28
          Philippe Escande	27
          Bernie Sanders	27
          Vladimir Poutine	26
          Angela Merkel	26
          Ghassem Soleimani	25
          Benyamin Nétanyahou	24
          Nicolas Maduro	20
          Barack Obama	18
          Juan Guaido	18
                
             
                
              Culture
          Mathias Enard	61
          Camille Laurens	56
          New York	42
          Véronique Ovaldé	38
          Monde »	31
          Michel Guerrin	28
          Los Angeles	24
          Victor Hugo	23
          Eric Chevillard	20
          Roman Polanski	20
          Monde Afrique	19
          France Culture	17
          Roselyne Bachelot	17
          Radio France	14
          France Inter	13
          service Culture	12
          Franck Riester	12
          J' ai	11
          Harvey Weinstein	11
          Adèle Haenel	11
                
             

Maintenant on veut regarder les patrons NOM-PREP-NOM extraits via XQuery. Cette séquence n'est pas moins parlant que les précedentes extractions vues. Les terminologies semblent être pertinentes pour ses rubriques « À la une » et « International » on parle souvent de la politique et donc du président. Pour la rubrique « Culture » le sujet principal, c'est la litérature et la presse (qui ont moins souffert de l'épidemie que le théâtre ou le cinéma, evidemment). Cliquant le bouton ci-dessous vous pouvez consulter les 20 premiers groupes nominaux pour chaque rubrique.

                
              À la une
          66 chef de l'Etat
          58 port du masque
          47 réforme des retraites
          41 projet de loi
          40 ans de prison
          40 Ligue des champions
          35 Coronavirus en direct
          31 plan de relance
          31 milliers de personnes
          29 garde à vue
          28 face au coronavirus
          26 Journal de crise
          25 crise des blouses
          24 millions de personnes
          23 Réforme des retraites
          23 dizaines de milliers
          22 ministre de l'intérieur
          22 mesures de confinement
          22 République en marche
          22 nombre de morts
                
             
                
              International
          82 chef de l'Etat
          78 plan de relance
          64 ans de prison
          44 droits de l'homme
          41 milliers de personnes
          33 dizaines de milliers
          31 face au coronavirus
          31 milliards de dollars
          27 projet de loi
          27 l'Etat de droit
          26 l'épidémie de coronavirus
          25 mesures de confinement
          23 forces de l'ordre
          23 millions de personnes
          23 ministre des affaires
          23 Conseil de sécurité
          22 chef du gouvernement
          22 nord du pays
          21 crise du coronavirus
          20 cas de contamination
                
             
                
              Culture
          48 lectures en poche
          44 coups de cœur
          42 sélection de séries
          30 journal de bord
          29 bord des lectures
          28 rédacteur en chef
          26 metteur en scène
          24 salles de cinéma
          21 sélection de programmes
          20 chronique du confinement
          19 journal des lectures
          15 mise en scène
          15 sélection de films
          14 début des années
          14 salles de spectacle
          14 choix en matière
          14 matière de musique
          13 temps de confinement
          12 marché de l'art
          12 choix de lectures
          11 metteuse en scène
                
             

Pour résumer, les rubriques « À la une » et « International » ont en effet beaucoup en commun laissant la rubrique « Culture » un peu à part. Globalement, l'extraction des patrons morpho-syntaxiques et des relations en dépendance permet d'avoir une idée sur les thématiques principales du corpus – on voit que les élections présedentielles américaines et la crise sanitaire sont les préoccupations centrales en 2020.

Toutes les méthodes testées sont bonnes, on est seulement limité par la qualité des données de base : si l'étiquetage est erroné, on ne peut rien y faire. Sinon le choix de patrons à extraire peut aussi jouer – certaines séquences sont peu fréquentes (par exemple, le patron VERBE-ADV-ADJ ne donne pas assez de données) et ne peuvent pas donner les informations linguistiques pertinentes.


Scripts et résultats

Les programmes et les résultats obtenus pour chaque de trois rubriques sont disponibles ci-dessous. Pour télécharger, cliquez le bouton droit de la souris.

Outil Scripts et supports 3208 (À la une) 3210 (International) 3246 (Culture)
Perl extract-patron.pl
patrons.txt
extract-relation.pl
patron ADJ-NOM
patron NOM-ADJ
patron NOM-PREP-NOM
patron NOM-VERBE-ADJ
patron VERBE-ADV-ADJ
patron VERBE-DET-NOM
relation OBJ
relation ACL
relation FLAT:NAME
patron ADJ-NOM
patron NOM-ADJ
patron NOM-PREP-NOM
patron NOM-VERBE-ADJ
patron VERBE-ADV-ADJ
patron VERBE-DET-NOM
relation OBJ
relation ACL
relation FLAT:NAME
patron ADJ-NOM
patron NOM-ADJ
patron NOM-PREP-NOM
patron NOM-VERBE-ADJ
patron VERBE-ADV-ADJ
patron VERBE-DET-NOM
relation OBJ
relation ACL
relation FLAT:NAME
XQuery extract-patron.xq
extract-relation.xq
patron ADJ-NOM
patron NOM-ADJ
patron NOM-PREP-NOM
patron NOM-VERBE-ADJ
patron VERBE-ADV-ADJ
patron VERBE-DET-NOM
relation OBJ
relation ACL
relation FLAT:NAME
patron ADJ-NOM
patron NOM-ADJ
patron NOM-PREP-NOM
patron NOM-VERBE-ADJ
patron VERBE-ADV-ADJ
patron VERBE-DET-NOM
relation OBJ
relation ACL
relation FLAT
patron ADJ-NOM
patron NOM-ADJ
patron NOM-PREP-NOM
patron NOM-VERBE-ADJ
patron VERBE-ADV-ADJ
patron VERBE-DET-NOM
relation OBJ
relation ACL
relation FLAT:NAME
XSLT extract-patron.xsl
extract-relation.xsl
patron ADJ-NOM
patron NOM-ADJ
patron NOM-PREP-NOM
patron NOM-VERBE-ADJ
patron VERBE-ADV-ADJ
patron VERBE-DET-NOM
relation OBJ
relation ACL
relation FLAT:NAME
patron ADJ-NOM
patron NOM-ADJ
patron NOM-PREP-NOM
patron NOM-VERBE-ADJ
patron VERBE-ADV-ADJ
patron VERBE-DET-NOM
relation OBJ
relation ACL
relation FLAT:NAME
patron ADJ-NOM
patron NOM-ADJ
patron NOM-PREP-NOM
patron NOM-VERBE-ADJ
patron VERBE-ADV-ADJ
patron VERBE-DET-NOM
relation OBJ
relation ACL
relation FLAT:NAME
Python extract-patron.py
patrons.txt
extract-relation.py
relations.txt
patron ADJ-NOM
patron NOM-ADJ
patron NOM-PREP-NOM
patron NOM-VERBE-ADJ
patron VERBE-ADV-ADJ
patron VERBE-DET-NOM
relation OBJ
relation ACL
relation FLAT:NAME
patron ADJ-NOM
patron NOM-ADJ
patron NOM-PREP-NOM
patron NOM-VERBE-ADJ
patron VERBE-ADV-ADJ
patron VERBE-DET-NOM
relation OBJ
relation ACL
relation FLAT:NAME
patron ADJ-NOM
patron NOM-ADJ
patron NOM-PREP-NOM
patron NOM-VERBE-ADJ
patron VERBE-ADV-ADJ
patron VERBE-DET-NOM
relation OBJ
relation ACL
relation FLAT:NAME

Conclusion

Dans la première partie de ce projet, nous avons construit une boîte à outils qui génère un corpus à partir des fils RSS dans deux formats : TXT et XML. Nous avons aussi testé deux méthodes d'extraction de données textuelles différentes, donc nous pouvons constater que la version pure Perl est meilleure. Non seulement la version du script avec les expressions régulières nous semble plus claire intuitivement, elle est aussi la plus rapide. En plus, pour pouvoir utiliser le module XML::RSS il faut étudier la documentation qui n'est pas toujours facile à prendre en main.

Dans la deuxième partie du projet nous avons repris le script de la première boîte à outils (celui avec la méthode pure Perl puisque elle est plus rapide) et nous l'avons completé de telle façon qu'il puisse étiqueter les données textuelles, une fois extraites. Nous avons testé 2 étiqueteurs différents : TreeTagger, l'étiqueteur en POS ; UDPipe, l'étiqueteur syntaxique. Le traitement s'est avéré un peu long, en moyenne 4 minutes (sur ma machine, bien entendu). Comme résultat, nous avons obtenu des fichiers étiquetés par TreeTagger en format XML et des fichiers étiquetés par UDPipe en format CoNLL. Pour ensuite extraire les relations syntaxiques des sorties UDPipe avec certains outils, nous avons converti les fichiers CoNLL en format XML.

Dans la troisième partie du projet, on a expérimenté divers outils d'extraction des informations à partir des données étiquetées dans la boîte à outil précedente afin de pouvoir étudier les terminologies du corpus et les analyser. On a constaté que les 4 méthodes font bien le travail, la seule limitation ici, c'est la qualité de données d'entrée, donc des fichiers étiquetés. On a obtenu quand même quelques résultats éronnés, mais c'est la responsabilité des outils d'étiquetage. Enfin, on a conclu que les sujets les plus discutés en année 2020, en tout cas dans le journal Le Monde, sont la crise sanitaire suite du Covid-19 et les élections présidentielles aux États-Unis. On a egalement constaté, qu'entre rubriques « À la une » et « International » il y a beaucoup de choses en commun, tandis que la rubrique « Culture » reste un peu à part.

Ce que j’ai trouvé particulièrement amusant, c'est de créer ce site. Pendant les travaux sur le premier Projet Encadré, j’ai eu l’opportunité de me familiariser avec les bases du web : HTML et CSS (la structure et le style de web-pages). Ce semestre je voulais améliorer le site du premier semestre et essayer de voir les bases de JavaScript afin de rendre mon site un peu plus dynamique. Ce plan s’est avéré trop ambitieux avec un programme aussi intense, mais j’ai quand même réussi à apprendre un peu plus. Notamment, j’ai découvert divers ressources très utiles :

XQuery – XSLT

Propose les solutions pour l'extraction d'informations les plus courtes et faciles à prendre en main (en tout cas pour moi).

Un peu dépassé, plus beaucoup utilisé vu que le format XML est moins populaire aujourd'hui que les autres formats de structuration de données (par exemple, json).

Perl

Très puissant quand il s'agit des expressions regulières !

Possible de traiter divers formats, XML et CoNLL y compris.

Beaucoup moins de documentations et guidelines disponibles en ligne que pour Python.

Nécessite la conversion de la sortie UDPipe en format XML.

Python

Pas besoin de reformater les fichiers CoNLL en XML – on peut en fait travailler sur tous les formats si on le veut !

Il existe une alternative à la bibliotèque Pyconll – CoNLL-U.

Nécessaire d'étudier la documentation pour pouvoir utiliser les bibliotèques.