我想计算一些文字中使用了多少个独特单词。棘手的部分是,我想将一个单词的不同形式视为一个单词。例如:
I work.
He works.
I am working.
I have worked.
本文中的独特单词只是这5个:[我,工作,他,我,有]因为有一个(相同)单词的4种不同形式 - 工作。
我觉得我需要一些字典,或者某些图书馆,但经过一些谷歌搜索没有找到任何东西。有人可以帮帮我吗?谢谢!
PS:我知道有些词是完全相同的,但它们的含义是不同的。 (例如:当他离开回家时,离开将覆盖地面)。无论如何,只是忽略这些情况 - 很难掩盖它们+它们很少见,并且不会对结果产生重大影响。答案 0 :(得分:2)
对于英语,您可以使用lucene发行版中的PorterStemmer
。我们的想法是为每个单词保留其词干,并将其存储到一组中。
import java.util.HashSet;
import java.util.Set;
import org.tartarus.snowball.ext.PorterStemmer;
public class Test {
public static void main(String[] args) {
Set<String> stems = new HashSet<>();
PorterStemmer stemmer = new PorterStemmer();
String strings[] = new String[] { "I work.", "He works.",
"I am working.", "I have worked." };
for (String s : strings) {
for (String word : s.split("[\\s\\.]+")) {
stemmer.setCurrent(word);
stemmer.stem();
stems.add(stemmer.getCurrent());
}
}
System.err.println(stems);
}
}
结果:
[work, have, am, I, He]
如果你决定使用lucene,你也可以开始使用lucene的更高级的标记器功能。在上面的例子中,我们只是分为空格和点字符。
答案 1 :(得分:0)
您需要一个stemming库。我没有直接使用过一个(仅通过Lucene的索引过程。在计算频率之前,有一个API可以过滤文本中的单词以删除所有相关单词作为预处理的一部分。
但是存在许多实现,例如this one。
答案 2 :(得分:0)
根据this page hosted by the Stanford NLP Group,您可以使用词干或词形推理来实现您的目标:
词干通常是指粗略的启发式过程,它会切断单词的末尾,以期在大多数时间内正确地实现这一目标,并且通常包括删除派生词缀。 Lemmatization 通常指的是使用词汇和单词的形态分析来正确地做事,通常旨在仅删除屈折结尾并返回单词的基本或字典形式,这被称为引理
从该页面中提供的所有链接中,唯一有效的链接是PorterStemmer,其用法将在另一个答案中解释。
对于词形变换器,请参阅this question here on SO,建议您使用Stanford Core NLP library。