112 votes

Comment faire un dédoublement de mot ou une lemmatisation ?

J'ai essayé PorterStemmer et Snowball mais les deux ne fonctionnent pas sur tous les mots, il en manque certains très courants.

Mes mots d'essai sont : " chats courir courir cactus cactus cactus communauté communautés communautés ", et les deux obtiennent moins de la moitié de la vérité.

Voir aussi :

28 votes

Ce ne serait pas plutôt les cactus ?

3 votes

Juste pour faire une référence circulaire à la question originale postée sur Reddit : Comment faire par programme pour faire de la symétrie ? (par exemple, "manger" en "manger", "cactus" en "cactus") Je le publie ici parce que les commentaires contiennent des informations utiles.

1 votes

144voto

theycallmemorty Points 4609

Si vous connaissez Python, le Boîte à outils en langage naturel (NLTK) possède un lemmatiseur très puissant qui fait usage de WordNet .

Notez que si vous utilisez ce lemmatiseur pour la première fois, vous devez télécharger le corpus avant de l'utiliser. Ceci peut être fait par :

>>> import nltk
>>> nltk.download('wordnet')

Vous ne devez le faire qu'une seule fois. En supposant que vous avez maintenant téléchargé le corpus, cela fonctionne comme suit :

>>> from nltk.stem.wordnet import WordNetLemmatizer
>>> lmtzr = WordNetLemmatizer()
>>> lmtzr.lemmatize('cars')
'car'
>>> lmtzr.lemmatize('feet')
'foot'
>>> lmtzr.lemmatize('people')
'people'
>>> lmtzr.lemmatize('fantasized','v')
'fantasize'

Il existe d'autres lemmatiseurs dans la gamme module nltk.stem mais je ne les ai pas essayés moi-même.

11 votes

Oh, c'est triste... avant de savoir chercher S.O., j'ai mis en place le mien !

12 votes

N'oubliez pas d'installer le corpus avant de l'utiliser. nltk pour la première fois ! velvetcache.org/2010/03/01/

1 votes

Eh bien, celui-ci utilise un algorithme non déterministe comme Porter Stemmer, car si vous l'essayez avec dies il vous donne dy au lieu de die . N'existe-t-il pas une sorte de dictionnaire des racines codé en dur ?

29voto

CTsiddharth Points 339

J'utilise stanford nlp pour effectuer la lemmatisation. J'ai été confronté à un problème similaire ces derniers jours. Je remercie stackoverflow de m'avoir aidé à résoudre ce problème.

import java.util.*; 
import edu.stanford.nlp.pipeline.*;
import edu.stanford.nlp.ling.*; 
import edu.stanford.nlp.ling.CoreAnnotations.*;  

public class example
{
    public static void main(String[] args)
    {
        Properties props = new Properties(); 
        props.put("annotators", "tokenize, ssplit, pos, lemma"); 
        pipeline = new StanfordCoreNLP(props, false);
        String text = /* the string you want */; 
        Annotation document = pipeline.process(text);  

        for(CoreMap sentence: document.get(SentencesAnnotation.class))
        {    
            for(CoreLabel token: sentence.get(TokensAnnotation.class))
            {       
                String word = token.get(TextAnnotation.class);      
                String lemma = token.get(LemmaAnnotation.class); 
                System.out.println("lemmatized version :" + lemma);
            }
        }
    }
}

Il pourrait également être une bonne idée d'utiliser des mots d'arrêt pour minimiser les lemmes de sortie s'ils sont utilisés plus tard dans le classificateur. Jetez un coup d'œil à coreNlp extension écrite par John Conwell.

0 votes

Désolé pour la réponse tardive j'ai résolu ce problème seulement maintenant ! :)

1 votes

La ligne 'pipeline = new...' ne compile pas pour moi. Si je la remplace par 'StanfordCoreNLP pipelne= new...', elle compile. Est-ce correct ?

0 votes

Oui, vous devez d'abord déclarer la variable du pipeline. Le NLP de Stanford peut également être utilisé en ligne de commande. Vous n'avez donc pas besoin de programmer, il vous suffit de créer le fichier de propriétés et de le transmettre aux exécutables. Lisez la documentation : nlp.stanford.edu/software/corenlp.shtml

24voto

StompChicken Points 6102

