如何做词干或词形化?

我已经尝试了PorterStemmer和Snowball,但都不适用于所有的单词,缺less一些非常常见的单词。

我的testing词是:“ 跑仙人掌仙人掌仙人掌社区社区 ”,都得到不到一半的权利。

也可以看看:

  • 产生真实词汇的词干algorithm
  • 梗阻 – 代码示例或开源项目?

如果您了解Python, 自然语言工具包(NLTK)有一个非常强大的使用WordNet的lemmatizer 。

请注意,如果您是第一次使用该lemmatizer,则必须在使用该语料库之前下载该语料库。 这可以通过以下方式完成:

>>> 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模块中还有其他的迷惑者 ,但是我自己没有尝试过。

我使用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); } } } } 

如果稍后在分类器中使用停用词来减less输出引理,也可能是一个好主意。 请看John Conwell写的coreNlp扩展。

我尝试了这个雪球演示网站上的条款列表,结果看起来不错….

  • 猫 – >猫
  • 运行 – >运行
  • 跑 – >跑
  • 仙人掌 – >仙人掌
  • 仙人掌 – >仙人掌
  • 社区 – >社区
  • 社区 – >共享

一个词干员应该把变化的forms转化为一些共同的词根。 把根作为一个“正确的”词典并不是词干的工作。 为此,您需要查看形态/正交分析器 。

我认为这个问题差不多是一回事,卡雷尔对这个问题的回答是我从第二个环节开始的。

词干与lemmatizer辩论继续。 精确而不是效率是一个问题。 你应该推理,以达到语言上有意义的单位,并尽量使用最小的计算果汁,并仍然在同一个关键字索引单词及其变化。

见Stemmers vs Lemmatizers

这里是一个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' 

马丁波特的官方网页包含一个PHP的Porter Stemmer以及其他语言 。

如果你真的认真对待好的阻塞,尽pipe你需要从Porteralgorithm开始,通过添加规则来修正你的数据集中常见的错误情况,然后在规则中添加很多例外。 这可以通过键/值对(dbm / hash / dictionaries)轻松实现,其中键是要查找的单词,值是replace原始单词的词干。 我曾经工作过的一个商业search引擎最终有800个例外的修改后的Porteralgorithm。

http://wordnet.princeton.edu/man/morph.3WN

对于我的很多项目,我更喜欢基于词汇的WordNet lemmatizer,而不是更激进的porter stemming。

http://wordnet.princeton.edu/links#PHP有一个指向WN API的PHP接口的链接。

看看WordNet这个英语的大型词汇数据库:

http://wordnet.princeton.edu/

有几种语言访问它的API。

这看起来很有趣:MIT Java WordnetStemmer: http ://projects.csail.mit.edu/jwi/api/edu/mit/jwi/morph/WordnetStemmer.html

做一个search的Lucene,即时消息不知道如果这是一个PHP端口,但我知道Lucene是可用于许多平台。 Lucene是一个OSS(来自Apache)的索引和search库。 当然,它和社区的额外可能有一些有趣的东西来看待。 至less你可以学习如何在一种语言中完成,所以你可以把“想法”翻译成PHP

如果我可以引用我对StompChicken提到的问题的回答:

这里的核心问题是,干扰algorithm在语音的基础上运行,没有真正理解他们正在使用的语言。

由于他们对语言不了解,也没有从术语辞典中摸索出来,对于“跑”,“跑”等不规范的情况,也无法正确认识和回应。

如果你需要处理不规则的情况,你需要select一种不同的方法,或者扩大你自己的自定义词典的修正,在词干分工完成之后运行。

NLTK中的最新版本的stemmer是Snowball。

你可以在这里find如何使用它的例子:

http://nltk.googlecode.com/svn/trunk/doc/api/nltk.stem.snowball2-pysrc.html#demo

你可以使用Morpha stemmer。 如果您计划从Java应用程序使用它,UW已经将morpha stemmer上传到了Maven central 。 有一个包装,使它更容易使用。 您只需要将其添加为依赖项并使用edu.washington.cs.knowitall.morpha.MorphaStemmer类。 实例是线程安全的(原始的JFlex有不必要的本地variables的类字段)。 实例化一个类并运行morpha和你morpha的单词。

 new MorphaStemmer().morpha("climbed") // goes to "climb" 

看看LemmaGen – 用C#3.0编写的开源库。

你的testing结果( http://lemmatise.ijs.si/Services

  • 猫 – >猫
  • 赛跑
  • 跑 – >跑
  • 仙人掌
  • 仙人掌 – >仙人掌
  • 仙人掌 – >仙人掌
  • 社区
  • 社区 – >社区

.Net lucene有一个内置的porter stemmer。 你可以试试。 但要注意的是,在导出引理时,搬运工词根并不考虑词语的上下文。 (通过algorithm及其实现,你会看到它是如何工作的)

马丁·波特(Martin Porter)写了“雪球”(Snowball,一种干扰algorithm的语言),并重写了“雪球”中的“英语Stemmer”。 C和Java有一个英文Stemmer。

他明确指出Porter Stemmer 只是出于历史原因而被重新实现,所以testing对Porter Stemmer的正确性testing会得到你应该已经知道的结果。

http://tartarus.org/~martin/PorterStemmer/index.html (重点是我的)

波特词干应视为“ 冻结 ”,即严格界定,不适宜进一步修改。 作为一个词干,它稍微逊色于雪球英语或波特2词干,它源于它,并偶尔有所改善。 因此,对于实际工作,build议使用新的Snowball推杆。 波特词干是适合涉及干扰的研究工作,在哪里实验需要是完全可重复的。

波特博士build议使用英语或波特2词干代替波特词干。 英文词干是在演示网站实际使用的@StompChicken早些时候回答的。

在Java中,我使用tartargus-snowball来填词

Maven的:

 <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-snowball</artifactId> <version>3.0.3</version> <scope>test</scope> </dependency> 

示例代码:

 SnowballProgram stemmer = new EnglishStemmer(); String[] words = new String[]{ "testing", "skincare", "eyecare", "eye", "worked", "read" }; for (String word : words) { stemmer.setCurrent(word); stemmer.stem(); //debug logger.info("Origin: " + word + " > " + stemmer.getCurrent());// result: test, skincar, eyecar, eye, work, read } 

试试这个: http : //www.twinword.com/lemmatizer.php

我在演示"cats running ran cactus cactuses cacti community communities"并得到了["cat", "running", "run", "cactus", "cactus", "cactus", "community", "community"]与可选标志ALL_TOKENS

示例代码

这是一个API,所以你可以从任何环境连接到它。 以下是PHP REST调用的样子。

 // These code snippets use an open-source library. http://unirest.io/php $response = Unirest\Request::post([ENDPOINT], array( "X-Mashape-Key" => [API KEY], "Content-Type" => "application/x-www-form-urlencoded", "Accept" => "application/json" ), array( "text" => "cats running ran cactus cactuses cacti community communities" ) ); 
Interesting Posts