使用Python检测文章抄袭及去重算法原理解析


Posted in Python onJune 14, 2019

在互联网出现之前,“抄”很不方便,一是“源”少,而是发布渠道少;而在互联网出现之后,“抄”变得很简单,铺天盖地的“源”源源不断,发布渠道也数不胜数,博客论坛甚至是自建网站,而爬虫还可以让“抄”完全自动化不费劲。这就导致了互联网上的“文章”重复性很高。这里的“文章”只新闻、博客等文字占据绝大部分内容的网页。

使用Python检测文章抄袭及去重算法原理解析

中文新闻网站的“转载”(其实就是抄)现象非常严重,这种“转载”几乎是全文照抄,或改下标题,或是改下编辑姓名,或是文字个别字修改。所以,对新闻网页的去重很有必要。

一、去重算法原理

文章去重(或叫网页去重)是根据文章(或网页)的文字内容来判断多个文章之间是否重复。这是爬虫爬取大量的文本行网页(新闻网页、博客网页等)后要进行的非常重要的一项操作,也是搜索引擎非常关心的一个问题。搜索引擎中抓取的网页是海量的,海量文本的去重算法也出现了很多,比如minihash, simhash等等。

在工程实践中,对simhash使用了很长一段时间,有些缺点,一是算法比较复杂、效率较差;二是准确率一般。

网上也流传着百度采用的一种方法,用文章最长句子的hash值作为文章的标识,hash相同的文章(网页)就认为其内容一样,是重复的文章(网页)。

这个所谓的“百度算法”对工程很友好,但是实际中还是会有很多问题。中文网页的一大特点就是“天下文章一大抄”,各种博文、新闻几乎一字不改或稍作修改就被网站发表了。这个特点,很适合这个“百度算法”。但是,实际中个别字的修改,会导致被转载的最长的那句话不一样,从而其hash值也不一样了,最终结果是,准确率很高,召回率较低。

为了解决这个问题,我提出了nshash(top-n longest sentences hash)算法,即:取文章的最长n句话(实践下来,n=5效果不错)分别做hash值,这n个hash值作为文章的指纹,就像是人的5个手指的指纹,每个指纹都可以唯一确认文章的唯一性。这是对“百度算法”的延伸,准确率还是很高,但是召回率大大提高,原先一个指纹来确定,现在有n个指纹来招回了。

二、算法实现

该算法的原理简单,实现起来也不难。比较复杂一点的是对于一篇文章(网页)返回一个similar_id,只要该ID相同则文章相似,通过groupby similar_id即可达到去重目的。

为了记录文章指纹和similar_id的关系,我们需要一个key-value数据库,本算法实现了内存和硬盘两种key-value数据库类来记录这种关系:

HashDBLeveldb 类:基于leveldb实现, 可用于海量文本的去重;

HashDBMemory 类:基于Python的dict实现,可用于中等数量(只要Python的dict不报内存错误)的文本去重。

这两个类都具有get()和put()两个方法,如果你想用Redis或MySQL等其它数据库来实现HashDB,可以参照这两个类的实现进行实现。

使用Python检测文章抄袭及去重算法原理解析

使用Python检测文章抄袭及去重算法原理解析

HashDBLeveldb类的实现

使用Python检测文章抄袭及去重算法原理解析

使用Python检测文章抄袭及去重算法原理解析

HashDBMemory类的实现

从效率上看,肯定是HashDBMemory速度更快。利用nshash对17400篇新闻网页内容的测试结果如下:

HashDBLeveldb: 耗时2.47秒; HashDBMemory: 耗时1.6秒;

具体测试代码请看 example/test.py。

有了这两个类,就可以实现nshash的核心算法了。

首先,对文本进行分句,以句号、感叹号、问号、换行符作为句子的结尾标识,一个正在表达式就可以分好句了。

其次,挑选最长的n句话,分别进行hash计算。hash函数可以用Python自带模块hashlib中的md5, sha等等,也可以用我在爬虫教程中多次提到的farmhash。

最后,我们需要根据这n个hash值给文本内容一个similar_id,通过上面两种HashDB的类的任意一种都可以比较容易实现。其原理就是,similar_id从0开始,从HashDB中查找这n个hash值是否有对应的similar_id,如果有就返回这个对应的similar_id;如果没有,就让当前similar_id加1作为这n个hash值对应的similar_id,将这种对应关系存入HashDB,并返回该similar_id即可。

这个算法实现为NSHash类:

使用Python检测文章抄袭及去重算法原理解析

使用Python检测文章抄袭及去重算法原理解析

NSHash类的实现

三、使用方法 

import nshash
nsh = nshash.NSHash(name='test', hashfunc='farmhash', hashdb='memory')
similar_id = nsh.get_similar(doc_text)

NSHash 类有三个参数:

  • name : 用于hashdb保存到硬盘的文件名,如果hashdb是HashDBMemory, 则用pickle序列化到硬盘;如果是HashDBLeveldb,则leveldb目录名为:name+'.hashdb'。name按需随便起即可。
  • hashfunc : 计算hash值的具体函数类别,目前实现两种类型: md5 和 farmhash 。默认是 md5 ,方便Windows上安装farmhash不方便。
  • hashdb :默认是 memory 即选择HashDBMemory,否则是HashDBLeveldb。

至于如何利用similar_id进行海量文本的去重,这要结合你如何存储、索引这些海量文本。可参考 example/test.py 文件。这个test是对excel中保存的新闻网页进行去重的例子。

总结

以上所述是小编给大家介绍的使用Python检测文章抄袭及去重算法原理解析 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
Python实现二叉搜索树
Feb 03 Python
详解Python中的Descriptor描述符类
Jun 14 Python
利用PyInstaller将python程序.py转为.exe的方法详解
May 03 Python
Python+Selenium+phantomjs实现网页模拟登录和截图功能(windows环境)
Dec 11 Python
python脚本后台执行方式
Dec 21 Python
Python logging模块写入中文出现乱码
May 21 Python
Python使用jpype模块调用jar包过程解析
Jul 29 Python
pytho matplotlib工具栏源码探析一之禁用工具栏、默认工具栏和工具栏管理器三种模式的差异
Feb 25 Python
深入解析NumPy中的Broadcasting广播机制
May 30 Python
Python Django模型详解
Oct 05 Python
python中tkinter复选框使用操作
Nov 11 Python
Python使用PyYAML库读写yaml文件的方法
Apr 06 Python
Ubuntu下Anaconda和Pycharm配置方法详解
Jun 14 #Python
PyQt5 加载图片和文本文件的实例
Jun 14 #Python
pyqt5 使用label控件实时显示时间的实例
Jun 14 #Python
ubuntu 18.04搭建python环境(pycharm+anaconda)
Jun 14 #Python
pyqt5 comboBox获得下标、文本和事件选中函数的方法
Jun 14 #Python
PyQt4实时显示文本内容GUI的示例
Jun 14 #Python
详解Python 定时框架 Apscheduler原理及安装过程
Jun 14 #Python
You might like
使用PHP 5.0创建图形的巧妙方法
2010/10/12 PHP
PHP实现图片不变型裁剪及图片按比例裁剪的方法
2016/01/14 PHP
深入理解 PHP7 中全新的 zval 容器和引用计数机制
2018/10/15 PHP
为jQuery增加join方法的实现代码
2010/11/28 Javascript
js实现网页自动刷新可制作节日倒计时效果
2014/05/27 Javascript
点击标签切换和自动切换DIV选项卡
2014/08/10 Javascript
jquery插件treegrid树状表格的使用方法详解(.Net平台)
2017/01/03 Javascript
详解如何构建Angular项目目录结构
2017/07/13 Javascript
解决vue打包项目后刷新404的问题
2018/03/06 Javascript
js运算符的一些特殊用法
2018/07/29 Javascript
jQuery实现鼠标移入移出事件切换功能示例
2018/09/06 jQuery
JavaScript中数组去重的5种方法
2020/07/04 Javascript
详解ES6 扩展运算符的使用与注意事项
2020/11/12 Javascript
[00:32]2016完美“圣”典风云人物:Maybe宣传片
2016/12/05 DOTA
pycharm 使用心得(四)显示行号
2014/06/05 Python
python网络编程学习笔记(10):webpy框架
2014/06/09 Python
python中in在list和dict中查找效率的对比分析
2018/05/04 Python
Python中一般处理中文的几种方法
2019/03/06 Python
Python QQBot库的QQ聊天机器人
2019/06/19 Python
解决python xx.py文件点击完之后一闪而过的问题
2019/06/24 Python
pandas实现to_sql将DataFrame保存到数据库中
2019/07/03 Python
Python 图像处理: 生成二维高斯分布蒙版的实例
2019/07/04 Python
html5 Canvas画图教程(8)—canvas里画曲线之bezierCurveTo方法
2013/01/09 HTML / CSS
英国派对礼服和连衣裙购物网站:TFNC London
2018/07/07 全球购物
写出程序把一个链表中的接点顺序倒排
2014/04/28 面试题
大学校庆邀请函
2014/01/11 职场文书
《一株紫丁香》教学反思
2014/02/19 职场文书
《他得的红圈圈最多》教学反思
2014/04/24 职场文书
社会调查研究计划书
2014/05/01 职场文书
班级体育活动总结
2014/07/05 职场文书
2014年民政工作总结
2014/11/26 职场文书
2014年医务科工作总结
2014/12/18 职场文书
汽车4S店销售经理岗位职责
2015/04/02 职场文书
师德承诺书2015
2015/04/28 职场文书
2016年圣诞节义工活动总结
2016/04/01 职场文书
漫改真人电影「萌系男友是燃燃的橘色」公开先导视觉图
2022/03/21 日漫