1.相似性和想异性度量
度量数据的相似性和相异性主要包括以下方面的内容:
- 数数据矩阵和相异性矩阵;
- 标称属性的临近性度量;
- 二元属性的临近性度量;
- 数值属性的相异性:闵科夫斯基距离
2 数据矩阵和相异性矩阵
- 数据矩阵
数据矩阵或称对象-属性结构:这种数据结构用关系表的形式或n×𝑝矩阵存放n个数据对象:
每行对应于一个对象。在记号中,我们可能使用𝑓作为遍历p个属性的下标。 - 相异性矩阵
相异性矩阵或称对象-对象结构:存放n个对象两两之间的临近度,通常用一个n×𝑛的矩阵表示:
相似性度量可以表示成相异性度量的函数。例如对于标称数据:
3 标称属性的临近性度量
- 标称属性临近性
标称属性可以取两个或多个状态。例如,map_color是一个标称属性,他可以有比如说5状态:红、黄、绿、粉红和蓝。
设一个标称属性的状态数目是M。这些状态可以用字母、符号或者一组整数表示。这些整数只是用于数据处理,并不代表任何特点的顺序。
m: 匹配的数目(即i和j取值相同状态的属性数) p: 刻画对象的属性总数 - 标称属性之间的相异性
假设我们有表2.2种中的样本数据,不过只有对象标识符和属性test-1是可用的,其中test-1是标称的。
- 标称属性的相异性
由于我们只有一个标称属性test-1,我们令皮p=1,使得当对象i和j匹配时,d(i,j)=0,当对象不同时, d(i,j)=1。于是,我们得到:
相似性可以表示为:
4 二元属性的临近性度量
- 二元属性
二元属性只有两种状态:0或1,其中0表示该属性不出现,1表示出现。我们可以使用对称和非对称二元属性刻画对象间的相异性和相似性度量。 - 对称的二元属性
- 非对称的二元属性
非对称的二元属性,两个状态不是同等重要的;如病理化验的阳性(1)和阴性(1)结果。给定两个非对称的二元属性,两个都取值1的情况(正匹配)被认为比两个都取值0(负匹配)的情况更有意义。
对于非对称的二元属性,两个状态不是同等重要的。此时,i与j的相异性表示为:
对象i与j之间的非对称的二元相似性可以用下式计算:
5 数值属性的相异性
5.1距离的计算
- 欧几里得距离
- 曼哈顿距离
- 闵科夫斯基距离
其中,p是一个参量,p选取不同的值,表示不同的距离:
p=1时,表示曼哈顿距离;
p=2时,表示欧式距离;
p→∞ 时,表示切比雪夫距离
- 余弦相似性
对于稀疏矩阵,例比较文档或针对给定的查询词向量对文档排序,可以对文档向量或词频向量计算余弦相似性计算文档的相似距离。
6 代码实战
6.1 计算动物之间的闵科夫斯基距离
# 闵科夫斯基距离
def minkowskiDist(v1, v2, p):
"""假设v1和v2是两个等长的数值型数组
返回v1和v2之间阶为p的闵可夫斯基距离"""
dist = 0.0
for i in range(len(v1)):
dist += abs(v1[i] - v2[i])**p
return dist**(1/p)
6.2 计算动物之间的相似性
# 余弦相似度
def cos_sim(vector_a, vector_b):
"""
计算两个向量之间的余弦相似度
:param vector_a: 向量 a
:param vector_b: 向量 b
:return: sim
"""
vector_a = np.mat(vector_a)
vector_b = np.mat(vector_b)
num = float(vector_a * vector_b.T)
denom = np.linalg.norm(vector_a) * np.linalg.norm(vector_b)
cos = num / denom
sim = 0.5 + 0.5 * cos
return sim
7 完成代码
# *-* coding:utf-8 *-*
import numpy as np
# 闵科夫斯基距离
def minkowskiDist(v1, v2, p):
"""假设v1和v2是两个等长的数值型数组
返回v1和v2之间阶为p的闵可夫斯基距离"""
dist = 0.0
for i in range(len(v1)):
dist += abs(v1[i] - v2[i])**p
return dist**(1/p)
# 余弦相似度
def cos_sim(vector_a, vector_b):
"""
计算两个向量之间的余弦相似度
:param vector_a: 向量 a
:param vector_b: 向量 b
:return: sim
"""
vector_a = np.mat(vector_a)
vector_b = np.mat(vector_b)
num = float(vector_a * vector_b.T)
denom = np.linalg.norm(vector_a) * np.linalg.norm(vector_b)
cos = num / denom
sim = 0.5 + 0.5 * cos
return sim
# 主方法
if __name__ == '__main__':
rattle_snake = [1, 1, 1, 1, 0]
dart_frog = [1, 0, 1, 0, 4]
m_distance = minkowskiDist(rattle_snake, dart_frog, 2)
c_distance = cos_sim(rattle_snake, dart_frog)
print("闵科夫斯基距离: ", m_distance)
tance = minkowskiDist(rattle_snake, dart_frog, 2)
c_distance = cos_sim(rattle_snake, dart_frog)
print("闵科夫斯基距离: ", m_distance)
print("余弦相似度: ", c_distance)