web-dev-qa-db-fra.com

Quelle est la meilleure méthode de création de racine en Python?

J'ai essayé toutes les méthodes nltk pour le raclage, mais cela me donne des résultats étranges avec quelques mots. 

Exemples

Il coupe souvent la fin des mots quand il ne devrait pas le faire:

  • caniche => caniche
  • article article

ou ne découle pas très bien: 

  • facilement et facilement ne sont pas liés à la même Parole
  • feuilles, pousse, ne sont pas équeutées

Connaissez-vous d'autres librairies en python ou un bon dictionnaire?

Je vous remercie

24
PeYoTlL

Les résultats que vous obtenez sont (généralement) attendus pour un stemmer en anglais. Vous dites que vous avez essayé "toutes les méthodes nltk" mais quand j'essaie vos exemples, cela ne semble pas être le cas.

Voici quelques exemples utilisant le PorterStemmer

import nltk
ps = nltk.stemmer.PorterStemmer()
ps.stem('grows')
'grow'
ps.stem('leaves')
'leav'
ps.stem('fairly')
'fairli'

Les résultats sont 'grow', 'leav' et 'fairli' qui, même s'ils sont ce que vous vouliez, sont des versions à tige du mot original.

Si nous passons au mot clé Snowball, nous devons fournir le langage en tant que paramètre.

import nltk
sno = nltk.stem.SnowballStemmer('english')
sno.stem('grows')
'grow'
sno.stem('leaves')
'leav'
sno.stem('fairly')
'fair'

Les résultats sont les mêmes que précédemment pour "pousse" et "feuilles" mais "assez" est considéré comme "juste"

Donc, dans les deux cas (et il y a plus de deux radicales disponibles dans nltk), les mots que vous dites ne sont pas liés, en fait, le sont. Le LancasterStemmer retournera «easy» s'il est fourni avec «easy» ou «easy» comme entrée.

Peut-être que vous vouliez vraiment un lemmatizer? Cela renverrait 'article' et 'caniche' inchangé.

import nltk
lemma = nltk..wordnet.WordNetLemmatizer()
lemma.lemmatize('article')
'article'
lemma..lemmatize('leaves')
'leaf'
88
Spaceghost

Tous ces stemmers qui ont été discutés ici sont des stemmer algorithmiques, ils peuvent donc toujours produire des résultats inattendus tels que

In [3]: from nltk.stem.porter import *

In [4]: stemmer = PorterStemmer()

In [5]: stemmer.stem('identified')
Out[5]: u'identifi'

In [6]: stemmer.stem('nonsensical')
Out[6]: u'nonsens'

Pour obtenir correctement les mots racines, il faut un stemmer basé sur un dictionnaire, tel que Hunspell Stemmer. Voici une implémentation en python de ce répertoire dans le répertoire link . Exemple de code est ici

>>> import hunspell
>>> hobj = hunspell.HunSpell('/usr/share/myspell/en_US.dic', '/usr/share/myspell/en_US.aff')
>>> hobj.spell('spookie')
False
>>> hobj.suggest('spookie')
['spookier', 'spookiness', 'spooky', 'spook', 'spoonbill']
>>> hobj.spell('spooky')
True
>>> hobj.analyze('linked')
[' st:link fl:D']
>>> hobj.stem('linked')
['link']
9
0xF

Stemming consiste à supprimer les suffixes (habituellement, seuls les suffixes, dans la mesure où je n’ai essayé aucun des serveurs Nltk à supprimer un préfixe, à oublier les infixes) . Nous pouvons donc appeler ce programme un programme stupide/moins intelligent. Il ne vérifie pas si un mot a une signification avant ou après avoir dérivé… .. Par exemple. Si vous essayez d’endiguer "xqaing", bien qu’il ne s’agisse pas d’un mot, il supprimera "-ing" et vous donnera "xqa".

Donc, pour utiliser un système plus intelligent, on peut utiliser des lemmatiseurs ... Les lemmas utilisent des lemmes bien formés (mots) sous forme de wordnet et de dictionnaires ... C'est donc toujours le cas et le mot correct est renvoyé. Cependant, il est lent car il passe par tous les mots afin de trouver celui qui convient.

1
Ritveak Dugar

Dans mon projet de chatbot, j'ai utilisé PorterStemmer. Cependant, LancasterStemmer remplit également cette fonction. L’objectif ultime est d’attacher la Parole à sa racine afin que nous puissions rechercher et comparer avec les mots saisis.

Par exemple: De nltk.stem importer PorterStemmerps = PorterStemmer ()

def SrchpattrnStmmed(self):
    KeyWords =[]
    SrchpattrnTkn = Word_tokenize(self.input)
    for token in SrchpattrnTkn:
        if token not in stop_words:
            KeyWords.append(ps.stem(token))
            continue
    #print(KeyWords)
    return KeyWords

J'espère que ça va aider ..

0
sarvesh Kumar

Stemmers varient dans leur agressivité. Porter est l'un des auteurs les plus agressifs de l'anglais. Je trouve que ça fait généralement plus mal que ça ne sert… .. Du côté plus léger, vous pouvez utiliser un lemmatiseur comme déjà suggéré, .__ ou un stemmer algorithmique plus léger . La limitation des lemmatiseurs est qu'ils ne peuvent pas gérer les mots inconnus , ce qui n’est pas un problème grave.

Personnellement j'aime bien le stemmer de Krovetz qui est une solution hybride, combinant un lemmatiseur à dictionnaire et un stemmer léger pour les mots sans vocabulaire. Krovetz propose également kstem ou light_stemmer dans Elasticsearch. Il existe une implémentation en python sur pypi https://pypi.org/project/KrovetzStemmer/ , bien que ce ne soit pas celui que j'ai utilisé.

Une autre option est le lemmatizer dans SpaCy. Un traitement ultérieur avec spaCy evry token a un attribut lemma_. (notez que le trait de soulignement lemma contient un identifiant numérique du lemma_) - https://spacy.io/api/token

Voici quelques articles comparant divers algorithmes de bouturage:

0
Daniel Mahler