目录

整体框架

1. 查询文本切分策略

2. 文本相似性计算

2.1 计算粒度

2.2 相似性度量算法

2.3 整体相似度的评估

文本相似度

simhash算法及原理简介

1. 什么是SimHash

2. SimHash的计算原理

3. 相似度判断

4. 大规模数据下的海明距离计算

开源代码实现


整体框架

文本查重需要考虑的问题:

注意:章节序号对查重结果的影响

具体细节参考: 文本在线查重(Online Copy Detection)的实现

1. 查询文本切分策略

考虑到如下几个问题:

(1)百度搜索输入框中文字符的最大输入个数为:38。
(2)通用中文查重标准认为:连续重复字符数大于等于13属于抄袭。
(3)句意统一,字符串越长,百度搜索返回的结果往往和查询结果越匹配。

我们制定如下的查询文本切分策略:

对于查询文本,首先以“,;。!?”为切分符进行切分,得到切分后的字符串集合。
对于切分后的字符串,从前往后尽量组合,在组合后的字符串长度小于38的前提下,组合成的字符串长度越长越好。例如,如果s[i+1]+s[i]>s[i]且s[i+1]+s[i]<38,则将s[i+1]、s[i]两者组合成新的字符串。

具体实现代码如下:

def split_search(query_all):query_array = re.split(u"[,;。!?]", query_all.decode('utf-8'))if(len(query_array[-1])<5):query_array.pop(-1)flag = len(query_array)-1i = -1while (i<flag):i += 1if(i>flag-1):breakelif(len(query_array[i])<38):if(len(query_array[i])+len(query_array[i+1])>38):continueelse:query_array[i+1] = query_array[i] + query_array[i+1]query_array.pop(i)flag -= 1i -= 1else:continuereturn query_array

2. 文本相似性计算

2.1 计算粒度

对于查询文本和搜索结果文本,皆以“,;。!?”为切分符。
对于切分后的字符串,从前往后组合成长度大于13的字符串,也就是使每一个用于计算的字符串都满足长度大于13。

def split_content_all(query_all):query_array = re.split(r"[,;。!?]", query_all)flag = len(query_array)-1for i in range(flag):if(i>flag-1):breakelif(len(query_array[i])>=13):continueelse:query_array[i+1] = query_array[i] + query_array[i+1]query_array.pop(i)flag -= 1return query_array

2.2 相似性度量算法

在介绍具体算法之前,我们先来了解一下有关copy-detection的知识。copy-detection主要用于检测文件或网页中相同的内容,判定是否存在拷贝、抄袭等行为以及程度。在下面的讨论中,我们将范围缩减到只考虑包含ASCII字符的文件,不考虑图片及视屏等内容。通常情况下,我们认为用于copy-detection的算法应该满足以下要求:

1、无视空白符(Whitespace insensitivity)。
在比较文件内容的过程中,我们通常不希望被空格、制表符、标点符号等影响我们判定的结果,因为它们并不是我们感兴趣的内容。在不同的应用下,我们感兴趣的内容会有些不同,比如在程序代码文件中,变量名通常是我们不感兴趣的。
2、噪音抑制(Noise suppression)。
主要是指应该排除一些可以接受的拷贝,比如成语、谚语、免责声明等,这些也不是我们感兴趣的。比如在程序代码文件中,你或许希望排除一些教师给定标程中的内容。
3、位置无关性(Position independence)。
在完全拷贝一份文件后,简单的将文件内容调换一下位置,仍然属于抄袭行为。位置无关性就反映了这么一种性质,粗粒度的位置调换不会影响最终的判定。更进一步说,从原文件中添加或者删除一段内容,不应该影响到其他部分的判断。

基于对问题的分析,我们选取了hash类算法(计算速度快)和字符串直接匹配算法(准确度高)进行了相应实验,下文将对各类算法的实现和实验结果进行阐述。

(1)hash类算法

hash 算法的实质就是把数据映射成比较短的固定长度的散列值,从而提高存储效率或者是计算效率。
具体来说,Hash 算法就是把任意长度的输入,通过散列算法,变换成固定长度的输出。该输出就是散列值。这种转换是一种压缩映射,散列值的空间一般远小于输入的空间。 但是如果不同的数据通过hash 算法得到了相同的输出,这个就叫做碰撞,因此不可能从散列值来唯一确定输入值。
一个优秀的 hash 算法,满足:

