Le projet
L’objectif de recherche de mon Master 2 est de repérer et d’identifier automatiquement les émotions présentes dans un corpus épique latin composé de la Thébaïde de Stace, de la Pharsale de Lucain, de l’Enéide de Virgile et des Argonautes de Valerius Flaccus. Cette recherche a pour but de réaliser une étude comparative des émotions dans chaque œuvre. Mon analyse prend en compte à la fois des émotions dites (mots-concepts) et des émotions montrées (manifestations). Je m’appuie pour cela sur un lexique référentiel constitué en M1 recensant l’ensemble des mots qui renvoient à des émotions. Ce lexique a été construit à partir d’une recherche de cooccurrences de surface réalisée sur le corpus latin du LASLA à partir des émotions répertoriées par Cicéron. Je dispose donc d’une liste de termes, associée à une base de données regroupant l’ensemble des formes fléchies de chaque entrée du dictionnaire. Ces données sont, de plus, regroupées par racine lexicale (par exemple, pavor, pavidus, paveo sont identifiés sous le code « 101 »).


Identifier automatiquement les émotions dites ne pose pas de problème particulier, car il s’agit d’une simple recherche par chaîne de caractère. L’association entre le mot et l’idée étant presque systématique, un simple script de recherche lexicale a suffi. Cependant, c’est beaucoup plus problématique dans le cas des émotions montrées, faisant appel à un lexique qui est occasionnellement associé à des émotions, notamment par connotation. Si certains termes sont non ambigus, comme lacrima, d’autres ne permettent pas une annotation systématique (comme flamma qui peut aussi bien renvoyer aux flammes de l’amour qu’à celles de l’incendie). Par conséquent, mon projet HN4 avait pour objectif de construire un script capable de repérer automatiquement et efficacement les manifestations d’émotion. Mon hypothèse de départ était qu’en prenant en compte le contexte du mot cible, il devait être possible de décider s’il s’agissait effectivement d’une manifestation émotionnelle ou non. Cette hypothèse découle d’une expérience de lecteur où l’on comprend que le mot relève de l’expression de l’émotion grâce au contexte qui l’entoure. C’est pourquoi j’ai tenté de mettre au point un script R qui prenait en compte le contexte avant d’annoter et d’identifier le mot cible. L’objectif de mon projet est de fournir un outil efficace pour aider à l’annotation des émotions et voir s’il est possible d’automatiser cette annotation.
La méthode :
A. Préparation du corpus
Afin d’expérimenter mon script, j’ai choisi un corpus restreint par rapport à mon projet de mémoire, et ai donc travaillé sur les Argonautiques de Valerius Flaccus. En effet, je dispose d’une version de ce texte encodée manuellement à l’aide d’Oxygen, avec laquelle je pourrai comparer les résultats de l’analyse automatique.

Mon corpus numérique est issu de l’édition de Ehlers (1980), en format numérique, obtenu à partir de la Bibliotheca Teubneuriana en ligne, que j’ai nettoyé dans l’éditeur de texte Notepad++ (que j’ai l’habitude d’utiliser et qui permet un usage facile des expressions régulières, notamment). J’ai entré le texte en format TXT dans R. A partir de l’édition papier, j’ai créé des variables pour chaque chant avec les numéros de vers (je ne pouvais pas procéder à une numérotation totalement automatique car certains vers sont manquants, et je voulais respecter au maximum l’édition de Ehlers). Ces vecteurs ont été transformés en dataframes
, puis fusionnés, ce qui m’a permis d’avoir un ensemble de données avec le numéro des chants et le numéro des vers.
Ensuite j’ai transformé le texte de Valerius Flaccus en tibble
, avec une ligne par vers (numérotés grâce aux variables manuellement définies). Enfin, j’ai opéré une tokenisation (avec pour unité le mot), grâce à des fonctions du package tidytext
vues lors des cours HN3. Je dispose ainsi de données où pour chaque ligne j’ai le vers, le chant, le numéro de vers, la position du vers dans l’œuvre, le mot cible, et la position du mot dans l’œuvre.

b. Préparation des données des émotions
J’ai dû ensuite formater ma banque de données lexicales recensant les formes des mots pouvant renvoyer à des émotions. L’idée initiale était de constituer des dictionnaires en dataframes
et d’opérer ensuite une fusion à partir de la variable [word]
, ce qui permettait une identification du lexique commun au lexique référentiel et au texte. Cette méthode fonctionne pour les émotions dites, quoiqu’elle nécessite de nombreuses manipulations de données (et génère assez facilement des erreurs, notamment des dédoublements de lignes). Surtout, cela ne peut pas être appliqué pour les émotions montrées car cela ne permet pas de prendre en compte le contexte. De plus, je devais enregistrer dans une même variable des ensembles de données de longueurs différentes, ce qui était impossible dans des dataframes. Il fallait aussi que l’extraction de données depuis le lexique référentiel soit automatisable, car cela aurait été trop coûteux de reproduire 254 fois (pour le nombre d’entrées du lexique) la même opération. Grâce aux conseils d’A. Berra, j’ai donc constitué des listes, et entré chaque ensemble de formes, correspondant à des racines lexicales, dans une liste référence. J’ai créé une fonction permettant de récupérer l’ensemble des formes associées à chaque code chiffré depuis la base de données, et indexé chaque ensemble de formes dans le dictionnaire.

C. Repérage automatique des émotions
J’ai ensuite préparé mon dataframe
pour l’accueil de nouvelles données en créant des nouvelles variables correspondant au repérage la présence de l’émotion d’une part et à l’identification du type d’émotion d’autre part (peur, colère, joie, etc.). J’ai d’abord exécuté le script pour le repérage des émotions dites, qui ne posent a priori pas de difficultés particulières, avant de lancer la requête sur les émotions montrées. Pour celles-ci, j’ai d’abord effectué un repérage simple sans condition des mots dans le corpus qui trouvaient une correspondance dans le dictionnaire de référence.

J’ai récupéré une liste de ligne à tester, enregistrée dans un vecteur, à partir de laquelle j’ai construit un script pour analyser le contexte. En effet, pour chaque élément du vecteur, j’ai vérifié si dans une plage de -5mots ; +5mots il y avait des mots déjà encodés comme étant des émotions. Si c’était le cas, le mot cible était identifié comme une émotion, la variable correspondante était modifiée. De plus, selon la catégorie d’émotion présente dans le contexte, le mot cible était étiqueté comme appartenant à cette même catégorie. J’ai ainsi enrichi mon jeu de données.
D. Test de réussite
Pour juger de la validité de ce processus, j’ai réalisé une phase de test visant à comparer les résultats de l’annotation automatique avec les données du corpus annoté manuellement. Je dispose en effet d’une annotation manuelle des Argonautiques dans laquelle chaque mot renvoyant à une émotion est identifié, balisé et complété par des attributs indiquant s’il s’agit d’un concept ou d’une émotion, et de quelle catégorie d’émotion il s’agit (colère, tristesse, etc.). J’ai dû modifier mon document XML-TEI afin de pouvoir l’exploiter efficacement dans R. L’objectif était d’obtenir un dataframe issu du XMLque je pourrais fusionner avec le jeu de données que j’avais généré. Or, la fusion s’effectuant par une variable contenant les mots du texte, il a fallu que je singularise chaque token par une balise <w>
et que je modifie et simplifie mon encodage pour ne garder que les informations nécessaires au test contenues dans des attributs à cette même balise. J’ai effectué ces manipulations à l’aide d’expressions régulières dans Oxygen.
Grâce au package xml2
, et aux conseils d’A. Berra, j’ai extrait les données et les ai mises dans un dataframe
. J’ai donc récupéré les mots du corpus et indiqué automatiquement dans une variable la présence d’émotion. J’ai dû nettoyer les données afin de rendre possible la fusion (quelques erreurs de tokenisation causées par des erreurs dans le fichier source posaient notamment problème). J’ai ensuite fusionné les données, et ai lancé un petit script permettant de comparer les données de la variable d’annotations issue du XMLavec les annotations issues du script R. J’ai entré les résultats dans de nouvelles variables, distinguant les succès, les faux-positifs et les faux-négatifs, et ai lancé un décompte du total de chacun. J’ai également généré deux dataframes issus de la fonction filter()
pour les faux-positifs et faux-négatifs, afin d’analyser les erreurs et d’améliorer le script par la suite.
E. Résultats
e.1 Emotions dites :
La recherche des émotions dites ne posant pas de problème particulier, le repérage automatique permet assez rapidement d’obtenir des résultats utiles pour l’analyse de la présence des émotions dans les œuvres. R a permis une automatisation de la recherche dans des corpus que je n’avais pas encodés manuellement et donc permet d’effectuer des comparaisons facilement. J’ai généré des graphiques à l’aide de ggplot afin d’obtenir des visualisations de ces données obtenues.

