我已经尝试了PorterStemmer和Snowball,但它们都无法处理所有单词,错过了一些非常常见的单词。
我的测试单词是:“cats running ran cactus cactuses cacti community communities”,但两者都只有不到一半的正确率。
另请参阅:
我已经尝试了PorterStemmer和Snowball,但它们都无法处理所有单词,错过了一些非常常见的单词。
我的测试单词是:“cats running ran cactus cactuses cacti community communities”,但两者都只有不到一半的正确率。
另请参阅:
>>> import nltk
>>> nltk.download('wordnet')
您只需要执行一次此操作。假设您现在已经下载了语料库,它的工作方式如下:
>>> 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'
在nltk.stem模块中还有其他的词形还原器,但我自己没有尝试过。
WordNetLemmatizer
错误还原词形的单词有哪些? - alvas我使用斯坦福NLP进行词形还原。在过去的几天里,我一直卡在了一个类似的问题上。感谢stackoverflow帮助我解决了这个问题。
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);
}
}
}
}
如果后面的分类器要使用词形还原的结果,建议使用停用词来减少输出结果。请查看 John Conwell 编写的coreNLP扩展。
我在这个Snowball演示网站上尝试了您的术语列表,结果看起来还不错...
一个词干提取器应该将单词的屈折形式转化为一些常见的词根形式。词干提取器的工作并不是使这个词根成为一个“正确”的词典词汇。要做到这一点,您需要查看形态/正字分析器。
我认为这个问题大致也是关于同样的事情,Kaarel对那个问题的回答是我从中获取第二个链接的地方。
词干提取器(stemmer)与词形还原器(lemmatizer)的辩论仍在继续。这是一个关于精度和效率之间偏好的问题。你应该进行词形还原以实现语言学上有意义的单位,而进行词干提取则能够使用最少的计算资源来将单词及其变体索引到相同的键下。
以下是使用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'
pos=NOUN
吧?顺便说一句:好久不见了,希望我们很快能在会议上见面 =) - alvaspos=VERB
,你只对动词进行词形还原。名词保持不变。我不得不编写一些自己的代码来绕过实际的Penn Treebank POS标签,以对每个令牌应用正确的词形还原。此外,WordNetLemmatizer
在对nltk的默认分词器进行词形还原时效果不佳。所以像does n't
这样的例子无法还原为do not
。 - Nick Ruizport.stem("this")
产生 thi
,而 port.stem("was")
则产生 wa
,即使为每个单词提供了正确的 pos。 - Lerner Zhangimport nltk
from nltk.corpus import wordnet
lmtzr = nltk.WordNetLemmatizer().lemmatize
def get_wordnet_pos(treebank_tag):
if treebank_tag.startswith('J'):
return wordnet.ADJ
elif treebank_tag.startswith('V'):
return wordnet.VERB
elif treebank_tag.startswith('N'):
return wordnet.NOUN
elif treebank_tag.startswith('R'):
return wordnet.ADV
else:
return wordnet.NOUN
def normalize_text(text):
word_pos = nltk.pos_tag(nltk.word_tokenize(text))
lemm_words = [lmtzr(sw[0], get_wordnet_pos(sw[1])) for sw in word_pos]
return [x.lower() for x in lemm_words]
print(normalize_text('cats running ran cactus cactuses cacti community communities'))
# ['cat', 'run', 'ran', 'cactus', 'cactuses', 'cacti', 'community', 'community']
print(normalize_text('The cactus ran to the community to see the cats running around cacti between communities.'))
# ['the', 'cactus', 'run', 'to', 'the', 'community', 'to', 'see', 'the', 'cat', 'run', 'around', 'cactus', 'between', 'community', '.']
http://wordnet.princeton.edu/man/morph.3WN
对于我的许多项目,我更喜欢基于词汇的WordNet词形还原器,而不是更具攻击性的porter词干提取器。 http://wordnet.princeton.edu/links#PHP有一个链接到WN APIs的PHP接口。针对词形还原,最常用的 Python 包(无特定顺序)包括:spacy
、nltk
、gensim
、pattern
、CoreNLP
和 TextBlob
。我更喜欢 spaCy 和 gensim 的实现方式(基于 pattern),因为它们可以自动识别单词的 POS 标签并分配适当的词元。这样可以得到更相关的词元,保持意义不变。
如果您计划使用 nltk 或 TextBlob,则需要手动找到正确的 POS 标签并找到正确的词元。
spaCy 词形还原示例:
# Run below statements in terminal once.
pip install spacy
spacy download en
import spacy
# Initialize spacy 'en' model
nlp = spacy.load('en', disable=['parser', 'ner'])
sentence = "The striped bats are hanging on their feet for best"
# Parse
doc = nlp(sentence)
# Extract the lemma
" ".join([token.lemma_ for token in doc])
#> 'the strip bat be hang on -PRON- foot for good'
使用 Gensim 进行词形还原的例子:
from gensim.utils import lemmatize
sentence = "The striped bats were hanging on their feet and ate best fishes"
lemmatized_out = [wd.decode('utf-8').split('/')[0] for wd in lemmatize(sentence)]
#> ['striped', 'bat', 'be', 'hang', 'foot', 'eat', 'best', 'fish']
请看LemmaGen -一款用C#3.0编写的开源库。
测试词汇结果(http://lemmatise.ijs.si/Services)