Jaccard相似系数

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

定义

给定两个集合A,BJaccard 系数定义为AB交集的大小与AB并集的大小的比值,定义如下:

当集合AB都为空时,J(A,B)定义为1
Jaccard 系数相关的指标叫做Jaccard 距离,用于描述集合之间的不相似度。Jaccard 距离越大,样本相似度越低。公式定义如下:

其中对称差(symmetric difference)

实例

由于编辑距离关注在于字符间的不同之处,而最长公共子序列(LCS)侧重点在于相同的部分,因此都无法衡量差异具体值的大小,只能获得“是否相同”这个结果,所以Jaccard系数用来关心个体间共同具有的特征是否一致这个问题。

如集合A={1,2,3,4};B={3,4,5,6};
那么他们的J(X,Y)=l{3,4}/l{1,2,3,4,5,6}=1/3;

在数据挖掘领域,常常需要比较两个具有布尔值属性的对象之间的距离,Jaccard距离就是常用的一种方法。给定两个比较对象A,B。A, B 均有n个二元属性,即
每个属性取值为{0,1}。定义如下4个统计量:

  • M00:A,B属性值同时为0的属性个数;
  • M01:A属性值为0且B属性值为1的属性个数;
  • M10:A属性值为1且B属性值为0的属性个数;
  • M11:A,B属性值同时为1的属性个数;

如下图所示:

显然有

Jaccard 系数:

Jaccard距离:

代码实现

// 结果是去重的jaccard系数
// A ⋂ B 
int _intersection(const wstring &str1, const wstring &str2) {
    wstring::const_iterator first1 = str1.begin(), last1 = str1.end(), first2 = str2.begin(), last2 = str2.end();
    int counter = 0;
    wchar_t final = '\0';
    while (first1 != last1 && first2 != last2) {
        if (*first1 < *first2)
            ++first1;
        else if (*first2 < *first1)
            ++first2;
        else {
            if (*first1 != final) {
                ++counter;
                final = *first1;
            }
            ++first1;
            ++first2;
        }
    }
    return counter;
}

// A ⋃ B
int _union(const wstring &str1, const wstring &str2) {
    wstring::const_iterator first1 = str1.begin(), last1 = str1.end(), first2 = str2.begin(), last2 = str2.end();
    int counter = 0;
    wchar_t final = '\0';
    while (first1 != last1 && first2 != last2) {
        if (*first1 <= *first2) {
            if (final != *first1) {
                ++counter;
                final = *first1;
            }
            ++first1;
        } else if (*first2 < *first1) {
            if (final != *first2) {
                ++counter;
                final = *first2;
            }
            ++first2;
        }
    }

    while (first1 != last1) {
        if (final != *first1) {
            ++counter;
            final = *first1;
        }
        ++first1;
    }

    while (first2 != last2) {
        if (final != *first2) {
            ++counter;
            final = *first2;
        }
        ++first2;
    }
    return counter;
}

// |A ⋂ B| / |A ⋃ B|
double jaccard_index(wstring str1, wstring str2) {
    if (str1.size() == 0 || str2.size() == 0)
        return 0;
    sort(str1.begin(), str1.end());
    sort(str2.begin(), str2.end());
    return 1.0 * _intersection(str1, str2) / _union(str1, str2);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值