正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。
逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。
输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。
冲突避免:很难找到两段内容不同的明文,使得它们的 hash值一致(发生冲突)。即对于任意两个不同的数据块,其hash值相同的可能性极小;对于一个给定的数据块,找到和它hash值相同的数据块极为困难。

常见的hash算法包括如下几种:

  • winnowing算法

具体原理和实现代码可参考博客:《【文本相似性计算】winnowing算法》。

  • simHash类算法

具体原理和实现代码可参考博客:《【文本相似性计算】simHash算法》。

  • minHash类算法

具体原理和实现代码可参考博客:《【文本相似性计算】minHash和LSH算法》。

(2)字符串直接匹配算法

常见的字符串直接匹配算法有很多,例如欧几里得距离、余弦距离、最长公共子序列、编辑距离(levenshtein距离)、Jaccard相似性系数等。

各类算法的实现代码参考github:https://github.com/Neo-Luo/TextSimilarity

2.3 整体相似度的评估

具体实现代码如下:

def cal_total_rate(final_res,query_all):score = 0for item in final_res['detail']:score += final_res['detail'][item]['dist'] * \len(final_res['detail'][item]['query_str'])final_res['total_rate'] = float(score) / float(len(query_all))return final_res

文本相似度

计算的处理流程是:

1.对所有文章进行分词

2.分词的同时计算各个词的tf值

3.所有文章分词完毕后计算idf值

4.生成每篇文章对应的n维向量(n是切分出来的词数,向量的项就是各个词的tf-idf值)

5.对文章的向量两篇两篇代入余弦定理公式计算,得出的cos值就是它们之间的相似度了

余弦相似度:当两条新闻向量夹角的余弦等于1时,这两条新闻完全重复;当夹角的余弦接近于1时,两条新闻相似,从而可以归成一类;夹角的余弦越小,两条新闻越不相关。

simhash算法及原理简介

1. 什么是SimHash

SimHash算法是Google在2007年发表的论文《Detecting Near-Duplicates for Web Crawling》中提到的一种指纹生成算法,被应用在Google搜索引擎网页去重的工作之中。
简单的说,SimHash算法主要的工作就是将文本进行降维,生成一个SimHash值,也就是论文中所提及的“指纹”,通过对不同文本的SimHash值进而比较海明距离,从而判断两个文本的相似度。
对于文本去重这个问题,常见的解决办法有余弦算法、欧式距离、Jaccard相似度、最长公共子串等方法。但是这些方法并不能对海量数据高效的处理。
比如说,在搜索引擎中,会有很多相似的关键词,用户所需要获取的内容是相似的,但是搜索的关键词却是不同的,如“北京好吃的火锅“和”哪家北京的火锅好吃“,是两个可以等价的关键词,然而通过普通的hash计算,会产生两个相差甚远的hash串。而通过SimHash计算得到的Hash串会非常的相近,从而可以判断两个文本的相似程度。

2. SimHash的计算原理

github: https://github.com/yanyiwu/simhash

github参考:simhash算法原理及实现

SimHash算法主要有五个过程:分词、Hash、加权、合并、降维。

  • step1:分词

给定一段语句,进行分词,得到有效的特征向量,然后为每一个特征向量设置1-5等5个级别的权重(如果是给定一个文本,那么特征向量可以是文本中的词,其权重可以是这个词出现的次数)。例如给定一段语句:“CSDN博客结构之法算法之道的作者July”,分词后为:“CSDN 博客 结构 之 法 算法 之 道 的 作者 July”,然后为每个特征向量赋予权值:CSDN(4) 博客(5) 结构(3) 之(1) 法(2) 算法(3) 之(1) 道(2) 的(1) 作者(5) July(5),其中括号里的数字代表这个单词在整条语句中的重要程度,数字越大代表越重要。

其中,数字越大,代表特征词在句子中的重要性就越高。这样,我们就得到了一个文本的分词的词向量和每个词向量对应的权重。

  • step2:Hash

通过hash函数计算各个特征向量的hash值,hash值为二进制数01组成的n-bit签名。比如“CSDN”的hash值Hash(CSDN)为100101,“博客”的hash值Hash(博客)为“101011”。就这样,字符串就变成了一系列数字。

  • step3:加权

前面的计算我们已经得到了每个词向量的Hash串和该词向量对应的权重,这一步我们计算权重向量W=hash*weight,即遇到1则hash值和权值正相乘,遇到0则hash值和权值负相乘。

例如给“CSDN”的hash值“100101”加权得到:W(CSDN) = 100101 * 4 = 4 -4 -4 4 -4 4,给“博客”的hash值“101011”加权得到:W(博客)=101011 * 5 = 5 -5 5 -5 5 5,其余特征向量类似此般操作。

  • step4:合并

对于一个文本,我们计算出了文本分词之后每一个特征词的权重向量,在合并这个阶段,我们把文本所有词向量的权重向量相累加,得到一个新的权重向量,拿前两个特征向量举例,例如“CSDN”的“4 -4 -4 4 -4 4”和“博客”的“5 -5 5 -5 5 5”进行累加,得到“4+5 -4+-5 -4+5 4+-5 -4+5 4+5”,得到“9 -9 1 -1 1”。

  • step5:降维

对于前面合并后得到的文本的权重向量,如果大于0则置1,否则置0,就可以得到该文本的SimHash值。最后我们便可以根据不同语句simhash的海明距离来判断它们的相似度。例如把上面计算出来的“9 -9 1 -1 1 9”降维(某位大于0记为1,小于0记为0),得到的01串为:“1 0 1 0 1 1”,从而形成它们的simhash签名。

到此为止,我们已经计算出了一个文本的SimHash值。那么,如何判断两个文本是否相似呢?我们要用到海明距离。

3. 相似度判断

对于两个文本的SimHash的相似度判断,我们使用海明距离来计算。什么是海明距离呢?

简单的说,Hamming Distance,又称汉明距离,在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数。也就是说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数。例如:1011101 与 1001001 之间的汉明距离是 2。至于我们常说的字符串编辑距离则是一般形式的汉明距离。

海明距离的求法:异或时,只有在两个比较的位不同时其结果是1 ,否则结果为0,两个二进制“异或”后得到1的个数即为海明距离的大小。

换言之,现在问题转换为:对于64位的SimHash值,我们只要找到海明距离在3以内的所有签名,即可找出所有相似的短语。

在处理大规模数据的时候,我们一般使用64位的SimHash,正好可以被一个long型存储。这种时候,海明距离在3以内就可以认为两个文本是相似的。

4. 大规模数据下的海明距离计算

如何扩展到海量数据呢?譬如如何在海量的样本库中查询与其海明距离在3以内的记录呢?

  • 一种方案是,查找待查询文本的64位simhash code的所有3位以内变化的组合:大约需要四万多次的查询。
  • 另一种方案是,预生成库中所有样本simhash code的3位变化以内的组合:大约需要占据4万多倍的原始空间。

这两种方案,要么时间复杂度高,要么空间复杂度复杂,能否有一种方案可以达到时空复杂度的绝佳平衡呢?答案是肯定的,这时候有一种较好的办法来均衡计算海明距离的时间复杂度和空间复杂度,具体的计算思想是这样的:

  • 我们可以把 64 位的二进制simhash签名均分成4块,每块16位。根据鸽巢原理(也称抽屉原理),如果两个SimHash相似,即两个签名的海明距离在 3 以内,它们必有一块完全相同。如下图所示:               
  • 然后把分成的4 块中的每一个块分别作为前16位来进行查找,建倒排索引。

开源代码实现

1. https://github.com/CuiYongen/DuplicateChecking

2. https://github.com/tianlian0/paper_checking_system

