我使用 lucene 雪球分析器来执行词干提取。结果是没有意义的话。我提到了这个问题。
一种解决方案是使用一个数据库,该数据库包含一个词的词干版本与一个稳定版本的词之间的映射。(从社区到社区的示例,无论社区的基础是什么(社区/或其他词))
我想知道是否有执行此类功能的数据库。
我使用 lucene 雪球分析器来执行词干提取。结果是没有意义的话。我提到了这个问题。
一种解决方案是使用一个数据库,该数据库包含一个词的词干版本与一个稳定版本的词之间的映射。(从社区到社区的示例,无论社区的基础是什么(社区/或其他词))
我想知道是否有执行此类功能的数据库。
从一个词干中恢复一个特定的词在理论上是不可能的,因为一个词干可以为许多词所共有。根据您的应用程序,一种可能性是构建一个词干数据库,每个词干映射到一个由多个单词组成的数组。但是你需要预测其中哪个词是合适的,给定一个要重新转换的词干。
作为这个问题的一个非常幼稚的解决方案,如果您知道单词标签,您可以尝试将带有标签的单词存储在数据库中:
run:
NN: runner
VBG: running
VBZ: runs
然后,给定词干“run”和标签“NN”,您可以确定“runner”是该上下文中最可能的词。当然,这种解决方案远非完美。值得注意的是,您需要处理相同的词形在不同的上下文中可能被不同的标记这一事实。但请记住,解决这个问题的任何尝试充其量只是一个近似值。
编辑:从下面的评论来看,您可能想要使用词形还原而不是词干提取。以下是使用斯坦福核心 NLP 工具获取单词引理的方法:
import java.util.*;
import edu.stanford.nlp.pipeline.*;
import edu.stanford.nlp.ling.*;
import edu.stanford.nlp.ling.CoreAnnotations.*;
Properties props = new Properties();
props.put("annotators", "tokenize, ssplit, pos, lemma");
pipeline = new StanfordCoreNLP(props, false);
String text = "Hello, world!";
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);
}
}
您所引用的问题包含一条经常被忽视的重要信息。您需要的被称为“词形还原” - 将屈折词还原为其规范形式。它与词干相关但不同,仍然是一个开放的研究问题。对于形态更复杂的语言来说尤其困难(英语没那么难)。维基百科有一个您可以尝试的软件列表。我使用的另一个工具是TreeTagger - 它非常快速且相当准确,尽管它的主要目的是词性标记,并且词形还原只是一个奖励。尝试在谷歌上搜索“统计词形还原”(是的,我确实对统计与基于规则的 NLP 有强烈的感觉)
您可能会查看NCI Metathesaurus —— 虽然本质上主要是生物医学,但它们提供了自然语言处理的示例和一些用于 Java 的开源工具集,通过浏览它们的代码可能会发现它们很有用。
您可能会喜欢这个开源项目,它使用词干提取并包含一种算法来进行反向词干提取:
在项目的这个页面上,有关于如何进行反向词干的解释。总而言之,它的工作原理如下。
首先,您将提取一些文档,这里是删除停用词的简短(法语)字符串,例如:
['sup chat march trottoir',
'sup chat aiment ronron',
'chat ronron',
'sup chien aboi',
'deux sup chien',
'combien chien train aboi']
然后诀窍是保留最流行的原始单词的计数以及每个词干单词的计数:
{'aboi': {'aboie': 1, 'aboyer': 1},
'aiment': {'aiment': 1},
'chat': {'chat': 1, 'chats': 2},
'chien': {'chien': 1, 'chiens': 2},
'combien': {'Combien': 1},
'deux': {'Deux': 1},
'march': {'marche': 1},
'ronron': {'ronronner': 1, 'ronrons': 1},
'sup': {'super': 4},
'train': {'train': 1},
'trottoir': {'trottoir': 1}}
最后,您现在可能会猜到如何自己实现它。只需取给定词干词最重要的原始词。您可以参考以下实现,它在 MIT 许可下作为Multilingual-Latent-Dirichlet-Allocation-LDA项目的一部分提供: