我该如何进行词干提取或词形归并?

114

28
那应该是仙人掌吧? - MSalters
3
只是为了循环引用Reddit上发布的原始问题: [如何以编程方式进行词干提取? (例如,“eating”变为“eat”,“cactuses”变为“cactus”)](http://www.reddit.com/r/programming/comments/8e5d3/how_do_i_programatically_do_stemming_eg_eating_to/)在此发布,因为评论包含有用的信息。 - Renaud Bompuis
1
请参见 https://dev59.com/4WQm5IYBdhLWcg3w0Bq5 - alvas
22个回答

2

3
欢迎来到SO,感谢您的发布,+1。如果您能对这个词干算法的使用、性能等方面进行一些评论,那就太好了。仅提供一个链接通常被认为不是一个很好的答案。 - jogojapan

1

您可以使用Morpha词干提取器。如果您计划从Java应用程序中使用它,UW已经将 Morpha词干提取器上传到Maven中央。有一个包装器使其更容易使用。您只需要将其添加为依赖项,然后使用 edu.washington.cs.knowitall.morpha.MorphaStemmer 类即可。实例是线程安全的(原始的JFlex对于不必要的局部变量使用了类字段)。实例化一个类并运行morpha和您想要提取词干的单词。

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

1

搜索一下Lucene,我不确定是否有PHP端口,但我知道Lucene可用于许多平台。Lucene是一个开源(来自Apache)索引和搜索库。自然地,它和社区的额外功能可能有一些有趣的东西可以看看。至少你可以学习如何在一种语言中完成它,以便将“想法”翻译成PHP。


1

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

核心问题在于词干算法是基于语音基础运作的,对其所处理的语言实际上并没有理解。

由于它们没有对术语字典进行运行,也无法识别和适当地响应不规则情况,例如“run”/“ran”等,因此它们没有语言理解。

如果您需要处理不规则情况,您需要选择不同的方法或增加自己的自定义修正词典,在词干处理完成后运行。


1

0

试试这个链接: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"
  )
);

0
在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
}

0

Martin Porter编写了Snowball(一种用于词干算法的语言),并在Snowball中重写了“英语词干提取器”。C和Java都有英语词干提取器。

他明确表示,波特词干提取器仅出于历史原因被重新实现,因此针对波特词干提取器进行词干提取正确性测试将得到您(应该)已知道的结果。

来自http://tartarus.org/~martin/PorterStemmer/index.html(我强调)

波特词干提取器应被视为“冻结”,即严格定义,不可进一步修改。作为一个词干提取器,它略逊于Snowball英语或Porter2词干提取器,后者源自它,并经过偶尔的改进。因此,建议使用新的Snowball词干提取器进行实际工作。波特词干提取器适用于涉及词干提取的IR研究工作,其中实验需要完全可重复。

Porter博士建议使用英语或Porter2词干分析器,而不是Porter词干分析器。正如@StompChicken之前所回答的那样,英语词干分析器实际上是演示网站中使用的。


0

在.Net Lucene中,有一个内置的Porter词干提取器。你可以尝试使用它。但请注意,Porter词干提取并不考虑单词上下文来推导词形还原。(仔细阅读算法和其实现,你就会了解它是如何工作的)


0

我强烈推荐使用Spacy(基础的文本解析和标注)和Textacy(在Spacy上构建的高级文本处理工具)。

在Spacy中,默认情况下可以使用词形还原功能,通过令牌的.lemma_属性获取。在进行很多其他文本预处理操作时,也可以使用textacy进行词形还原。例如,在创建一组术语 或单词时,或者在执行需要词形还原的某些处理之前。

在编写任何代码之前,我鼓励您先了解这两个工具,因为这可能会节省您很多时间!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接