【前面部分为转载--begin】
通过 采集系统 我们采 集了大量文本数据,但是文本中有很多重复数据影响我们对于结果的分析。分析前我们需要对这些数据去除重复,如何选择和设计文本的去重算法?常见的有余弦夹 角算法、欧式距离、Jaccard相似度、最长公共子串、编辑距离等。这些算法对于待比较的文本数据不多时还比较好用,如果我们的爬虫每天采集的数据以千万计算,我们如何对于这些海量千万级的数据进行高效的合并去重。最简单的做法是拿着待比较的文本和数据库中所有的文本比较一遍如果是重复的数据就标示为重复。看起来很简单,我们来做个测试,就拿最简单的两个数据使用Apache提供的 Levenshtein for 循环100w次计算这两个数据的相似度。代码结果如下:
- String s1 = "你妈妈喊你回家吃饭哦,回家罗回家罗" ;
- String s2 = "你妈妈叫你回家吃饭啦,回家罗回家罗" ;
- long t1 = System.currentTimeMillis();
- for (int i = 0; i < 1000000; i++) {
- int dis = StringUtils .getLevenshteinDistance(s1, s2);
- }
- long t2 = System.currentTimeMillis();
- System. out .println(" 耗费时间: " + (t2 - t1) + " ms ");
耗费时间: 4266 ms
大跌眼镜,居然计算耗费4秒。假设我们一天需要比较100w次,光是比较100w次的数据是否重复就需要4s,就算4s一个文档,单线程一分钟才处 理15个文档,一个小时才900个,一天也才21600个文档,这个数字和一天100w相差甚远,需要多少机器和资源才能解决。
为此我们需要一种应对于海量数据场景的去重方案,经过研究发现有种叫 local sensitive hash 局部敏感哈希 的东西,据说这玩意可以把文档降维到hash数字,数字两两计算运算量要小很多。查找很多文档后看到google对于网页去重使用的是simhash,他 们每天需要处理的文档在亿级别,大大超过了我们现在文档的水平。既然老大哥也有类似的应用,我们也赶紧尝试下。simhash是由 Charikar 在2002年提出来的,参考 《Similarity estimation techniques from rounding algorithms》 。 介绍下这个算法主要原理,为了便于理解尽量不使用数学公式,分为这几步:
- 1、分词,把需要判断文本分词形成这个文章的特征单词。最后形成去掉噪音词的单词序列并为每个词加上权重,我 们假设权重分为5个级别(1~5)。比如:“ 美国“51区”雇员称内部有9架飞碟,曾看见灰色外星人 ” ==> 分词后为 “ 美国(4) 51区(5) 雇员(3) 称(1) 内部(2) 有(1) 9架(3) 飞碟(5) 曾(1) 看见(3) 灰色(4) 外星人(5)”,括号里是代表单词在整个句子里重要程度,数字越大越重要。
- 2、hash,通过hash算法把每个词变成hash值,比如“美国”通过hash算法计算为 100101,“51区”通过hash算法计算为 101011。这样我们的字符串就变成了一串串数字,还记得文章开头说过的吗,要把文章变为数字计算才能提高相似度计算性能,现在是降维过程进行时。
- 3、加权,通过 2步骤的hash生成结果,需要按照单词的权重形成加权数字串,比如“美国”的hash值为“100101”,通过加权计算为“4 -4 -4 4 -4 4”;“51区”的hash值为“101011”,通过加权计算为 “ 5 -5 5 -5 5 5”。
- 4、合并,把上面各个单词算出来的序列值累加,变成只有一个序列串。比如 “美国”的 “4 -4 -4 4 -4 4”,“51区”的 “ 5 -5 5 -5 5 5”, 把每一位进行累加, “4+5 -4+-5 -4+5 4+-5 -4+5 4+5” ==》 “9 -9 1 -1 1 9”。这里作为示例只算了两个单词的,真实计算需要把所有单词的序列串累加。
- 5、降维,把4步算出来的 “9 -9 1 -1 1 9” 变成 0 1 串,形成我们最终的simhash签名。 如果每一位大于0 记为 1,小于0 记为 0。最后算出结果为:“1 0 1 0 1 1”。
整个过程图为:
大家可能会有疑问,经过这么多步骤搞这么麻烦,不就是为了得到个 0 1 字符串吗?我直接把这个文本作为字符串输入,用hash函数生成 0 1 值更简单。其实不是这样的,传统hash函数解决的是生成唯一值,比如 md5、hashmap等。md5是用于生成唯一签名串,只要稍微多加一个字符md5的两个数字看起来相差甚远;hashmap也是用于键值对查找,便于 快速插入和查找的数据结构。不过我们主要解决的是文本相似度计算,要比较的是两个文章是否相识,当然我们降维生成了hashcode也是用于这个目的。看 到这里估计大家就明白了,我们使用的simhash就算把文章中的字符串变成 01 串也还是可以用于计算相似度的,而传统的hashcode却不行。我们可以来做个测试,两个相差只有一个字符的文本串,“你妈妈喊你回家吃饭哦,回家罗回 家罗” 和 “你妈妈叫你回家吃饭啦,回家罗回家罗”。
通过simhash计算结果为:
1000010010101101111111100000101011010001001111100001001011001011
1000010010101101011111100000101011010001001111100001101010001011
通过 hashcode计算为:
1111111111111111111111111111111110001000001100110100111011011110
1010010001111111110010110011101
大家可以看得出来,相似的文本只有部分 01 串变化了,而普通的hashcode却不能做到,这个就是局部敏感哈希的魅力。目前Broder提出的shingling算法和Charikar的 simhash算法应该算是业界公认比较好的算法。在simhash的发明人Charikar的论文中并没有给出具体的simhash算法和证明,“量子图灵”得出的证明simhash是由随机超平面hash算法演变而来的。
现在通过这样的转换,我们把库里的文本都转换为simhash 代码,并转换为long类型存储,空间大大减少。现在我们虽然解决了空间,但是如何计算两个simhash的相似度呢?难道是比较两个simhash的 01有多少个不同吗?对的,其实也就是这样,我们通过海明距离(Hamming distance)就可以计算出两个simhash到底相似不相似。两个simhash对应二进制(01串)取值不同的数量称为这两个simhash的海 明距离。举例如下: 10101 和 00110 从第一位开始依次有第一位、第四、第五位不同,则海明距离为3。对于二进制字符串的a和b,海明距离为等于在a XOR b运算结果中1的个数(普遍算法)。
为了高效比较,我们预先加载了库里存在文本并转换为simhash code 存储在内存空间。来一条文本先转换为 simhash code,然后和内存里的simhash code 进行比较,测试100w次计算在100ms。速度大大提升。
未完待续:
1、目前速度提升了但是数据是不断增量的,如果未来数据发展到一个小时100w,按现在一次100ms,一个线程处理一秒钟 10次,一分钟 60 * 10 次,一个小时 60*10 *60 次 = 36000次,一天 60*10*60*24 = 864000次。 我们目标是一天100w次,通过增加两个线程就可以完成。但是如果要一个小时100w次呢?则需要增加30个线程和相应的硬件资源保证速度能够达到,这样 成本也上去了。能否有更好的办法,提高我们比较的效率?
2、通过大量测试,simhash用于比较大文本,比如500字以上效果都还蛮好,距离小于3的基本都是相似,误判率也比较低。但是如果我们处理的 是微博信息,最多也就140个字,使用simhash的效果并不那么理想。看如下图,在距离为3时是一个比较折中的点,在距离为10时效果已经很差了,不 过我们测试短文本很多看起来相似的距离确实为10。如果使用距离为3,短文本大量重复信息不会被过滤,如果使用距离为10,长文本的错误率也非常高,如何 解决?
【后面加自己的-后续补】
相关推荐
本文将深入探讨如何利用Python编程语言和哈希算法来有效地实现图像去重。 首先,我们要理解哈希算法的基本原理。哈希(Hash)算法是一种将任意长度的输入(也叫做预映射)通过一个算法,变换成固定长度的输出,这个...
simhash是一种局部敏感哈希算法,它能够将高维文本数据映射到低维空间,同时保留原数据的相似性。通过计算不同文本指纹之间的汉明距离(Hamming Distance),可以得到两个文本指纹的相似度。汉明距离是指两个字符串...
因此,K8工具可能结合了其他的相似性比较算法,如Jaccard相似度或余弦相似度,以更精确地判断文本的相似程度。 此外,K8文本去重工具还可能支持分块处理和并行计算,以提高处理速度。分块处理是指将大文件拆分成...
4. 哈希算法:文件去重的一个常见方法是使用哈希算法(如MD5、SHA-1或SHA-256),计算每个文件的唯一标识符(哈希值)。如果两个文件的哈希值相同,那么它们的内容很可能一样。这种方法高效且准确,但可能会遇到哈希...
在IT领域,图片去重是一项重要的任务,尤其在大规模数据处理和存储时,例如网络爬虫抓取图片或媒体库管理。"Deduplication_图片去重_"这个标题所指的就是一种针对图像进行重复检查的技术,目的是有效地识别并去除...
- 内容比较:对于部分哈希值不同但内容相似的文件,可以进行逐行或关键词比较来确定是否重复。 - 预处理技术:如去除空格、换行符,统一大小写等,以提高去重效果。 4. **"精英txt文本整理工具箱v3.5"的功能特性*...
软件会遍历整个手机号码列表,通过比较每个号码与其他号码的相似性来识别并去除重复项。这些算法可能包括哈希碰撞检测、排序后查找重复项或利用数据库索引技术等。在处理大量数据时,高效的去重算法可以显著提高处理...
1. **基于哈希的方法**:这是最常见的去重策略,通过计算每个索引条目的哈希值来识别重复项。相同的哈希值表明可能存在重复。这种方法简单快速,但可能存在哈希冲突的问题。 2. **指纹法**:对于文本数据,可以使用...
【照片去重工具】是一种专为用户解决存储空间被大量重复照片占用问题的软件。它通过先进的图像识别技术,能够智能地分析并比较图片的相似度,帮助用户快速找到并删除重复或相似的照片,以此来优化硬盘空间,提高管理...
2. **字符串匹配**:除了哈希外,源码可能也包含了精确或近似的字符串匹配算法,如Rabin-Karp、KMP、Boyer-Moore或Sunday算法,这些算法可以快速查找文本中的相同或相似片段。 3. **数据结构优化**:为了高效存储和...
同源网页去重主要通过哈希函数来实现,对网页的URL进行散列处理。哈希函数可以将URL转化为一个唯一的哈希值,如果两个URL经过哈希后得到相同的值,那么它们很可能指向同一个网页。在实际操作中,首先对URL进行...
3. **相似度计算**:图像相似度的衡量有很多种方法,如像素级别的差异(均方误差)、结构相似度指数(SSIM)、归一化互信息(NMI)或者哈希算法(如PCA-SIFT、BRIEF等)。OpenCV提供了部分功能来实现这些算法,例如`cv2....
传统的网页去重算法通常通过哈希(Hashing)方法来识别网页的相似性,但这种方法在处理中文文本时可能存在局限性,因为中文字符的编码复杂度和语言的语义表达方式使得简单地进行哈希比较往往不够准确。 改进的DSC...
它通过将数据转换为一个固定长度的哈希值,使得相似的文档会有更少的哈希冲突。SimHash的关键在于使用多个不同的哈希函数,并对结果进行加权求和,然后取模得到最终的哈希值。当两个文档的SimHash值之间的Hamming...
在大数据场景下,哈希技术常用于快速查找、去重和分布式存储。哈希碰撞(两个不同的输入得到相同的哈希值)是哈希表的主要问题,解决方法包括开放寻址法、链地址法和再哈希法等。在KNN算法中,哈希可以用来快速定位...
哈希技术在大数据处理中的作用主要体现在快速查找和数据去重上。哈希函数能够将任意大小的数据映射为固定长度的哈希值,通过哈希值的比较可以高效地判断两个数据是否相同。在KNN算法中,哈希技术可以帮助我们快速...
这些算法的特点是在文本相似度较高时,产生的哈希值也会较为相似。 **minHash原理**:minHash是一种局部敏感哈希算法,它通过对集合中的元素应用特定的哈希函数,抽取少量元素来代表整个集合。如果这些代表元素的...
通过计算两张图片的哈希值或者使用结构相似度指数(SSIM)等方法来判断图片内容是否一致,从而达到去重的目的。 `wxPython`是一个流行的Python GUI(图形用户界面)库,它允许开发者创建美观且跨平台的应用程序。在...
2. **特征压缩编码**:通过哈希编码等技术将文本转换为数字串,减少存储需求,加快比较速度。 3. **文档相似度计算**:基于特征的重合程度来判断两个网页是否重复。 4. **聚类算法**:通过迭代计算找出相似的文档...