求海量文本中两两相似文本的快速算法
来源:互联网 发布:淘宝苹果数据线 编辑:程序博客网 时间:2024/06/06 00:49
问题描述
这个问题的输入是一个文本语料库,输出是语料库中相似度大于某个阈值的所有文本对,阈值可以是0.9或者0.8.
举个例子,比如我的输入是下面的语料库,我的阈值是0.6,我的相似度度量用的是文本中以字为单位的jaccard相似度
1. 福禄很可爱
2. 福禄真可爱
3. 福禄是可爱
4. 阿里巴巴牛逼
5. 阿里巴巴很牛逼
我的输出是:
文档ID文档ID相似度
1 2 0.66
1 3 0.66
4 5 0.8
暴力求解
看我上面的例子你可能觉得这很简单吗?大不了我用暴力计算,来一个二重循环,把语料库整个遍历一遍,不就算出来了吗?如果语料库中的文本数少,这么搞当然可以。
假设语料库中的文本数是N,这么算的复杂度是O(n^2),对海量文本来说,这简直是灾难,此路不通;
map-reduce思路
大数据时代,我们其实不缺计算资源,暴力求解的思路可以有map reduce的方法来求解
图1就是这个问题的一个map reduce解法的例子 ,其中RID代表文档号,a列是原始文本
图1 MAP reduce解法示例
Map-Reduce解法中的map过程,其实就是一个建立倒排索引的过程,我们真的有必要对所有token都建立倒排索引吗?
还记得‘抽屉原理’吗?
若x,y是两个按照token排序(比如按照字母表顺序)的集合,O(x,y)>=a,则必然有x排在前面的|x|-a+1个token
和y的排在前面|y|-a+1个token中至少有一个重合。
如何证明这个呢?反证法呀
假设结论不成立,则必然推出结论O(x,y) < a (这里不解释,自己去想吧),得出矛盾
如果文本已经按照token排序,那么我们在建倒排索引的时候,其实就没有必要把一个文本中所有的token都建索引,
只需对前面|x|-a+1个建立索引即可。我们就得到第二个过滤原则,即前缀过滤原则
前缀过滤原则:对于已经按照token排序的文本x,y,若O(x,y)>=a,则x,y的长度为|x|-a+1的前缀和长度为|y|-a+1的前缀
至少有一个token重合.
按照前缀过滤原则,我们在MAP阶段(倒排索引建立阶段),可以不必对所有的token建立索引。
回头看(1),和(3)式,前缀过滤原则最终可以转换成对于一个按token排序的文本x,只需索引长度为
的前缀中的token。还是来看个例子吧
对于下面的一组语料,我们只需索引标红的token
w =[C, D, F ]
z =[A, B, E, F,H ]
y =[ A, B,C, D, E]
x =[ B,C, D, E, F ]
我们给出一个完整的算法,PPjoin
这就是PPjoin算法,虽然PPjoin还有一些细节可以优化,但这里不再赘述。
我使用PPjoin算法对几百万个文本,阈值设为0.9最终1个小时左右跑出了所有相似度大于0.9的文本。当然,我是
在阿里的ODPS里面跑的,若是你用的其他的平台,这个时间仅供参考。
资源
源代码 https://code.google.com/p/ppjoinplus/
PPjoin 论文 http://www.cse.unsw.edu.au/~weiw/files/TODS-PPJoin-Final.pdf
声明:本文是我参考PPjoin论文写的读书笔记,文正的图片和算法步骤都是出自论文,本文是博主原创,转载请注明出处
- 求海量文本中两两相似文本的快速算法
- 文本求相似度
- Oracle 求文本相似度的问题
- 文本相似度算法
- 文本相似度算法
- 文本相似度算法
- 文本相似度算法
- 文本相似度算法
- 文本相似度算法
- 文本相似度算法
- 文本相似度的那些算法
- [转]文本相似度算法
- 文本相似度-BM25算法
- 文本分析系列——基于相似哈希信息指纹的文本相似度算法
- 海量数据文本相似度解决方式SimHash+分词方法+基于内容推荐算法
- 几种文本相似度算法的C++实现
- 文本比较算法Ⅲ——计算文本的相似度
- 文本比较算法Ⅲ——计算文本的相似度
- Python相关常用库概念介绍
- IntelliJ IDEA 工具技巧
- Web Api 分类
- 2016.3pycharm破解码
- HDU 1068 ( Bipartite Matching )
- 求海量文本中两两相似文本的快速算法
- SNAP-The SENTINEL-1 Toolbox
- Let the Balloon Rise
- 70. Climbing Stairs
- idTCPSever得到连接IP和端口。
- iOS开发之App主题切换完整解决方案(Swift版)
- 带权的完备二分匹配问题
- Linux下文件操作
- 大数据工程师面试题(六)