IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Calcule fréquences de mots clés dans un texte


Sujet :

Python

  1. #1
    Membre régulier
    Étudiant
    Inscrit en
    Février 2009
    Messages
    220
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2009
    Messages : 220
    Points : 77
    Points
    77
    Par défaut Calcule fréquences de mots clés dans un texte
    Bonjour,

    J'ai besoin de connaitre comment je pourrai calculer les fréquences de plusieurs mots (une liste de mots) dans un corpus textuel.

    Merci d'avance pour vos aides.

  2. #2
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 937
    Points : 7 345
    Points
    7 345
    Par défaut
    Vous pouvez utiliser la méthode count

  3. #3
    Membre averti Avatar de dariyoosh
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    236
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 236
    Points : 334
    Points
    334
    Par défaut
    Il est également possible d'utiliser les expressions régulières en définissant un pattern correspondant à votre requête. Voici donc un exemple: trouver le nombre d'occurrences du mot "hello" dans un texte:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    pattern = "[hH]ello"
    text = "hello word1 hello word2 word3 word4 Hello"
    regexp = re.compile(pattern)
    count = 0
    for token in text.split(" "):
        if regexp.search(token):
            count += 1
    print("There are %d occurrences of the pattern %s"%(count,pattern))

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 483
    Points : 9 282
    Points
    9 282
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Puisque c'est un "corpus textuel", il faut déjà trouver les mots. Pour ça, il faut définir ce qu'est un mot, ce qui dépend du domaine qu'on traite.

    Par exemple, un mot c'est une suite de lettres, précédée et suivie par un séparateur qui peut être: début ou fin de ligne, espace, signe de ponctuation ('.,;:!?'), apostrophe, guillemets, etc...

    Il faut ensuite écrire le code qui trouvera les mots à partir de cette définition (=un "parser"). Si c'est complexe, on peut utiliser les expressions régulières.

    Les mots clés peuvent être, à mon avis, intégrés comme clés dans un dictionnaire, avec comme valeur le nombre de présences du mot-clé dans le texte: {'truc':5, 'machin':12, ...}. L'avantage du dictionnaire est que les clés étant "hashée", elles sont retrouvées plus rapidement que si on cherche dans une liste.

    Après, on peut opérer de deux manières opposées:

    1- on parcourt le texte avec le parser, et à chaque fois qu'on trouve un mot clé, on ajoute 1 à son compteur

    2- on parcourt les mots clés, et pour chacun d'entre eux, on compte le nombre de fois où ce mot est rencontré dans le texte. On suppose dans ce cas que le texte a déjà été traduit en liste de mots à l'aider du parser.

    Je préfère pour ma part la méthode 1.

  5. #5
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut
    Il y a aussi des librairies qui font ça très bien, comme NLTK. Il y a un très bon tuto en ligne aussi, ce qui ne gâche rien.

  6. #6
    Membre régulier
    Étudiant
    Inscrit en
    Février 2009
    Messages
    220
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2009
    Messages : 220
    Points : 77
    Points
    77
    Par défaut
    Bonjour,

    Pour tyrtamos, votre méthode elle me semble super mais malheureusement j'ai rien compris de ton message. Qu'est ce que vous voulez dire avec dictionnaire et les clés étant "hashée" ...

    Pour Herode, j'ai fais un petit recherche sur NLTK et j'ai trouvé beaucoup d'exemples, elle permet en fait de faire une normalisation pour le texte ainsi que plusieurs autre choses, elle est très intéressante mais comment je vais l'utiliser pour calculer les fréquences des mots ?

  7. #7
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 483
    Points : 9 282
    Points
    9 282
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par ysahel Voir le message
    Qu'est ce que vous voulez dire avec dictionnaire et les clés étant "hashée"
    Désolé, mais comme ça fait partie des bases de Python, je pensais que c'était acquis...

    Voilà une liste avec tes mots-clés: ['mot1', 'mot2', 'mot3'...]

    Si on veut associer un compteur à chaque mot, on peut créer une autre liste:
    [5, 12, 3] avec la correspondance donnée par les indices 'mot1' => 5, 'mot2' => 12, etc...

    Mais quand on cherche un mot dans une liste de 1000 mots par exemple, on essaie statistiquement 500 mots avant de trouver le bon: c'est long et ce n'est pas très élégant.

    Un dictionnaire en Python, qui porterait en même temps tes mots-clés et leur compteur, serait comme ça: D = {'mot1': 5, 'mot2': 12, 'mot3': 3}. Les mots sont les 'clés' du dictionnaire, et l'adresse de chacun de ces mots dans le dictionnaire est donné par calcul (=par hachage: http://fr.wikipedia.org/wiki/Fonction_de_hachage). Cela fait que quand on cherche D['mot3'], Python ne teste pas avant les mots précédents 'mot1' et 'mot2', mais tombe tout de suite dessus parce qu'il a déjà calculé son adresse.

    D'où ma suggestion...

    (plus d'infos ici => http://python.developpez.com/cours/TutoSwinnen/)

  8. #8
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 483
    Points : 9 282
    Points
    9 282
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Comme c'est un pb amusant, j'ai "commis" un petit code en tant que source d'inspiration. Le texte vient d'un "générateur de faux textes":

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #! /usr/bin/python
    # -*- coding: utf-8 -*-
    from __future__ import division
    # Python v2.7
     
    #import os, sys
     
    #############################################################################
    class Parsetexte(object):
     
        def __init__(self, texte):
            self.texte = texte
            self.ind = 0 # initialisation indice courant
            self.fin = len(self.texte)-1 # indice du dernier caractère du texte
            self.sep = ' \t\n\r\f\v' + '\'".,;:!?' # séparateurs de mots
     
        def motsuivant(self):
     
            # chercher le 1er caractère du mot suivant
            while True:
                if self.ind<=self.fin and texte[self.ind] in self.sep:
                    self.ind += 1
                else:
                    break
            if self.ind >self.fin:
                # il n'y a plus de mot à trouver: renvoyer la chaine vide
                return ""
     
            # chercher le dernier caractère du mot +1
            ind2 = self.ind + 1
            while True:
                if ind2<=self.fin and texte[ind2] not in self.sep:
                    ind2 += 1
                else:
                    break
            # saisir le mot à renvoyer
            mot = texte[self.ind:ind2]
            # mettre à jour l'indice courant
            self.ind = ind2
     
            # et renvoie le mot trouvé à l'appelant
            return mot
     
    #############################################################################
     
    texte = """
     
    Accedat huc suavitas quaedam oportet sermonum atque morum, haudquaquam mediocre condimentum amicitiae. Tristitia autem et in omni re severitas habet illa quidem gravitatem, sed amicitia remissior esse debet et liberior et dulcior et ad omnem comitatem facilitatemque proclivior.
     
    Excogitatum est super his, ut homines quidam ignoti, vilitate ipsa parum cavendi ad colligendos rumores per Antiochiae latera cuncta destinarentur relaturi quae audirent. hi peragranter et dissimulanter honoratorum circulis adsistendo pervadendoque divites domus egentium habitu quicquid noscere poterant vel audire latenter intromissi per posticas in regiam nuntiabant, id observantes conspiratione concordi, ut fingerent quaedam et cognita duplicarent in peius, laudes vero supprimerent Caesaris, quas invitis conpluribus formido malorum inpendentium exprimebat.
     
    Verum ad istam omnem orationem brevis est defensio. Nam quoad aetas M. Caeli dare potuit isti suspicioni locum, fuit primum ipsius pudore, deinde etiam patris diligentia disciplinaque munita. Qui ut huic virilem togam deditšnihil dicam hoc loco de me; tantum sit, quantum vos existimatis; hoc dicam, hunc a patre continuo ad me esse deductum; nemo hunc M. Caelium in illo aetatis flore vidit nisi aut cum patre aut mecum aut in M. Crassi castissima domo, cum artibus honestissimis erudiretur.
     
    Et eodem impetu Domitianum praecipitem per scalas itidem funibus constrinxerunt, eosque coniunctos per ampla spatia civitatis acri raptavere discursu. iamque artuum et membrorum divulsa conpage superscandentes corpora mortuorum ad ultimam truncata deformitatem velut exsaturati mox abiecerunt in flumen.
     
    Ideoque fertur neminem aliquando ob haec vel similia poenae addictum oblato de more elogio revocari iussisse, quod inexorabiles quoque principes factitarunt. et exitiale hoc vitium, quod in aliis non numquam intepescit, in illo aetatis progressu effervescebat, obstinatum eius propositum accendente adulatorum cohorte.
    """
     
    # dictionnaire des mots-clés à compter
    D = {'hoc': 0, 'omnem': 0, 'more': 0}
     
    P = Parsetexte(texte)
     
    i = 0
    while True:
        mot = P.motsuivant()
        if mot=="":
            break
        i += 1
        if D.has_key(mot):
            D[mot] += 1
        print mot
     
    print "*"*50
    print "nombre total de mots:", i
    print u"comptage des mots-clés", D
    Ce qui donne à l'exécution:

    Accedat
    huc
    suavitas
    quaedam
    oportet
    sermonum
    atque

    ===> j'ai coupé la liste trop longue, mais les 267 mots du texte ont bien été trouvés!

    eius
    propositum
    accendente
    adulatorum
    cohorte
    **************************************************
    nombre total de mots: 267
    comptage des mots-clés {'more': 1, 'hoc': 3, 'omnem': 2}

    Désolé: je ne peux plus suivre ce fil avant la semaine prochaine.

    Bonne suite!

    =====================================================
    [edit] je n'ai pas résisté: on peut présenter cela comme un itérateur, ce qui va simplifier l'appel:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    class motsuivant(object):
     
        def __init__(self, texte, sep=' \t\n\r\f\v' + '\'".,;:!?'):
            self.texte = texte # texte à analyser
            self.sep = sep # séparateurs de mots
            self.ind = 0 # initialisation indice courant
            self.fin = len(self.texte)-1 # indice du dernier caractère du texte
     
        def __iter__(self):
            return self
     
        def next(self):
            """trouve et retourne le mot suivant"""
            # cherche le 1er caractère du mot suivant
            while self.ind<=self.fin and texte[self.ind] in self.sep:
                self.ind += 1
            if self.ind >self.fin:
                # il n'y a plus de mot à trouver!
                raise StopIteration # sortie de la boucle d'itération
     
            # cherche le 1er caractère après le mot trouvé
            ind2 = self.ind + 1
            while ind2<=self.fin and texte[ind2] not in self.sep:
                ind2 += 1
     
            # saisit le mot à renvoyer
            mot = texte[self.ind:ind2]
     
            # met à jour l'indice courant
            self.ind = ind2# + 1
     
            # et renvoie le mot trouvé à l'appelant
            return mot
    Et on exécutera avec:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    i = 0
    for mot in motsuivant(texte):
        i += 1
        if D.has_key(mot):
            D[mot] += 1
        print mot
    Ce qui donnera, bien sûr, les mêmes résultats qu'avant!

    NB: ce "parser" n'a pas un caractère général. On a considéré qu'un mot, c'est n'importe quoi entre 2 séparateurs. Mais dans certains cas, par exemple pour analyser une expression à calculer, ça ne marche plus, parce qu'il faut tenir compte du sens des mots trouvés. Ainsi, "2.55+(34*479)" devrait renvoyer '2.55', '+', '(', '34', '*', '479', ')', ce que le code précédent ne sait pas faire sans être modifié.

Discussions similaires

  1. search par mot clés dans produits plone
    Par Abla23 dans le forum Zope
    Réponses: 4
    Dernier message: 03/07/2006, 18h34
  2. détection mot clef dans un texte
    Par Royd938 dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 19/04/2006, 19h12
  3. recherche par mots-clés dans base access
    Par syber72 dans le forum Access
    Réponses: 2
    Dernier message: 07/03/2006, 14h53
  4. Comment stocker des mots clés dans une bas Mysql
    Par renofx1 dans le forum SQL Procédural
    Réponses: 5
    Dernier message: 05/01/2006, 01h57
  5. [FLASH MX] Mot cliquable dans un texte
    Par Greutzeb dans le forum Flash
    Réponses: 2
    Dernier message: 05/05/2005, 14h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo