zoukankan      html  css  js  c++  java
  • 两个文本相似度算法实现和对比

    背景

    最近做一个爬虫相关的项目,需要排除掉一些相似的链接,比如分页控件里上一页,下一页等等没什么用的链接.

    编辑距离算法

    编辑距离,又称Levenshtein距离(莱文斯坦距离也叫做Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数,如果它们的距离越大,说明它们越是不同。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。

    这个概念是由俄罗斯科学家Vladimir Levenshtein在1965年提出来的,所以也叫 Levenshtein 距离。它可以用来做DNA分析,拼字检测,抄袭识别等等。总是比较相似的,或多或少我们可以考虑编辑距离。

    如果你去搜索编辑距离算法的话可能会看到下面的例子

    如果str1=”ivan”,str2=”ivan”,那么经过计算后等于 0。没有经过转换。相似度=1-0/Math.Max(str1.length,str2.length)=1

    如果str1=”ivan1”,str2=”ivan2”,那么经过计算后等于1。str1的”1”转换”2”,转换了一个字符,所以距离是1,相似度=1-1/Math.Max(str1.length,str2.length)=0.8

    注意算法中的1,其实是固定的值.我就是因为这个值总是算不对走了一些弯路.还有一些文章中介绍算法的时候会用矩阵计算.但是我数学功底很差,所以用了另一种方式实现.

    通过算法描述中可以知道,字符串的编辑操作可以是插入,删除,修改.这三个方式的编辑操作,操作数都记为1.那么我的实现中,其实是移除了插入和删除的两个操作,全部是修改操作.实现如下,有什么问题的话还请指出.谢谢!

    public static int Levenshtein(string str1, string str2)
    {
        var maxLen = Math.Max(str1.Length, str2.Length);
    
        var tmp1 = str1.PadRight(maxLen);
        var tmp2 = str2.PadRight(maxLen);
    
        var interval = 0.0f;
        for (int i = 0; i < maxLen; i++)
        {
            if (tmp1[i] != tmp2[i])
            {
                interval += 1;
            }
        }
    
        return Convert.ToInt32((1 - interval / maxLen) * 100);
    }
    

    杰卡德相似系数

    Jaccard index, 又称为Jaccard相似系数(Jaccard similarity coefficient)用于比较有限样本集之间的相似性与差异性。Jaccard系数值越大,样本相似度越高。

    给定两个集合A,B,Jaccard 系数定义为A与B交集的大小与A与B并集的大小的比值

    这个算法还是比较容易理解的,其实就是计算两个字符串中字符的交集和并集的比值.在实际使用时两个长度不相同的链接相似度过高的问题,而且在比对url这种场景下反斜线对于相似度的判断还是有一些影响的.经过简单的修改实现的代码如下

    public static int Jaccard(string str1, string str2)
    {
        var tmp1 = Regex.Replace(str1, "/", "");
        var tmp2 = Regex.Replace(str2, "/", "");
        var intersect = tmp1.Intersect(tmp2).Count();
        var union = tmp1.Union(tmp2).Count();
        var abs = Math.Abs(tmp2.Length - tmp1.Length);
        return Convert.ToInt32((double)intersect / (union + abs) * 100);
    }
    

    对比

    分别使用两个算法计算以下两个网址的相似度

    https://news.cnblogs.com/n/597903/
    https://news.cnblogs.com/n/597947/

    结果如下

    算法 相似度
    Jaccard 86%
    Levenshtein 94%

    延展

    通过相似度算法似乎也可以实现爬虫中只抓取列表页中的内容链接

  • 相关阅读:
    夺命雷公狗---Redis---4-安全性
    夺命雷公狗---Redis---3-Redis常用命令
    夺命雷公狗---Redis---2-Redis数据结构
    夺命雷公狗---Redis---1-Redis介绍
    夺命雷公狗---PHP开发APP接口---5(核心技术之缓存技术)
    夺命雷公狗---PHP开发APP接口---4(综合通信方式封装)
    夺命雷公狗---PHP开发APP接口---3(XML方式封装接口数据方法)
    夺命雷公狗---PHP开发APP接口---2(手动编写XML)
    夺命雷公狗---PHP开发APP接口---1(手动编写json)
    夺命雷公狗ThinkPHP项目之----商城10商品属性管理
  • 原文地址:https://www.cnblogs.com/huaface/p/9110557.html
Copyright © 2011-2022 走看看