文本查重:知识点总结相关推荐

  1. [转]simhash进行文本查重

    有1亿个不重复的64位的01字符串,任意给出一个64位的01字符串f,如何快速从中找出与f汉明距离小于3的字符串? 大规模网页的近似查重 主要翻译自WWW07的 Detecting Near-Dupl ...

  2. 大量文本查重相似度计算功能设计-基于simhash+相似度算法

    最近做文本查重功能,陆续遇到一些问题,做一下记录: 1.simhash分桶策略,只适合基本完全相同的文本查重,比如网页查重.64位simhash如果有3位以内的海明距离,则认为文本一致:存储使用hba ...

  3. 【代码模板】simHash算法文本查重(golang代码实现)

    ps: 供自己以后参考以及供了解simhash算法的人看 本代码针对通用文本查重,故所有分词的权重均为1 由于没有安装分词器,所以目前只能对英文句子进行相似度检测 代码只提供一个大致思路,没有做进一步 ...

  4. 【JavaWeb 爬虫】Java文本查重网页版 爬取百度搜索结果页全部链接内容

    ! ! 更新:增加了网页过滤判断,只允许域名包含blog,jianshu的网站通过 小技巧 Java中InputStream和String之间的转换方法 String result = new Buf ...

  5. python实现文本查重系统_NLP之gensim库python实现文本相似度/匹配/查重

    目的 给定一个或多个搜索词,如"高血压 患者",从已有的若干篇文本中找出最相关的(n篇)文本. 理论知识 文本检索(text retrieve)的常用策略是:用一个ranking ...

  6. 文本查重:difflib.SequenceMatcher

    目录 1. SequenceMatcher FlowChart 1.1 get_matching_blocks() 1.2 find_longest_match() 1.3 ratio() 2. 例子 ...

  7. 20190508 文本查重系统(四)

    楼上突然知道我的web项目是用python2.7写的,然后,然后我就花了三天的时间改版了,顺便改了很多以前没有发现的bug,是的,还是python写的,这次是python3.6.至于java版本,写完 ...

  8. 文本在线查重系统设计与实现(1)

    <基于多粒度偏好的网络文本抄袭检测系统的研究与实现>论文重点记录及知识点 网络爬虫:技术类文本选择主要爬取CSDN,新浪博客等技术性站点:新闻类文本主要爬取腾讯新闻等新闻网站等: 相似度计 ...

  9. python文章抄袭检测_CSDN文章被洗稿、抄袭严重!用Python做一个“基于搜索引擎的文章查重工具”,解决!...

    前言 文章抄袭在互联网中普遍存在,很多博主.号主深受其烦. 近几年随着互联网的发展,抄袭等不道德行为在互联网上愈演愈烈,甚至复制.黏贴后发布标原创屡见不鲜,部分抄袭后的文章,甚至标记了一些联系方式从而 ...

最新文章

  1. py文件打包或apk_Python文件打包成exe很简单,如果安卓手机也能运行的软件你会吗...
  2. php 运行外部程序_PHP实现执行外部程序的方法详解
  3. 我的世界java一键修复_我的世界JAVA 1.14.2最新预览版发布 修复光源BUG
  4. java自我复制_原型模式--自我复制(结合Java浅复制与深复制)
  5. java反射机制_java反射机制的讲解
  6. [转载]JavaScript 的轻框架开发
  7. 网络访问保护(NAP)技术之详解
  8. 为什么饿着饿着就不饿了
  9. 拉普拉斯分布_理解拉普拉斯特征映射中的优化问题的约束条件
  10. java error_java基础:Error和Exception
  11. python如何下载os库_python下载os库的方法
  12. 常见的几种网络抓包及协议分析工具
  13. 卡通动漫漫画微信小程序源码开源版
  14. ECharts实战教程
  15. 职称论文通过查重之后就能发表吗?
  16. 大数据为什么用python_为什么大数据用python
  17. 深度学习细粒度图像研究汇总
  18. 【地理人工智能交叉】通过整合兴趣点和Word2Vec模型感知城市土地利用的空间分布
  19. Red Hat Enterprise Linux Server 7.3 离线安装Podman
  20. 产品研发管理的系统解决方案

热门文章

  1. 公司业务系统与呼叫中心系统的对接方式
  2. 转场动画:动画效果 css 动画 animate.css
  3. 【机器学习】Reinforcement Learning-强化学习学习笔记
  4. 【C语言】strlen和sizeof的区别
  5. Netcool为中国电子口岸构筑无忧网络管理平台
  6. 基于深度学习的视觉里程计算法
  7. 帮过网:大专如何报考公务员
  8. python优点和缺点_Python的优势和不足有哪些
  9. Python基础07互评成绩
  10. 【小波分析】七、小波分析与非线性逼近(下)