32 votes

Algorithme de fréquence des mots pour le traitement du langage naturel

Sans obtenir un diplôme en recherche d'information, j'aimerais savoir s'il existe des algorithmes permettant de compter la fréquence d'apparition des mots dans un texte donné. L'objectif est d'obtenir une "impression générale" de ce que les gens disent dans un ensemble de commentaires textuels. Dans la lignée de Wordle .

Ce que j'aimerais :

  • ignorer les articles, les pronoms, etc. ("a", "an", "the", "him", "them" etc.)
  • préserver les noms propres
  • ignorer la césure, sauf pour le genre doux

Atteindre les étoiles, ce serait génial :

  • manipuler la terminaison et les pluriels (par exemple, like, likes, liked, liking donnent le même résultat)
  • regroupement des adjectifs (adverbes, etc.) avec leurs sujets (" grand service " par opposition à " grand ", " service ")

J'ai essayé d'utiliser Wordnet, mais je ne fais que modifier les choses à l'aveuglette en espérant que cela fonctionne pour mes données spécifiques. Une solution plus générique serait la bienvenue.

0 votes

Je me demande si cela peut vous être utile : ibm.com/developerworks/linux/library/l-cpnltk.html

0 votes

Je l'ai fait en .NET : blog.wekeroad.com/2007/09/12/ blog.wekeroad.com/2007/09/20/ J'espère que cela vous aidera

69voto

Aleksandar Dimitrov Points 4862

Vous n'aurez pas besoin d'un seul, mais de plusieurs beaux algorithmes, du type de ceux qui suivent.

  • L'ignorance des pronoms se fait via un liste d'arrêt .
  • préserver les noms propres ? Tu veux dire, détecter les entités nommées, comme Hoover Barrage et dire "c'est un seul mot" ou des noms composés, comme programmation langue ? Je vais vous donner un indice : c'est une question difficile, mais il existe des bibliothèques pour les deux. Cherchez NER (Named entitiy recognition) et lexical chunking. OpenNLP est un kit d'outils Java qui fait les deux.
  • ignorer la césure ? Vous voulez dire, comme pour les sauts de ligne ? Utilisez des expressions régulières et vérifiez le mot résultant en consultant le dictionnaire.
  • la gestion des pluriels/de la phraséologie : vous pouvez consulter l'outil Dégommeur de neige . Il fait très bien l'affaire.
  • "regrouper" les adjectifs avec leurs noms est généralement une tâche de analyse syntaxique superficielle . Mais si vous recherchez spécifiquement des adjectifs qualitatifs (bon, mauvais, merdique, étonnant...), vous serez peut-être intéressé par les documents suivants analyse des sentiments . LingPipe fait cela, et bien plus encore.

Je suis désolé, je sais que tu as dit que tu voulais un KISS, mais malheureusement, tes exigences ne sont pas si faciles à satisfaire. Néanmoins, il existe des outils pour tout cela, et vous devriez pouvoir les relier entre eux et ne pas avoir à effectuer de tâches vous-même, si vous ne le souhaitez pas. Si vous voulez effectuer une tâche vous-même, je vous suggère de vous pencher sur la dérivation, c'est la plus facile de toutes.

Si vous optez pour Java, combinez Lucene avec le OpenNLP toolkit. Vous obtiendrez de très bons résultats, car Lucene dispose déjà d'un triturateur intégré et de nombreux didacticiels. La boîte à outils OpenNLP, quant à elle, est peu documentée, mais vous n'en aurez pas besoin. Vous pourriez également être intéressé par NLTK écrit en Python.

Je vous conseille de laisser tomber votre dernière exigence, car elle implique une analyse superficielle et n'améliorera certainement pas vos résultats.

Ah, au fait, le terme exact de ce document-terme-fréquence que vous cherchez s'appelle tf-idf . C'est à peu près la meilleure façon de rechercher la fréquence des documents pour les termes. Pour le faire correctement, vous ne pourrez pas vous en sortir en utilisant des matrices vectorielles multidimentionnelles.

... Oui, je sais. Après avoir suivi un séminaire sur la RI, mon respect pour Google était encore plus grand. Après avoir fait un peu de RI, mon respect pour eux est tombé tout aussi vite.

16voto

underspecified Points 569

Bienvenue dans le monde de la PNL ^_^

Tout ce dont vous avez besoin, c'est d'un peu de connaissances de base et de quelques outils.

Il existe déjà des outils qui vous permettent de savoir si un mot dans une phrase est un nom, un adjectif ou un verbe. Ils s'appellent tagueurs de parties du langage . En général, ils prennent de l'anglais en clair en entrée, et produisent le mot, sa forme de base et la partie de la parole. Voici le résultat d'un marqueur de parties du langage UNIX populaire sur la première phrase de votre message :

