背景上周某一天,笔者搜遍全网,综合各种不完整的代码片段、GitHub 上几十个 SimHash 项目、几十个相关网络资源文章后,终于搞定了一个还算精确的 SimHash 算法的 Java 版本。 输出是检验掌握一个知识点的简单标准,本文就来详细介绍一下基于 SimHash 算法的相似文本检索的原理和实现过程。 文本相似度的应用最近在搞一个漏洞库爬虫项目,需要综合分析并合并几个漏洞网站的漏洞信息,不同漏洞的发布基本上是相似的,但是不同网站可能稍有差异,怎么将不同网站发布的、本质是同一种漏洞的记录合并呢? 这就涉及到了文本相似度计算问题。基本思路是:对网页漏洞解析时,先以漏洞简介或者标题去系统的漏洞库中检索,是否有相似的漏洞,如果存在,视为同一条漏洞信息,追加漏洞来源即可。 这个问题的经典解决方案就是 Google 用来处理海量文本去重的算法 SimHash ,它是一种局部敏感 hash 【全称: Locality Sensitive Hashing】,全称和缩写的 Sim 有些出入,不知道为什么呢! 利用 SimHash 判断文本相似度的基本流程为:
SimHash 算法简介Java 里有 HashMap ,想必大家都不陌生,它通过一个函数得到值来标识某项数据的位置,为了避免 Hash 冲突,选中的函数应该尽量让数据分散。 SimHash 与我们熟悉的 Hash 不太一样,它要求对相同或相似的文本,产生相同或者相近的哈希值,值得相似程度同时能反映输入得文本得相似度。 它的原理是: SimHash 原理 基本流程是:
从文本到 SimHash 指纹的过程,有一个经典的示例: 算法示例 算法实现需要解决的三个技术点:
汉明距离看看来自百度百科的解释:
从其定义上来看,就是二进制序列异或计算时相异为 1 ,异或的结果中 1 的总数,就是两个字符串的汉明距离,所以实现汉明距离计算的方法也很简单。 启示录本篇先介绍基础概念,下一篇笔者将继续介绍具体的算法实现。从 SimHash 算法的流程来看,比较难理解的是,为什么可以直接对哈希值中的 0 或 1 替换为权重值,然后对所有分词累加权重呢? |
|
来自: 昵称16619343 > 《待分类》