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

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

一、去重算法原理

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

HashDBLeveldb类的实现

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类:

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写了个检测文章抄袭,详谈去重算法原理相关推荐

  1. 用Python写了个检测文章抄袭,详谈去重算法原理

    在互联网出现之前,"抄"很不方便,一是"源"少,而是发布渠道少:而在互联网出现之后,"抄"变得很简单,铺天盖地的"源"源 ...

  2. python文件去重算法_使用Python检测文章抄袭及去重算法原理解析

    在互联网出现之前,"抄"很不方便,一是"源"少,而是发布渠道少:而在互联网出现之后,"抄"变得很简单,铺天盖地的"源"源 ...

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

    在互联网出现之前,"抄"很不方便,一是"源"少,而是发布渠道少:而在互联网出现之后,"抄"变得很简单,铺天盖地的"源"源 ...

  4. Python检测文章抄袭,谈谈去重算法原理

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

  5. python 实现显著性检测_使用python轻松实现高大上的YOLOV4对象检测算法

    YOLO系列对象检测算法,算是人工智能技术领域的一匹黑马,当开发者宣布不再为YOLO系列检测算法更新时,很多开发者瞬间失去了"精神食粮".突然,当YOLOV4检测算法发布的时候,让 ...

  6. python为什么那么好看_为什么Python代码要写得美观而明确

    欢迎阅读"Python 光明节(Pythonukkah)"系列文章,这个系列文章将会讨论<Python 之禅>.我们首先来看<Python 之禅>里的前两个 ...

  7. python博客园_用Python向博客园发布新文章

    最近在开发一个博客系统,经常把写的东西放在自己网站的博客上(之前写在Onenote),然后我在博客园也申请了一个博客,就有了同样一篇文章,我需要复制粘贴排版分别提交两次的情况.于是我就想能不能在我的网 ...

  8. python 公众号爬虫_用Python爬虫爬取公众号文章

    经常有读者微信私聊我,问我有没有博客之类的,因为在手机上看公众号技术文章没有电脑上方便.确实,手机上看截图需要点击放大才能看得更清楚,代码也需要左右滑动才能看到全部.我的文章大部分都是首发于公众号,有 ...

  9. python优雅代码大全_代码这样写更优雅(Python版)

    Python 这门语言最大的优点之一就是语法简洁,好的代码就像伪代码一样,干净.整洁.一目了然.但有时候我们写代码,特别是 Python 初学者,往往还是按照其它语言的思维习惯来写,那样的写法不仅运行 ...

最新文章

  1. 学术圈要炸锅:论文作者和审稿人串通欺骗盲审,ACM Fellow发文痛斥!顶会“想中就中”...
  2. 下一代 Debian - \'Lenny\' 代码冻结
  3. PAT甲级1138 Postorder Traversal:[C++题解]前序遍历和中序遍历建树
  4. VirtraulBox中安装Ubuntu16.04
  5. leetcode 792. Number of Matching Subsequences | 792. 匹配子序列的单词数(Java)
  6. 错误使用.Net Redis客户端CSRedisCore,自己挖坑自己填
  7. Python学习15 正则表达式1
  8. 清除n天以前的日志文件以及mysql-bin文件
  9. Spring Cloud Stream 简单使用
  10. java实现io阻塞的代码,Java:完整的每个连接线程阻塞IO与NIO的代码示例?
  11. 三种经典网页音乐播放器
  12. 互动拍照 — AR拍照
  13. NSACE|企业网络安全问题,千万别不在乎
  14. 同步电机是如何达到同步的?工作原理是什么?
  15. php实现 三角形_HTML纯CSS绘制三角形(各种角度)
  16. mysql execute 方法_MyEclipse------execute()使用方法
  17. 怎么删除日历每日重复提醒事项
  18. Android 系统(93)---android 怎么判断手机号是移动还是联通还是电信
  19. #2 – Rendering Tiers(WPF渲染级别)
  20. [Linux]termios

热门文章

  1. 计算机中文名称乱码,中文文件名乱码怎么解决?
  2. 数据结构课程设计大作业——江大公交路线查询系统
  3. EF BB BF 文本文件开头 iniparser
  4. 在LaTeX中使用Python的简单介绍
  5. fastjson html 转义,JSONString的转义和反转义
  6. 51单片机ADC0832模数转换+ LCD1602显示+Proteus仿真
  7. (转)两性学堂——《搭讪入门指南》
  8. 供应丙烯酰胺-聚乙二醇-琥珀酰亚胺乙酸酯试剂,Acrylamide-PEG-NHS est
  9. 虚拟机的Nginx安装配置
  10. Cocos Creator 位图字体(艺术数字配置、BMFont)