使用 Apache Lucene 进行词形还原

10
我正在使用Apache Lucene开发一个文本分析项目。我需要对一些文本进行词形归并(将单词转换为它们的标准形式)。我已经编写了代码进行词干提取(stemming)。使用它,我可以将以下句子转换为:
"stem part word never chang even when morpholog inflect lemma base form word exampl from produc lemma produc stem produc becaus word product"
但是,我需要获取单词的基本形式:例如,需要获取"example"而不是"exampl","produce"而不是"produc"等。
我使用Lucene是因为它有许多语言的分析器(我至少需要英语和俄语)。我知道有Stanford NLP库,但它没有俄语支持。
那么有没有办法像我用Lucene做词干提取一样对多种语言进行词形还原(Lemmatization)呢?
以下是我的词干提取代码的简化版本:
//Using apache tika to identify the language
LanguageIdentifier identifier = new LanguageIdentifier(text);
//getting analyzer according to the language (eg, EnglishAnalyzer for 'en')
Analyzer analyzer = getAnalyzer(identifier.getLanguage());
TokenStream stream = analyzer.tokenStream("field", text);
stream.reset();
while (stream.incrementToken()) {
    String stem = stream.getAttribute(CharTermAttribute.class).toString();
    // doing something with the stem
    System.out.print(stem+ " ");
}
stream.end();
stream.close();

更新:我找到了library,它几乎可以满足我的需求(对于英语和俄语),并使用Apache Lucene(虽然是以自己的方式),值得探索。


你最后找到了使用Apache Lucene进行词形还原的方法吗? - Jamie Birch
嗨@Jamie!感谢您关注这个问题。不幸的是,除了我在更新中提到的那个库之外,我没有找到任何东西。它运行良好,但仅支持英语和俄语。 - Kirill Simonov
2个回答

2
如果还有人需要,我决定回答这个问题并说明如何使用之前找到的 russianmorphology 库来对英语和俄语进行词形还原。首先,除了 lucene-core 之外,您还需要这些 依赖项
<!-- if you need Russain -->
<dependency>
    <groupId>org.apache.lucene.morphology</groupId>
    <artifactId>russian</artifactId>
    <version>1.1</version>
</dependency>

<!-- if you need English-->
<dependency>
    <groupId>org.apache.lucene.morphology</groupId>
    <artifactId>english</artifactId>
    <version>1.1</version>
</dependency>

<dependency>
    <groupId>org.apache.lucene.morphology</groupId>
    <artifactId>morph</artifactId>
    <version>1.1</version>
</dependency>

接下来,请确保导入正确的分析器:

import org.apache.lucene.morphology.english.EnglishAnalyzer;
import org.apache.lucene.morphology.russian.RussianAnalyzer;

这些分析器与标准的Lucene分析器不同,它们使用MorphologyFilter将每个单词转换为其正常形式的集合。

因此,如果您使用以下代码:

String text = "The stem is the part of the word that never changes even when morphologically inflected; a lemma is the base form of the word. For example, from \"produced\", the lemma is \"produce\", but the stem is \"produc-\". This is because there are words such as production";
Analyzer analyzer = new EnglishAnalyzer();
TokenStream stream = analyzer.tokenStream("field", text);
stream.reset();
while (stream.incrementToken()) {
    String lemma = stream.getAttribute(CharTermAttribute.class).toString();
    System.out.print(lemma + " ");
}
stream.end();
stream.close();

它会打印

词干是单词的一部分,即使在形态上变化时也不会改变。屈折变化的基本形式是单词的引导形式。例如,从“produced”产生“produce”,引导形式是“produce”,但词干是“produc”。这是因为有像“production”这样的单词。

对于俄语文本

String text = "Продолжаю цикл постов об астрологии и науке. Астрология не имеет научного обоснования, но является частью истории науки, частью культуры и общественного сознания. Поэтому астрологический взгляд на науку весьма интересен.";
RussianAnalyzer会输出以下内容:

继续循环帖子关于占星术和占星术不具有科学依据,但是它是科学历史的一部分,是文化和社会意识的一部分,因此对科学的占星术观点非常有趣。

您可能会注意到一些单词具有多个基本形式,例如inflected被转换为[inflected, inflect]。如果您不喜欢这种行为,则需要更改org.apache.lucene.morphology.analyzer.MorhpologyFilter的实现(如果您想了解如何做到这一点,请告诉我,我将详细说明)。
希望能帮到您,祝好运!

1
Yep,StanfordNLP 对英语很好。但如果您需要支持多种语言,我可以向您推荐Freeling,请查看其Freeling_online_demo,请选择语言和输出(用于词形还原的形态分析)。我不会说俄语,但我认为它适用于这段文本:

我继续发布有关占星术和科学的文章。占星术没有科学依据,但是它是科学历史、文化和社会意识的一部分。因此,对科学的占星术观点非常有趣。

为了机器可读性,您可以使用xml输出(在您的结果下面),为了自动化,您可以将Freeling与python/java集成,但通常我更喜欢通过命令行调用它。

谢谢您的推荐!我一定会尝试在我的项目中使用这个工具。唯一的缺点是它是一个C++库,因此无法完全集成到Java项目中。 - Kirill Simonov
很高兴能够提供帮助。关于Java,我认为你可以使用这个Freeling_APIS来解决问题,虽然它不是完全集成的,但是Freeling的创建者提供了适用于Linux/Windows的Java APIS。 - Jason Angel
Freeling有词形还原器吗? - StackUser
是的,它有。如果您执行POS标记器,则可以看到词元。 - Jason Angel

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