“古之善为士者,微妙玄通,深不可识。
夫唯不可识。
故强为之容:豫兮,若冬涉川;犹兮,若畏四邻;俨兮,其若客;涣兮,若冰之将释;孰兮,其若朴;旷兮,其若谷;浑兮,其若浊。
孰能浊以止,静之徐清?
孰能安以久,动之徐生?”[1]
在数据挖掘和数据分析中,经常会遇到需要知道个体数据间差异的大小,进而需要得到个体数据间的相似度,最常见的就是电商平台中对于物品的推荐以及内容平台中对于信息的推送等等。
相似度就是两个item之间的相似性,一般就是计算两个item的特征之间的距离
,距离越大,相似度越小;距离越小,相似度越大;也可以两个向量间的夹角
来表示,夹角越大,相似度越小;夹角越小,相似度越大;
常用的有以下四种方法:
- 欧几里得距离(Eucledian Distance)或称 欧氏距离
- 余弦相似度 (Cosine Similarity)
- 杰卡德相似系数(Jaccard Similarity coefficient)
- 皮尔逊相关系数(Pearson correlation)
欧几里得距离 or 欧氏距离
两个n维向量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的欧氏距离:
python代码常用的有两种,一种使用numpay,一种使用scipy:
import numpy as np
x=np.random.random(8)
y=np.random.random(8)
d1=np.sqrt(np.sum(np.square(x-y)))
d1
输出:
1.1282380087788222
from scipy.spatial.distance import pdist
z=np.vstack([x,y])
d2=pdist(z)
d2
输出:
array([ 1.12823801])
余弦相似度 (Cosine Similarity)
也可以叫余弦相似度。 几何中夹角余弦可用来衡量两个向量方向的差异,机器学习中借用这一概念来衡量样本向量之间的差异。余弦取值范围为[-1,1]。求得两个向量的夹角,并得出夹角对应的余弦值,此余弦值就可以用来表征这两个向量的相似性。夹角越小,趋近于0度,余弦值越接近于1,它们的方向更加吻合,则越相似。当两个向量的方向完全相反夹角余弦取最小值-1。当余弦值为0时,两向量正交,夹角为90度。因此可以看出,余弦相似度与向量的幅值无关,只与向量的方向相关。
两个n维样本点a(x11,x12,…,x1n)和b(x21,x22,…,x2n)的夹角余弦:
d3=np.dot(x,y)/(np.linalg.norm(x)*np.linalg.norm(y))
d3
输出:
0.70543665237781283
z=np.vstack([x,y])
d4=1-pdist(z,'cosine')
d4
输出:
array([ 0.70543665])
杰卡德相似系数(Jaccard Similarity coefficient)
杰卡德相似系数
两个集合A和B的交集元素在A,B的并集中所占的比例,称为两个集合的杰卡德相似系数,用符号J(A,B)表示。杰卡德相似系数是衡量两个集合的相似度一种指标。
杰卡德距离
与杰卡德相似系数相反的概念是杰卡德距离(Jaccard distance)。杰卡德距离用两个集合中不同元素占所有元素的比例来衡量两个集合的区分度。
杰卡德相似系数代码实现:
import numpy as np
from scipy.spatial.distance import pdist
x=np.random.random(8)>0.5
y=np.random.random(8)>0.5
x=np.asarray(x,np.int32)
y=np.asarray(y,np.int32)
#方法一:根据公式求解
up=np.double(np.bitwise_and((x != y),np.bitwise_or(x != 0, y != 0)).sum())
down=np.double(np.bitwise_or(x != 0, y != 0).sum())
d1=(up/down)
#方法二:根据scipy库求解
X=np.vstack([x,y])
d2=pdist(X,'jaccard')
皮尔逊相关系数(Pearson correlation)
皮尔逊相关系数的定义
前面提到的余弦相似度只与向量方向有关,但它会受到向量的平移影响,在夹角余弦公式中如果将 x 平移到 x+1, 余弦值就会改变。怎样才能实现平移不变性?这就要用到皮尔逊相关系数(Pearson correlation),有时候也直接叫相关系数。
如果将夹角余弦公式写成:
表示向量x和向量y之间的夹角余弦,则皮尔逊相关系数则可表示为:
皮尔逊相关系数具有平移不变性和尺度不变性,计算出了两个向量(维度)的相关性。
import numpy as np
x=np.random.random(8)
y=np.random.random(8)
#方法一:根据公式求解
x_=x-np.mean(x)
y_=y-np.mean(y)
d1=np.dot(x_,y_)/(np.linalg.norm(x_)*np.linalg.norm(y_))
#方法二:根据numpy库求解
X=np.vstack([x,y])
d2=np.corrcoef(X)[0][1]
相关系数是衡量随机变量X与Y相关程度的一种方法,相关系数的取值范围是[-1,1]。相关系数的绝对值越大,则表明X与Y相关度越高。当X与Y线性相关时,相关系数取值为1(正线性相关)或-1(负线性相关)。
-
老子《道德经》第十五章,老子故里,中国鹿邑。 ↩