文本相似度之Sim_hash算法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文本相似度之Sim_hash算法相关的知识,希望对你有一定的参考价值。
参考技术A 本文记录的目的是方便自己学习和复习,有误之处请谅解,欢迎指出。最近项目有用到Sim_hash,做个简单记录。
Sim_hash是Google用来处理大量文本去重的算法,属于 局部敏感哈希(Locality Sensitive Hashing,LSH) ,LSH哈希能够使两篇只有小部分改动的文章编码后哈希值具有相似性,既可用于去重,也可用于计算相似度。对于只有小部分改动的两篇文章,在计算他们之间的相似度时,如果采用md5,两篇文章的md5编码值差异会非常大。但使用局部敏感哈希可以使相似的文章哈希编码后聚集在一起,删除符合阈值条件的文章,达到去重的效果。
一、算法流程
1)分词:对文本进行去停用词、分词,提取n个关键词和关键词的tf-idf权重来表征文章。如下图分词及权重。
2)关键词哈希编码:每个关键词通过hash函数生成固定位数二进制哈希。
3)权重编码:二进制编码中0调整为-1变为权重向量,与权重相乘。
4)权重编码叠加:将所有权重编码纵向求和,得到最终的文章权重。
5)二值化:按正数为1负数为0的规则将文章权重二值化。
6)汉明距离相似度:排除汉明距离小于阈值的文章,一般设置为3。汉明距离计算速度快,思路简单,原理是计算两个二值化编码相同位置处的不同值的个数。
二、Sim_hash整体流程
需求: 来了一个相似文章推荐需求,需要推荐出与文章内容相似的数据,但又不能完全相似。利用目前库中已有的POI标签和POI权重数据,结合simhash算法,计算出每个文章poi_sim_hash,计算距离
数据: 线上拉取10W文章数据
测试结果: 下图为随机抽样的测试结果(第一条为查询数据),基本 符合预期效果 。前期还可以使用 类目和发布时间 进行前置过滤,减少数据量。
文本相似度算法
【中文标题】文本相似度算法【英文标题】:Text similarity Algorithms 【发布时间】:2011-08-13 05:45:33 【问题描述】:我正在做一个 Java 项目,我必须在其中制作一个文本相似性程序。我希望它获取 2 个文本文档,然后将它们相互比较并获得相似度。它们之间有多么相似。
我稍后会放置一个已经存在的数据库,该数据库可以找到单词的同义词并查看文本以查看文本文档作者是否只是将单词更改为其他同义词而文本完全相同.向上或向下移动 paragrafs 也是如此。 是的,因为它是一个抄袭程序......
我想听听你们会推荐什么样的算法。
通过查看这里和其他地方,我发现了 Levenstein 和 Cosine 的相似性。他们两个似乎都被提及很多。汉明距离是我老师告诉我的另一个距离。
我有一些与这些相关的问题,因为我并没有真正了解***。有人可以向我解释这些事情吗?
Levenstein:这个算法由sub改变,添加和删除单词,看看它与文本文档中的另一个单词有多接近。但是如何在整个文本文件中使用它呢?我可以看到它如何用于一个单词,但不能用于一个句子或从一个到另一个的整个文本文档。
余弦:通过测量两个向量之间夹角的余弦来衡量两个向量之间的相似性。我在这里不明白两个文本如何成为 2 个向量以及其中的单词/句子呢?
Hamming:这个距离似乎比 Levenstein 更好,但它只是在相等的弦上。当 2 个文档甚至其中的句子不是两个长度相等的字符串时,为什么它很重要?
***应该有意义,但事实并非如此。如果这些问题听起来太愚蠢,我很抱歉,但它让我感到沮丧,我认为这里有人非常有能力解释它,所以即使是这个领域的新手也能理解。
感谢您的宝贵时间。
【问题讨论】:
看看:en.wikipedia.org/wiki/Diff#Algorithm 肯定会帮助你,但是,不是从头开始。不如你先来看看我们可以从哪里开始。这就是家庭作业/学校项目的工作方式。 Err..对不起,我没有得到你。我想我确实开始了为什么我要问我不理解的问题。哦,我还没有做程序,我在理解事物的部分。我喜欢在使用它之前得到它。 【参考方案1】:Levenstein:理论上你可以将它用于整个文本文件,但它确实不太适合这项任务。它确实适用于单个单词或(最多)一个短语。
余弦:首先计算每个文档中的唯一单词。完成后,previous question 的答案将涵盖计算。
我从来没有为此目的使用过汉明距离,所以我不能说太多。
我会将 TFIDF(词频 * 倒排文档频率)添加到列表中。它与余弦距离非常相似,但 1) 往往在较短的文档上做得更好,并且 2) 在考虑整个语料库中哪些词非常常见而不仅仅是那些恰好常见的词方面做得更好到两个特定的文档。
最后一点:任何要产生有用的结果,您几乎需要在尝试计算相似度之前筛选掉停用词(尽管 TFIDF 似乎比其他人做得更好如果你跳过这个)。至少根据我的经验,词干(删除后缀)也非常有帮助。完成后,我使用了 Porter 的词干算法。
出于您的目的,您可能想要使用我称之为倒置词库的东西,它可以让您查找一个词,并为每个词替换一个规范词来表示该含义。我在一个项目上试过这个,并没有发现它像预期的那样有用,但听起来对你的项目来说它可能会更有用。
【讨论】:
谢谢。自从我浏览了大多数与相似性相关的主题以来,我确实看到了余弦实现。这是从我迷路的文本部分中理解向量;独特的词,嗯...关于倒叙词库,我将使用这个名为 wordnet 的词汇数据库:wordnet.princeton.edu 这是他们一直在做的一个庞大的项目。不过那是很久以后的事了。现在,在我开始使用它们之前,它已经了解了算法:D 啊,不要介意矢量交易。我刚刚找到了这个很好的例子,可以按照我的喜好向我解释它。如果有人也想读的话,这里就是:***.com/questions/1746501/… 这很好除了,因为 TFIDF 并不是计算相似度的真正解决方案。其目的是确定一个术语对整个文档的重要性。因此,它可用于计算余弦相似度(如您链接到的答案所示)。【参考方案2】:考虑一下 wikipedia 上关于 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).
现在,将“kitten”替换为“第一篇论文中的文字”,将“sitting”替换为“第二篇论文中的文字”。
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
方法中,您可以使用任何或所有比较算法。您可以在公式中加入的另一个是“最长公共子字符串”(这是发现抄袭的好方法。)
【讨论】:
我明白了。所以我们将所有单词保存在一个数组中,然后根据我们比较的算法?所以它可以像示例中一样:Now, replace "kitten" with "text from first paper", and "sitting" with "text from second paper".
这里它可以获取单词 text 然后将它与句子的每个单词进行比较,看看它们有多相似,直到它跳到另一个单词并做完全相同的事情直到最后一个字,然后吐出分数?
我会尝试将论文的文本视为一个巨大的单词。
嗯...所以“texfromthefirstpaper”和“textfromthesecondpaper”,然后比较它们。虽然如果我取第二个大词并写下“thesecondpaperstext”,那会不会给出完全不同的结果,因为它似乎是按字符串比较的? O.o 那么我是否正确,虽然第一个会给出更相似的结果,但第二个根本不会?【参考方案3】:
信息检索中比较两个文档相似度的基本思想是提取一些指纹,并根据指纹判断它们是否共享一些信息。
只是一些提示,Winnowing: Local Algorithms for Document Fingerprinting 可能是您解决问题的一个选择和一个很好的起点。
【讨论】:
谢谢,我明天早餐后去看看。^^ 我读过。我不能说这就是我想要的。虽然头疼;p以上是关于文本相似度之Sim_hash算法的主要内容,如果未能解决你的问题,请参考以下文章