我已经尝试了PorterStemmer和Snowball,但它们都无法处理所有单词,错过了一些非常常见的单词。
我的测试单词是:“cats running ran cactus cactuses cacti community communities”,但两者都只有不到一半的正确率。
另请参阅:
我已经尝试了PorterStemmer和Snowball,但它们都无法处理所有单词,错过了一些非常常见的单词。
我的测试单词是:“cats running ran cactus cactuses cacti community communities”,但两者都只有不到一半的正确率。
另请参阅:
您可以使用Morpha词干提取器。如果您计划从Java应用程序中使用它,UW已经将 Morpha词干提取器上传到Maven中央。有一个包装器使其更容易使用。您只需要将其添加为依赖项,然后使用 edu.washington.cs.knowitall.morpha.MorphaStemmer
类即可。实例是线程安全的(原始的JFlex对于不必要的局部变量使用了类字段)。实例化一个类并运行morpha
和您想要提取词干的单词。
new MorphaStemmer().morpha("climbed") // goes to "climb"
搜索一下Lucene,我不确定是否有PHP端口,但我知道Lucene可用于许多平台。Lucene是一个开源(来自Apache)索引和搜索库。自然地,它和社区的额外功能可能有一些有趣的东西可以看看。至少你可以学习如何在一种语言中完成它,以便将“想法”翻译成PHP。
如果我可以引用我对StompChicken提出的问题的回答:
核心问题在于词干算法是基于语音基础运作的,对其所处理的语言实际上并没有理解。
由于它们没有对术语字典进行运行,也无法识别和适当地响应不规则情况,例如“run”/“ran”等,因此它们没有语言理解。
如果您需要处理不规则情况,您需要选择不同的方法或增加自己的自定义修正词典,在词干处理完成后运行。
NLTK 中最新的词干提取器版本是 Snowball。
您可以在此处找到如何使用它的示例:
http://nltk.googlecode.com/svn/trunk/doc/api/nltk.stem.snowball2-pysrc.html#demo
试试这个链接:http://www.twinword.com/lemmatizer.php
我在演示中输入了您的查询 "cats running ran cactus cactuses cacti community communities"
并使用可选标志 ALL_TOKENS
得到了结果 ["cat", "running", "run", "cactus", "cactus", "cactus", "community", "community"]
。
示例代码
这是一个 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"
)
);
<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
}
Martin Porter编写了Snowball(一种用于词干算法的语言),并在Snowball中重写了“英语词干提取器”。C和Java都有英语词干提取器。
他明确表示,波特词干提取器仅出于历史原因被重新实现,因此针对波特词干提取器进行词干提取正确性测试将得到您(应该)已知道的结果。
来自http://tartarus.org/~martin/PorterStemmer/index.html(我强调)
波特词干提取器应被视为“冻结”,即严格定义,不可进一步修改。作为一个词干提取器,它略逊于Snowball英语或Porter2词干提取器,后者源自它,并经过偶尔的改进。因此,建议使用新的Snowball词干提取器进行实际工作。波特词干提取器适用于涉及词干提取的IR研究工作,其中实验需要完全可重复。
Porter博士建议使用英语或Porter2词干分析器,而不是Porter词干分析器。正如@StompChicken之前所回答的那样,英语词干分析器实际上是演示网站中使用的。
在.Net Lucene中,有一个内置的Porter词干提取器。你可以尝试使用它。但请注意,Porter词干提取并不考虑单词上下文来推导词形还原。(仔细阅读算法和其实现,你就会了解它是如何工作的)
我强烈推荐使用Spacy(基础的文本解析和标注)和Textacy(在Spacy上构建的高级文本处理工具)。
在Spacy中,默认情况下可以使用词形还原功能,通过令牌的.lemma_
属性获取。在进行很多其他文本预处理操作时,也可以使用textacy进行词形还原。例如,在创建一组术语 或单词时,或者在执行需要词形还原的某些处理之前。
在编写任何代码之前,我鼓励您先了解这两个工具,因为这可能会节省您很多时间!