$ echo "Without getting a degree in information retrieval, I'd like to know if there exists any algorithms for counting the frequency that words occur in a given body of text." | tree-tagger-english 
# Word  POS     surface form
Without IN  without
getting VVG get
a   DT  a
degree  NN  degree
in  IN  in
information NN  information
retrieval   NN  retrieval
,   ,   ,
I   PP  I
'd  MD  will
like    VV  like
to  TO  to
know    VV  know
if  IN  if
there   EX  there
exists  VVZ exist
any DT  any
algorithms  NNS algorithm
for IN  for
counting    VVG count
the DT  the
frequency   NN  frequency
that    IN/that that
words   NNS word
occur   VVP occur
in  IN  in
a   DT  a
given   VVN give
body    NN  body
of  IN  of
text    NN  text
.   SENT    .

Comme vous pouvez le voir, il a identifié "algorithmes" comme étant la forme plurielle (NNS) de "algorithme" et "existe" comme étant une conjugaison (VBZ) de "exister". Il a également identifié "a" et "the" comme étant des "déterminants (DT)" - un autre mot pour article. Comme vous pouvez le voir, l'identificateur POS a également identifié la ponctuation.

Pour tout faire, sauf le dernier point de votre liste, il suffit de passer le texte dans un trieur POS, de filtrer les catégories qui ne vous intéressent pas (déterminants, pronoms, etc.) et de compter les fréquences des formes de base des mots.

Voici quelques étiqueteurs POS populaires :

TreeTagger (binaire uniquement : Linux, Solaris, OS-X)
Tagger GENIA (C++ : compilez vous-même)
Tagger POS de Stanford (Java)

Pour faire la dernière chose sur votre liste, vous avez besoin de plus que de simples informations sur les mots. Un moyen facile de commencer est de compter séquences de mots plutôt que les mots eux-mêmes. Ils sont appelés n-grams . Un bon point de départ est UNIX pour les poètes . Si vous êtes prêt à investir dans un livre sur la PNL, je vous recommande Fondements du traitement statistique du langage naturel .

1 votes

Belle explication, qui mérite un vote positif. Juste une chose, cependant : Le Tagger de Stanford est un exemple typique de ce que j'appelle "Akademikerware" en allemand. C'est horrible de programmer avec, car l'API ne vous donnera que des maux de tête. Pour Java, je préfère OpenNLP et LingPipe. Pour Python, NLTK.

7voto

4voto

unmounted Points 10968

Voici un exemple de la façon dont vous pourriez le faire en Python, les concepts sont similaires dans n'importe quel langage.

>>> import urllib2, string
>>> devilsdict = urllib2.urlopen('http://www.gutenberg.org/files/972/972.txt').read()
>>> workinglist = devilsdict.split()
>>> cleanlist = [item.strip(string.punctuation) for item in workinglist]
>>> results = {}
>>> skip = {'a':'', 'the':'', 'an':''}
>>> for item in cleanlist:
      if item not in skip:
        try:
          results[item] += 1
        except KeyError:
          results[item] = 1

>>> results
{'': 17, 'writings': 3, 'foul': 1, 'Sugar': 1, 'four': 8, 'Does': 1, "friend's": 1, 'hanging': 4, 'Until': 1, 'marching': 2 ...

La première ligne ne fait que récupérer les bibliothèques qui aident à résoudre certaines parties du problème, comme dans la deuxième ligne, où urllib2 télécharge une copie du "Devil's Dictionary" d'Ambrose Bierce. Les lignes suivantes font une liste de tous les mots du texte, sans ponctuation. Ensuite, vous créez une table de hachage, qui dans ce cas est comme une liste de mots uniques associés à un numéro. La boucle for passe en revue chaque mot du livre de Bierce, s'il existe déjà un enregistrement de ce mot dans la table, chaque nouvelle occurrence ajoute un à la valeur associée à ce mot dans la table ; si le mot n'est pas encore apparu, il est ajouté à la table, avec une valeur de 1 (signifiant une occurrence.) Pour les cas dont vous parlez, vous voudriez accorder beaucoup plus d'attention aux détails, par exemple en utilisant les majuscules pour aider à identifier les noms propres uniquement au milieu des phrases, etc.

Pour entrer dans le domaine du déracinement et de la pluralisation, expérimenter, puis se tourner vers des travaux tiers, j'ai apprécié certaines parties du NLTK, qui est un projet universitaire open source, également en python.

1voto

graffic Points 588

L'algorithme que vous venez de décrire. Un programme qui fait ça tout de suite, avec un gros bouton qui dit "Fais-le"... Je ne sais pas.

Mais laissez-moi être constructif. Je vous recommande ce livre Programmation de l'intelligence collective . Les chapitres 3 et 4 contiennent des exemples très pragmatiques (vraiment, pas de théories complexes, juste des exemples).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X