e.2 Emotions montrées:
Le repérage automatique des émotions montrées étant le plus complexe, j’ai procédé à des tests de réussite plus poussés afin d’appréhender la réussite réelle de la manipulation avant de réaliser une analyse des émotions en elles-mêmes.
J’ai effectué plusieurs tests, notamment en faisant varier le contexte pris en compte pour le repérage automatique.
Contexte(mots) |
OK |
Faux positif |
Faux négatif |
Taux de réussite |
% émotions trouvées |
3 |
1217 |
497 |
907 |
46,43 |
55,09 |
5 |
1317 |
690 |
807 |
46,80 |
59,62 |
10 |
1551 |
1172 |
573 |
47,06 |
70,21 |
0 |
1800 |
2067 |
324 |
43 |
81,5 |
On constate qu’il reste un grand nombre d’erreurs dans l’annotation automatique, et ce quelle que soit l’échelle. On peut établir plusieurs conclusions quant au script établi :
- Il y a un problème au niveau du repérage, car même sans prendre en compte le contexte, toutes les occurrences ne sont pas repérées. Cela signifie qu’il manque des éléments dans le lexique référentiel, ou du moins qu’il y a un décalage entre celui-ci et ce qui est considéré comme une émotion dans le corpus annoté
- Le fait de prendre en compte le contexte permet de restreindre le nombre de faux positif de manière évidente : cela permet bien, a priori, d’éliminer certains mots identifiés à tort comme relevant d’une émotion.
- Plus le contexte est large, plus le nombre d’émotions trouvées augmentent. Les erreurs également mais le taux de réussite ne change que peu (inférieur à 50% dans tous les cas).
Après une analyse des erreurs faux négatifs, j’en suis arrivée au constat que certains mots étaient éliminés, alors qu’ils renvoyaient presque toujours à l’expression d’une émotion (les larmes, les plaintes, le deuil). J’ai donc modifié mon script pour différencier, parmi les manifestations, celles qui étaient ambiguës et nécessitaient une recherche dans le contexte, et celles qui étaient presque à coup sûr des expressions émotionnelles. J’ai relancé le script de recherche et l’analyse de réussite.
Contexte (mots) |
OK |
Faux positif |
Faux négatif |
Taux de réussite |
% émotions trouvées |
3 |
1382 |
538 |
742 |
51,92 |
62,56 |
5 |
1474 |
756 |
650 |
51,18 |
66,73 |
10 |
1538 |
1205 |
486 |
47,63 |
69,62 |
Le taux de réussite est plus élevé. Ce script est plus performant pour trouver les émotions, mais laisse encore passer de nombreuses erreurs.
En analysant les faux positifs et faux négatifs, j’identifie deux causes pour les faux-négatifs :
- Soit la forme n’est simplement pas dans le lexique référentiel, qui est donc à compléter et à améliorer.
- Soit les mots sont pourtant dans la liste du lexique référentiel mais pas identifiés comme des émotions. Cela veut dire qu’ils ont été éliminés par le script R par erreur, et que celui-ci peut être amélioré. Sur les 486 faux-positifs dans un contexte -10 + 10, 257 sont dus à cette erreur.
Et deux causes essentielles pour les faux positifs :
- L’ambiguïté lexicale : le script prenant en compte des chaînes de caractères, il y a des erreurs d’identification. C’est inévitable sur un corpus non lemmatisé. Pour réduire ces erreurs, on pourrait modifier le lexique et voir si la suppression des éléments problématiques est pertinente et joue sur le taux de réussite
- Une collocation fortuite
En récupérant les termes les plus souvent annotés comme faux positifs on voit nettement que certaines entrées du lexique créent des erreurs presque systématiquement, pour un taux de réussite très faible.

