Bureau d'étude PEIP - IS
TP4 - Introduction aux Word Embeddings
Attention : ce TP sera noté et comptera pour votre note de contrôle continu. Il est à réaliser en binôme lors des trois prochaines séances. Plus de détail en bas du sujet.
Nous allons aujourd'hui commencer à entrer dans le vif du sujet : le traitement automatique de texte. Nous allons travailler sur un ensemble de fichiers d'exemple qui sont issus de vrais corpus de texte.
Attention, bien que les fichiers d'exemple soient assez petits comparés aux corpus dont ils sont extraîts, ils restent assez volumineux. Prenez bien garde à optimiser vos programmes et à ne pas faire de traîtements inutiles, sinon votre code mettra des heures à s'éxecuter. Voici les corpus que nous allons utiliser :
- - wiki_text.txt : textes issus de wikipédia. 2 286 765 mots.
- - soap_text.txt : transcriptions de dialogues de feuilletons télévisées (General Hospital, All My children...). 2 699 733 mots.
- - tv_text.txt : transcription de dialogues de séries télé (Dr Who, The Office, Twin Peaks, The Simpsons,...). 2 798 041 mots.
- - movies_text.txt : transcription de dialogues de films (X-men, Saturday Night Fever, The Dark Knight,...). 2 154 831 mots.
On donne également un fichier tiny.txt qui est une version très (très) raccourcie des corpus précédents. Il est vivement consiellé de tester vos programmes sur ce fichier et non directement sur le très (très) gros corpus.
Tout cela se trouve dans l'archive text.zip.
But du TP
Nous allons utiliser ces corpus pour calculer la matrice de co-occurrences des mots dans un rayon de k-mots. Définissions d'abord ce dont il s'agit.
Considérons qu'il y a N mots différents dans le corpus. Nous construisons une matrice carrée de taille NxN. Chaque ligne est associée à un mot, de même pour chaque colonnes (pour des raisons évidentes de simplicité, la i^ème ligne et la i^ème colonne sont associées au même mot). Chaque case de la matrice est occupée par une valeur qui correspond au nombre de fois où un mot apparaît dans le k-contexte d'un autre (c'est à dire dans les k mots avant ou après ce dernier).
Pour donner un exemple, si on calcule la matrice de co-occurrence pour k=5, à la case m[i][j] on trouve le nombre de fois où le mot m_i apparaît dans les 5 mots avant ou après le mot m_j.
Le TP propose une marche à suivre, étape par étape, pour réussir à construire cette matrice. Nous utiliserons plusieurs outils qui seront peut être nouveaux pour vous en python : des pistes vous sont données pour que vous puissiez trouver sur internet les informations nécessaires à leur utilisation.
Travail à faire
- Créez une fonction lecture_traitement(f) qui lit un fichier texte dont le nom est passé en paramètre et renvoie son contenu sous la forme d'une seule String.
- De nombreux mots sont considérés comme différents juste à cause de leur casse : "Madame" et "madame" par exemple ne seront pas considérés comme identiques, alors qu'ils portent le même sens. Adaptez la fonction précédente en utilisant la fonction "lower" pour passer tous les caractères en minuscules.
- De même, beaucoup de caractères de ponctuation sont présents et ne sont pas utiles comme porteurs de sens. Adaptez votre fonction précédente pour qu'elle remplace tous les caractères qui ne sont pas des lettres minuscules par des espaces.
- Que fait la fonction "split" ? Utilisez là pour que votre fonction renvoie une liste de tous les mots présents dans le texte, et pas seulement une seule String.
- Créez une fonction liste_occurrences(l) qui calcule le nombre d'occurrences de chaque mot dans une liste de mots. Attention, cette fonction ne doit parcourir la liste qu'une seule fois (utilisez un dictionnaire).
- Donnez une fonction reduction_occurrences(d) qui, à partir d'un dictionnaire d'occurrence comme celui créé précédemment, renvoie la liste de tous les mots en supprimant les mots qui n'apparaissent qu'une seule fois, ainsi que les 100 mots les plus fréquents.
- Faites une fonction générale qui appelle dans l'ordre vos fonctions précédente et enregistre la liste résultante dans un fichier texte, avec un mot par ligne. Cela permettra de ne pas tout refaire à chaque fois mais de simplement charger le fichier de sauvegarde du texte pré-traité. Adaptez également votre code pour que l'ensemble des mots présents soit aussi enregistré dans un fichier à part.
- Nous allons commencer à travailler sur la fonction compute_matrix(l_mots, k, d_index) qui va calculer la matrice de co-occurrence. Cette fonction prend en paramètre plusieurs éléments : la liste des mots du corpus telle que définie dans les questions précédente, la valeur de k pour le calcul des contextes, et un dictionnaire qui associe à chaque mot son index dans la matrice. Commencez par écrire une fonction compute_dict(l_mots) qui transforme l'ensemble des mots du corpus en un dictionnaire de ce type (l'ordre des mots et de leur index n'a pas d'importance).
- Pour stocker la matrice, nous allons utiliser un numpy array. Il s'agit d'un objet python spécialement conçu pour stocker les tableaux et matrices de valeurs numériques (beaucoup plus adapté que les listes donc). Dans la fonction "compute_matrix", commencez par initialiser une matrice NxN ne contenant que des 0 (N étant le nombre de mots différents dans le corpus).
- Faites en sorte que, en parcourant la liste des mots du corpus une seule fois, votre fonction remplisse les cases de la matrice avec les bonnes valeurs. Prenez garde aux cas où les mots se trouvent en début ou en fin de fichier (et donc le contexte ne peut pas s'étendre complètement dans les 2 directions).
- La matrice de co-occurrence contient des effectifs (c'est à dire des valeurs entières). L'ordre de grandeur de ces valeurs dépend de la taille du corpus. Il serait plus utilie que cette matrice contienne des fréquences. Pour cela, il suffit de diviser l'effectif de chaque case de la matrice par le nombre total de mots dans tous les textes du corpus. Réalisez cette opération.
- Notre corpus comporte plusieurs fichiers et nos fonctions ne sont prévus que pour un fichier. Pour remédier à cela, on propose la chose suivante : on crée un fichier "index_corpus.txt" qui contient le nom de tous les fichiers du corpus (un par ligne). Une fonction prend le nom de ce fichier en paramètre et applique les fonctions de pré-traitement précédente sur tous les fichiers indexés. Elle fournit enfin une unique liste de mot et un unique dictionnaire pour tout le corpus.
- Caclulez la matrice de co-occurence en fréquence sur la totalité du corpus pour k=3. Utilisez la fonction dump de la librairie pickle pour enregistrer cette matrice dans un fichier.
Il existe bien d'autres pré-traitements que nous pourrions faire sur ce texte : remplacer tous les verbes conjugués par leur infinitif, tous les noms et adjectifs par leur radical, etc... Pour des besoins de simplification, on ne le fera pas ici.
Rendu
Le projet se réalise en binôme. Aucun monôme ne sera accepté. Si vous êtes un nombre impair, un et un seul trinôme sera accepté.
Votre code doit absolument être commenté. Une fonction qui ne contient pas au moins des commentaires pour indiquer la nature des paramètre et le but de la fonction ne sera pas prise en compte. Les points importants de vos algorithmes seront également expliqués. De manière générale, vous apporterez un soin particulier à la présentation de votre code et aux noms de vos variables et fonction.
Vos différents fichiers seront rendus dans une archive de la forme "nom1_nom2.zip". Cette archive contiendra vos fichiers de code, vos fichiers de sauvegarde (texte et pickle) ainsi qu'un fichier readme.txt qui rappelle le nom des membres du binômes et qui explique les principaux choix de programmation dans le code, les difficultés rencontrées, et le fonctionnement (en particulier, quelle fonction appeler pour lancer le programme).
ATTENTION : votre fichier de code doit impérativement fonctionner. Si vous ne parvenez pas à terminer, arrangez vous pour faire un fichier qui montre ce que vous avez pu faire, et précisez clairement votre avancement dans le readme.txt .
Le rendu est à faire avant le 8 mars 2024 23h59 dans un mail dont l'objet sera "[PEIP][BEIS] Rendu TP noté".