J'ai essayé votre liste de termes sur le site de démonstration de cette boule de neige et les résultats semblent corrects....

  • chats -> chat
  • running -> courir
  • ran -> ran
  • cactus -> cactus
  • cactus -> cactus
  • communauté -> communiti
  • communautés -> communiti

Un démonteur est censé ramener les formes infléchies des mots à une racine commune. Ce n'est pas vraiment le rôle d'un déracineur de faire de cette racine un mot "correct" du dictionnaire. Pour cela, il faut regarder analyseurs morphologiques/orthographiques .

Je pense cette question traite plus ou moins de la même chose, et c'est de la réponse de Kaarel à cette question que je tire le deuxième lien.

6 votes

Le fait est que stem("updates") == stem("update"), ce qui est le cas (update -> updat).

1 votes

Le logiciel peut faire stem(x) == stem(y) mais cela ne répond pas complètement à la question.

11 votes

Attention au jargon, un radical n'est pas une forme de base d'un mot. Si vous voulez une forme de base, vous avez besoin d'un lemmatiseur. Le radical est la plus grande partie d'un mot qui ne contient pas de préfixe ou de suffixe. Le radical du mot "update" est en effet "updat". Les mots sont créés à partir des troncs en ajoutant des terminaisons et des suffixes, par exemple updat-e, ou updat-ing. ( fr.wikipedia.org/wiki/Word_stem )

21voto

alvas Points 4333

Le débat entre le déracineur et le lemmatiseur continue. Il s'agit de préférer la précision à l'efficacité. Il faut lemmatiser pour obtenir des unités linguistiquement significatives et déraciner pour utiliser un minimum de ressources informatiques tout en indexant un mot et ses variations sous la même clé.

Voir Dissociateurs et lemmatiseurs

Voici un exemple avec python NLTK :

>>> sent = "cats running ran cactus cactuses cacti community communities"
>>> from nltk.stem import PorterStemmer, WordNetLemmatizer
>>>
>>> port = PorterStemmer()
>>> " ".join([port.stem(i) for i in sent.split()])
'cat run ran cactu cactus cacti commun commun'
>>>
>>> wnl = WordNetLemmatizer()
>>> " ".join([wnl.lemmatize(i) for i in sent.split()])
'cat running ran cactus cactus cactus community community'

3 votes

Comme mentionné précédemment, WordNetLemmatizer 's lemmatize() peut prendre une balise POS. Donc, à partir de votre exemple : " ".join([wnl.lemmatize(i, pos=VERB) for i in sent.split()]) donne 'cat run run cactus cactuses cacti community communities' .

0 votes

NickRuiz, je pense que vous vouliez dire pos=NOUN ? BTW : Long time no see, espérons que nous nous rencontrerons bientôt en conférence =)

0 votes

En fait, non (mais j'espère que les conférences auront lieu). Parce que si vous mettez pos=VERB on ne fait de la lemmatisation que sur les verbes. Les noms restent les mêmes. J'ai juste dû écrire un peu de mon propre code pour pivoter autour des balises POS de la Penn Treebank afin d'appliquer la lemmatisation correcte à chaque token. Aussi, WordNetLemmatizer est nul pour lemmatiser le tokenizer par défaut de nltk. Ainsi, des exemples comme does n't ne pas lemmatiser en do not .

9voto

Van Gale Points 21982

La page officielle de Martin Porter contient un Porter Stemmer en PHP ainsi que autres langues .

Si vous voulez vraiment obtenir un bon démembrement, vous devrez commencer par quelque chose comme l'algorithme de Porter, l'affiner en ajoutant des règles pour corriger les cas incorrects communs à votre ensemble de données, et enfin ajouter beaucoup d'exceptions aux règles. Cela peut être facilement mis en œuvre avec des paires clé/valeur (dbm/hash/dictionnaires) où la clé est le mot à rechercher et la valeur est le mot tronqué pour remplacer l'original. Un moteur de recherche commercial sur lequel j'ai travaillé une fois s'est retrouvé avec 800 exceptions à un algorithme Porter modifié.

0 votes

Une solution idéale permettrait d'apprendre ces attentes automatiquement. Avez-vous eu une expérience avec un tel système ?

0 votes

Non. Dans notre cas, les documents indexés étaient les codes et règlements d'un domaine juridique spécifique et des douzaines d'éditeurs (humains) analysaient les index pour détecter toute mauvaise tige.

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