J’ai malgré tout essayé de comparer une visualisation obtenue avec les émotions dites et celles prenant en compte en plus les émotions montrées.


On observe que les tendances générales ne se trouvent pas bouleversées par la prise en compte des émotions montrées, sauf dans l chant VI où la tristesse prend finalement le pas sur la peur, ou dans le chant 7 où l’amour occupe une place plus importante (ce qui nous semble cohérent avec notre expérience de lecture).
De plus, si l’on compare avec une visualisation issue de l’encodage manuel du document XML, il apparaît que la prise en compte des émotions montrées permette d’obtenir des résultats plus proches de la réalité, malgré les nombreuses erreurs que nous avons signalées. La peur et la tristesse notamment semblent plutôt bien repérées. En revanche, notre analyse automatique manque clairement de précision concernant la colère et la fureur, largement sous-représentées dans nos résultats par rapport à ce qu’on s’attendrait à trouver, et la joie au contraire sur-représentée. Le tableau ci-dessous vient confirmer ces premiers constats visuels :

En effet, la joie est largement sur-représentée dans l’analyse automatique (qui va au-delà de la tendance du script automatique à générer de nombreux faux-positifs). On note aussi des problèmes d’identification importants dans les chants 2, 5 et 6 qui semblent être le lieu de confusions entre la colère, la douleur et la fureur. Cela vient du fait que les émotions sont fortement entremêlées dans ces chants, et que le script n’a pas su choisir à quel mot-concept rattacher telle manifestation.
F. Perspectives
Pour améliorer les résultats, je propose plusieurs pistes à tester :
- Evaluer la pertinence de l’association des manifestations avec certaines émotions comme la joie. On trouve 178 occurrences de la joie dans le XML, 163 avec la recherche d’émotions dites, et 341 avec les émotions montrées. Ici l’ajout de données crée trop d’erreurs, car c’est une émotion qui est peu associée à des manifestations physiques.
- Modifier la condition de validation en prenant en compte le fait que certaines émotions montrées ne sont pas accompagnées d’un concept, afin de réduire le nombre de faux négatifs. On pourrait vérifier également s’il n’y a pas une autre manifestation à proximité. Cependant, cela risque d’augmenter les faux-positifs à cause de cooccurrences fortuites et non liées à l’expression d’une émotion.
- Ajouter une condition pour la validation de l’émotion. Dans la configuration actuelle du script de recherche, il suffit d’une cooccurrence pour valider le fait que la forme cible relève de l’expression de l’émotion. On pourrait ajouter comme condition qu’il y ait au moins deux cooccurrents (concepts ou manifestations) pour valider.
- Voir si le lexique référentiel mérite d’être enrichi, et si cela ne provoque pas plus d’erreur que cela n’en résout.
- Réduire le lexique référentiel en éliminant raisonnablement les entrées qui créent trop d’erreur.
Conclusion
La recherche automatique des émotions semble malgré tout un outil utile comme support à l’analyse des émotions. S’appuyer sur l’analyse du contexte pour repérer automatiquement les émotions montrées semble pertinent et permet de réduire considérablement les erreurs provoquées par une simple recherche d’occurrences, sans condition. Cependant, par rapport à notre hypothèse de base, il apparaît qu’une validation à partir de la présence d’un autre terme émotionnel dans le contexte proche n’est pas suffisant. Il faudra encore préciser les conditions d’identification des termes cibles comme relevant du domaine émotionnel et améliorer les ressources à notre disposition.