Jaccard笔记
计算两个集合的交集和并集的之间的比率,叫作 Jaccard 相似度(雅可比相似度)。似乎 Jaccard 又和 Tanimoto 有着相同的意思,只是 Tanimoto 在处理图形时,公式才不一样。
有两个集合,比如:
S集合:S = {1,2,3} T集合:T = {1,3,5} |S 交 T| / |S 并 T|,就可以得到它们之间的 Jaccard 相似度。
产生的值的范围是 0~1,也就说,结果的区间为 [0,1]。如果结果等于 0,则两个集合不相交;当结果为 1 时,两个集合相等;其他情况中,结果越趋向于 1,相似度越高,反之更不相似。
Jaccard 有个缺点:分子如果不变,随着分母越大,产生的值就越小。
这个方法可以应用到简单的文章抄袭识别上。比如《网络协议本质论》中有这么一段话:
NetBIOS 全称 NetWork Basic Input/Output System (网络基本输入/输出系统) 该协议是由IBM 公司开发,主要用于数十台计算机的小型局域网。NetBIOS 协议是一种局域网上程序可 以使用的应用程序编程接口(API),为程序提供了请求低级服务的统一的命令集,作用是为了给局域网提供网络以及其他特殊功能,几乎所有的局域网都是在NetBIOS协议的基础上工作的。在 Windows 操作系统中,默认情况下在安装 TCP/IP 协议后会自动安装 NetBIOS。比 如在 Windows 2000/XP 中,当选择“自动获得 IP”后会启用DHCP服务器,从该服务器使用 NetBIOS 设置;如果使用静态 IP 地址或 DHCP 服务器不提供 NetBIOS 设置,则启用 TCP/IP 上的 NetBIOS。具体的设置方法如下:首先打开“控制面板” ,双击“网络连接”图标,打开 本地连接属性。接着,在属性窗口的“常规”选项卡中选择“Internet 协议(TCP/IP),单击 ” “属性”按钮。然后在打开的窗口中,单击“高级”按钮;在“高级 TCP/IP 设置”窗口中选 择“WINS”选项卡,在“NetBIOS 设置”区域中就可以进行相应的 NetBIOS 设置。
另外 NetBIOS 在百度百科是这么描述的:
NETBIOS协议是由IBM公司开发,主要用于数十台计算机的小型局域网。该协议是一种在局域网上的程序可以使用的应用程序编程接口(API),为程序提供了请求低级服务的统一的命令集,作用是为了给局域网提供网络以及其他特殊功能,系统可以利用WINS服务、广播及Lmhost文件等多种模式将NetBIOS名解析为相应IP地址,实现信息通讯,所以在局域网内部使用NetBIOS协议可以方便地实现消息通信及资源的共享。因为它占用系统资源少、传输效率高,所以几乎所有的局域网都是在NetBIOS协议的基础上工作的。
然后我们计算 Jaccard 相似度:
def splitWord(content): '''按逗号和句号分割句子''' sentence = [] if content.find(','): sentence.extend(content.split(',')) if content.find('。'): sentence.extend(content.split('。')) return sentence if __name__ == '__main__': with open('fromBook','r') as fromBook: fromBookContent = splitWord(fromBook.read()) with open('fromBaike','r') as fromBaike: fromBaikeContent = splitWord(fromBaike.read()) fromBookSet = set(fromBookContent) fromBaikeSet = set(fromBaikeContent) # 交集/并集。+0.0 是为了让结果成为 float 类型 print(len(fromBookSet.intersection(fromBaikeSet))+0.0)/len(fromBookSet.union(fromBaikeSet))
代码原理是这样的:把一段文字看作是一个集合,每一句话(通过句号和逗号分割)是集合中的一个元素,然后计算两个集合的 Jaccard 相似度。
运行结果:
$ python jaccard.py 0.0606060606061
SciPy 库提供了现成的算法:
from scipy.spatial.distance import jaccard import numpy as np a = np.array([1, 2, 3, 4]) b = np.array([3, 4, 5, 6]) jaccard(a, b) # => 1.0