文本相似度算法

时间:2011-04-26 17:27:40

标签: java algorithm text similarity

我正在做一个Java项目,我必须制作文本相似性程序。我希望它能够获取2个文本文档,然后将它们相互比较并获得它的相似性。他们彼此有多相似。

我稍后会放入一个已经可以找到单词同义词的数据库,并通过文本查看其中一个文本文档编写者是否只是将这些单词更改为其他同义词,而文本完全相同。向上或向下移动paragrafs也是如此。 是的,就像一个瘟疫计划......

我想听听你们会推荐什么样的算法。

通过观察这里和其他地方,我发现了Levenstein和Cosine的相似性。他们似乎都被提到了很多。海明距离是我老师告诉我的另一个。

我得到了一些与此相关的问题,因为我并没有真正得到维基百科。有人可以向我解释这些事情吗?

Levenstein :此算法由sub更改,添加和删除单词,并查看它与文本文档中其他单词的接近程度。但是如何在整个文本文件中使用它?我可以看到如何在一个单词上使用它,但不能在一个句子或整个文本文档中使用它。

余弦:它通过测量两个矢量之间角度的余弦来衡量两个矢量之间的相似性。这里我不明白两个文本如何成为2个向量,那些文字/句子怎么样?

汉明:这个距离似乎比Levenstein更好,但它只是在相同的弦上。当2个文件甚至其中的句子不是两个相等长度的字符串时,怎么这么重要?

维基百科应该有意义,但事实并非如此。我很抱歉,如果这些问题听起来太愚蠢了,但它让我失望了,我认为这里有很多人可以解释它,所以即使是这个领域的新手也可以得到它。

感谢您的时间。

3 个答案:

答案 0 :(得分:12)

Levenstein:理论上你可以将它用于整个文本文件,但它真的不适合这项任务。它真的用于单个单词或(最多)短语。

余弦:您只需计算每个文档中的唯一单词即可。一旦你完成了这个计算,previous question的答案将涵盖计算。

我从来没有为此目的使用汉明距离,所以我不能说太多。

我会将TFIDF(Term Frequency * Inverted Document Frequency)添加到列表中。它与余弦距离非常相似,但1)倾向于在较短的文档上做得更好,2)更好地考虑到在整个语料库中哪些词极为常见,而不仅仅是恰好常见的词语两个特定的文件。

最后一点注意:对于任何这些产生有用的结果,你几乎需要在尝试计算相似度之前筛选出停用词(尽管TFIDF似乎比其他更好如果你跳过这个)。至少在我的经验中,阻止单词(删除后缀)也是非常有帮助的。当我完成它时,我使用了Porter的词干分析器算法。

出于您的目的,您可能希望使用我称之为倒置词库的内容,它可以让您查找单词,并且每个单词替换单个规范单词以表示该含义。我在一个项目上试过这个,并没有发现它像预期的那样有用,但听起来对你的项目来说它可能会更有用。

答案 1 :(得分:3)

比较两个文档之间相似性的基本思想,即信息检索的一个主题,是提取一些指纹,判断它们是否基于指纹共享一些信息。

只是一些提示,Winnowing: Local Algorithms for Document Fingerprinting可能是一个选择,也是你问题的良好开端。

答案 2 :(得分:3)

考虑维基百科上Levenshtein距离的例子:

For example, the Levenshtein distance between "kitten" and "sitting" is 3, since the following three edits change one into the other, and there is no way to do it with fewer than three edits:

   1. kitten → sitten (substitution of 's' for 'k')
   2. sitten → sittin (substitution of 'i' for 'e')
   3. sittin → sitting (insertion of 'g' at the end).

现在,将“小猫”替换为“第一篇论文中的文字”,并将“坐着”替换为“第二篇论文中的文字”。

Paper[] papers = getPapers();
for(int i = 0; i < papers.length - 1; i++) {
    for(int j = i + 1; j < papers.length; j++) {
        Paper first = papers[i];
        Paper second = papers[j];
        int dist = compareSimilarities(first.text,second.text);
        System.out.println(first.name + "'s paper compares to " + second.name + "'s paper with a similarity score of " + dist);
    }
}

比较这些结果并将孩子与最低距离分数挂钩。

compareSimilarities方法中,您可以使用任何或所有比较算法。你可以在公式中加入的另一个是“最常见的子串”(这是找到plagerism的好方法。)