Skip to content

Mots suivants

Énoncé

Description du problème

On souhaite effectuer une analyse sur les mots d'un texte. Plus particulièrement, on se propose de savoir pour chaque mot mi d'un texte donné, quels sont les mots mij qui le suivent. De plus, on souhaite associer à chaque mot mij un compteur cij du nombre d’occurrences du couple (mi, mij) dans le texte.

Une fois ces données calculées, on utilise l'outil de visualisation de graphes graphviz / dot pour les représenter.

Par exemple, pour le texte suivant (Le serpent python, Charles Trenet) :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
c’est un serpent python
c’est un python serpent
qui se promene dans la foret
pour chercher a devorer
un beau petit lapin
ou bien un negre fin.
car le serpent python a faim
il a une faim sans fin !
mais betes et gens sont partis hier
loues par la Metro Goldwyn Mayer
pour figurer dans un film de Tarzan
qui doit rapporter beaucoup d’argent !
et le serpent piteux
est triste et se mord la queue
car il comprend, o desespoir
qu’il ne mangera pas ce soir.

soudain le bois s’eveille
arrivent des appareils
de prises de vues de prise de son
c’est la scene du grand frisson
on lache des animaux
des lions et des rhino-
ceros qu’ont l’air feroce comm’ tout
mais sont doux comme des toutous
notre serpent du haut d’une branche en l’air
voit monsieur Johnny Weissmuller
qui fait joujou avec un elephant
quel joli tableau pour les enfants.
mais tant de cinema
ne remplit pas l’estomac
du pauvre serpent qui n’aura pas
qui n’aura pas de repas.

quand une idee subtile
germe au coeur du reptile
profitant d’une repetition
voici qu’avec precaution
dans l’ombre du crepuscule
il avance il recule
puis happe un morceau minuscule
un morceau de pellicule
qui depassait d’une boite en fer
c’etait la grande scene du Val d’Enfer
tournee le matin dans une cloche a plongeur
pour mieux voir evoluer le nageur.
et comme un spaghetti
le python en appetit
avale deux cents metres a present
des aventures de Tarzan !

puis il s’en va joyeux
pensant : " c’est merveilleux
je vais dormir maintenant trois semaines
digerer ce film sans peine. "
rampant par-ci par-la
il s’enroule, oh la la,
autour d’un cocotier geant
mais soudain s’ecrie : " j’ai en...
j’ai envie de vomir c’est affreux, tu m’as
empoisonne, cinema
tarzan n’est pas pour les pauvres pythons
j’en ai mal jusqu’au bout des tetons. "
et la moralite
du serpent depite
c’est que parfois trop de cine parleur
peut vous donner mal au coeur
ou que les hommes digerent, dit-on,
mieux que les serpents pythons.

Le graphe obtenu est le suiant :

graphe de "Le serpent python"

Travail demandé

Comment stocker ces données ?

On utilise un dictionnaire suivants. Chaque clef est un mot mi. À chaque clef, il faut associer un ensemble de mots, chacun muni d’un compteur. Pour ce faire, on utilise à nouveau un dictionnaire. Chaque valeur du dictionnaire suivants est donc un dictionnaire dont les clefs sont les mij et les valeurs sont les cij.

On vous demande de compléter le fichier mots_suivant.py affiché ci-dessous et disponible ici qui réalise la lecture d’un fichier, son analyse, l’affichage du graphe et enfin la génération d’une petite phrase en se déplaçant aléatoirement dans le graphe.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/env python3
"""
On fait une analyse de texte pour dessiner le graphe des mots suivants.
Permet l'utilisation de dictionnaires et une imbrication de structures.
On se sert des donnees pour generer des phrases aleatoires.
"""
import sys
from re import finditer
from random import choice, random
from os import system

def get_mots(nom_fichier):
    """Renvoie un tableau dynamique sur tous les mots du fichier.

    Elimine au passage tout ce qui n'est pas une lettre.
    """
    mots = []
    with open(nom_fichier, "r") as fichier:
        for ligne in fichier:
            for mot in finditer("[a-zA-Z]+", ligne):
                mots.append(mot.group(0))
    return mots

def get_couples(tableau):
    """Renvoie un un tableau dynamique des couples.

    Le tableau dynamique renvoyé contient tous les couples d'elements
    successifs de l'iterateur donne.
    """
    couples = []
    valeur_precedente = tableau[0]
    for valeur in tableau[1:]:
        couples.append((valeur_precedente, valeur))
        valeur_precedente = valeur
    return couples

def analyse_texte():
    """Analyse le fichier donné en argument.

    L'analyse parcours les mots du fichier et dessine le graphe
    des mots suivants.

    Ensuite, une phrase aléatoire est générée à partir du dictionnaire
    des mots.
    """

    # Parcours
    if len(sys.argv) != 2:
        print("utilisation :", sys.argv[0], "fichier_texte")
        sys.exit(1)
    suivants = compte_mots_suivants(sys.argv[1])
    genere_graphe(suivants)

    # Génération d'une petite phrase aleatoire.
    mot_depart = choice(list(suivants.keys()))
    phrase = [mot_depart]
    for _ in range(10):
        phrase.append(get_suivant_aleatoire(phrase[-1], suivants))
    print(" ".join(phrase))

def compte_mots_suivants(nom_fichier):
    """ Renvoie le dictionnaire des mots suivants.

    Renvoie un dictionnaire associant a chaque mot m1 du fichier
    un dictionnaire associant a chaque mot m2 suivant m1 dans le
    fichier le nombre de fois ou m2 apparait apres m1.
    """
    # TODO
    ...

def genere_graphe(suivants):
    """ Genere le graphe dans les fichiers mots-suivants.dot et .png.

    Attention : il faut analyser des petits textes seulement car le
    layout du graph par l'outil dot peut vite coûter très cher en temps
    de calcul.
    """

    # On créer un fichier au format texte dot, utilisé pour
    # décrire un graphe.
    with open("mots-suivants.dot", "w") as fichier_dot:
        # TODO : écrire dans le graph dans le fichier .dot
        ...

    # On utilise l'outil dot pour convertir le fichier .dot en image
    system("dot -Tpng mots-suivants.dot -o mots-suivants.png")

def get_suivant_aleatoire(mot, suivants):
    """Tire aleatoirement un suivant du mot donné.

    Le tirage aléatoire doit être pondéré par le nombre d'occurences.
    Si le mot donne n'a pas de suivant, retourne un mot aleatoire.
    """
    # TODO
    ...

if __name__ == "__main__":
    analyse_texte()

En guise de documentation du format .dot, voici le fichier mots-suivants.dot généré pour notre exemple ci dessus.

Difficulté

star star star star

Exercices associés