man*_*ock 109 nlp stemming lemmatization
我已经尝试过PorterStemmer和Snowball,但两个都不能用于所有单词,缺少一些非常常见的单词.
我的测试词是:" 猫跑仙人掌仙人掌仙人掌社区社区 ",两者都不到一半.
也可以看看:
the*_*rty 142
如果你了解Python,那么自然语言工具包(NLTK)就有一个非常强大的使用WordNet的变形器.
请注意,如果您是第一次使用此词形变换器,则必须在使用它之前下载语料库.这可以通过以下方式完成:
>>> import nltk
>>> nltk.download('wordnet')
Run Code Online (Sandbox Code Playgroud)
你只需要这样做一次.假设您现在已经下载了语料库,它的工作原理如下:
>>> 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'
Run Code Online (Sandbox Code Playgroud)
nltk.stem模块中还有其他的引理器,但我自己没有尝试过.
CTs*_*rth 29
我使用stanford 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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果稍后在分类器中使用,则使用停用词来最小化输出引理也可能是个好主意.请查看John Conwell撰写的coreNlp扩展.
Sto*_*ken 24
我在这个雪球演示网站上尝试了你的术语列表,结果看起来还不错....
一个词干分子应该将变形的词汇转换成一些共同的词根.将root作为一个"正确的"词典单词并不是一个干扰者的工作.为此,您需要查看形态/正交分析仪.
我认为这个问题或多或少是相同的,Kaarel对这个问题的回答是我从第二个链接开始的.
alv*_*vas 20
词干与引理论辩论还在继续.这是一个优于精确而不是效率的问题.你应该使用lemotize来获得语言上有意义的单位,并且使用最少的计算成果,并且仍然在同一个键下索引一个单词及其变体.
这是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'
Run Code Online (Sandbox Code Playgroud)
Martin Porter的官方页面包含PHP中的Porter Stemmer以及其他语言.
如果您真的认真考虑好干预,虽然您需要从像Porter算法这样的东西开始,通过添加规则来修改它来修复数据集常见的不正确的情况,然后最后添加很多例外规则.这可以通过键/值对(dbm/hash/dictionaries)轻松实现,其中键是要查找的单词,值是用于替换原始单词的词干单词.我曾经使用的商业搜索引擎最终得到了一些改进的Porter算法的800个例外.
根据我遇到的 Stack Overflow 和博客上的各种答案,这是我正在使用的方法,它似乎可以很好地返回真实单词。这个想法是将传入的文本分成一组单词(使用您喜欢的任何方法),然后找到这些单词的词性 (POS) 并使用它来帮助词干和词形还原。
您上面的示例效果不佳,因为无法确定 POS。但是,如果我们使用真正的句子,事情会好得多。
import 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', '.']
Run Code Online (Sandbox Code Playgroud)
http://wordnet.princeton.edu/man/morph.3WN
对于我的很多项目,我更喜欢基于词典的WordNet lemmatizer而不是更具攻击性的搬运工.
http://wordnet.princeton.edu/links#PHP有一个指向WN API的PHP接口的链接.
搜索 Lucene,我不确定是否有 PHP 端口,但我知道 Lucene 可用于许多平台。Lucene 是一个 OSS(来自 Apache)索引和搜索库。当然,它和社区的额外内容可能会有一些有趣的东西值得一看。至少您可以了解它是如何用一种语言完成的,这样您就可以将“想法”翻译成 PHP。
| 归档时间: |
|
| 查看次数: |
128543 次 |
| 最近记录: |