6.8. 成对度量、亲和度和核函数#
sklearn.metrics.pairwise 子模块实现了用于评估样本集的成对距离或亲和度的工具。
此模块包含距离度量和核函数。这里简要总结了这两者。
距离度量是函数 d(a, b),如果对象 a 和 b 被认为比对象 a 和 c “更相似”,则 d(a, b) < d(a, c)。两个完全相同的对象之间的距离为零。最流行的例子之一是欧几里得距离。要成为“真正的”度量,它必须满足以下四个条件
1. d(a, b) >= 0, for all a and b
2. d(a, b) == 0, if and only if a = b, positive definiteness
3. d(a, b) == d(b, a), symmetry
4. d(a, c) <= d(a, b) + d(b, c), the triangle inequality
核函数是相似性的度量,即如果对象 a 和 b 被认为比对象 a 和 c “更相似”,则 s(a, b) > s(a, c)。核函数也必须是半正定的。
有很多方法可以将距离度量和相似性度量(例如核函数)相互转换。令 D 为距离,S 为核函数
- S = np.exp(-D * gamma),其中选择- gamma的一种启发式方法是
- gamma = 1 / num_features
 
- S = 1. / (D / np.max(D))
可以使用 pairwise_distances 评估 X 的行向量和 Y 的行向量之间的距离。如果省略 Y,则计算 X 的行向量的成对距离。类似地,可以使用 pairwise.pairwise_kernels 使用不同的核函数来计算 X 和 Y 之间的核函数。有关更多详细信息,请参阅 API 参考。
>>> import numpy as np
>>> from sklearn.metrics import pairwise_distances
>>> from sklearn.metrics.pairwise import pairwise_kernels
>>> X = np.array([[2, 3], [3, 5], [5, 8]])
>>> Y = np.array([[1, 0], [2, 1]])
>>> pairwise_distances(X, Y, metric='manhattan')
array([[ 4.,  2.],
       [ 7.,  5.],
       [12., 10.]])
>>> pairwise_distances(X, metric='manhattan')
array([[0., 3., 8.],
       [3., 0., 5.],
       [8., 5., 0.]])
>>> pairwise_kernels(X, Y, metric='linear')
array([[ 2.,  7.],
       [ 3., 11.],
       [ 5., 18.]])
6.8.1. 余弦相似度#
cosine_similarity 计算向量的 L2 归一化点积。也就是说,如果 \(x\) 和 \(y\) 是行向量,它们的余弦相似度 \(k\) 定义为
这被称为余弦相似度,因为欧几里德 (L2) 归一化将向量投影到单位球体上,然后它们的点积就是向量表示的点之间的角度的余弦。
此核函数是计算表示为 tf-idf 向量的文档相似度的常用选择。cosine_similarity 接受 scipy.sparse 矩阵。(请注意,sklearn.feature_extraction.text 中的 tf-idf 功能可以生成归一化向量,在这种情况下,cosine_similarity 等效于 linear_kernel,只是速度较慢。)
参考文献
- C.D. Manning, P. Raghavan 和 H. Schütze (2008)。信息检索导论。剑桥大学出版社。https://nlp.stanford.edu/IR-book/html/htmledition/the-vector-space-model-for-scoring-1.html 
6.8.2. 线性核#
函数 linear_kernel 计算线性核,它是 polynomial_kernel 的特例,其中 degree=1 和 coef0=0(齐次)。如果 x 和 y 是列向量,它们的线性核为
6.8.3. 多项式核#
函数 polynomial_kernel 计算两个向量之间的 d 次多项式核。多项式核表示两个向量之间的相似性。从概念上讲,多项式核不仅考虑相同维度下向量的相似性,还考虑跨维度的相似性。在机器学习算法中使用时,这允许考虑特征交互。
多项式核定义为
其中
- x,- y是输入向量
- d是核的次数
如果 \(c_0 = 0\),则该核被称为齐次核。
6.8.4. Sigmoid 核#
函数 sigmoid_kernel 计算两个向量之间的 Sigmoid 核。Sigmoid 核也称为双曲正切或多层感知器(因为在神经网络领域,它经常用作神经元激活函数)。它定义为
其中
- x,- y是输入向量
- \(\gamma\) 称为斜率 
- \(c_0\) 称为截距 
6.8.5. RBF 核#
函数 rbf_kernel 计算两个向量之间的径向基函数 (RBF) 核。此核定义为
其中 x 和 y 是输入向量。如果 \(\gamma = \sigma^{-2}\),则该核被称为方差为 \(\sigma^2\) 的高斯核。
6.8.6. 拉普拉斯核#
函数 laplacian_kernel 是径向基函数核的一个变体,定义为
其中 x 和 y 是输入向量,\(\|x-y\|_1\) 是输入向量之间的曼哈顿距离。
它已被证明在应用于无噪声数据的机器学习中很有用。例如,参见 量子力学的机器学习简述。
6.8.7. 卡方核#
卡方核是计算机视觉应用中训练非线性 SVM 的非常流行的选择。它可以使用 chi2_kernel 计算,然后传递给 kernel="precomputed" 的 SVC
>>> from sklearn.svm import SVC
>>> from sklearn.metrics.pairwise import chi2_kernel
>>> X = [[0, 1], [1, 0], [.2, .8], [.7, .3]]
>>> y = [0, 1, 0, 1]
>>> K = chi2_kernel(X, gamma=.5)
>>> K
array([[1.        , 0.36787944, 0.89483932, 0.58364548],
       [0.36787944, 1.        , 0.51341712, 0.83822343],
       [0.89483932, 0.51341712, 1.        , 0.7768366 ],
       [0.58364548, 0.83822343, 0.7768366 , 1.        ]])
>>> svm = SVC(kernel='precomputed').fit(K, y)
>>> svm.predict(K)
array([0, 1, 0, 1])
它也可以直接用作 kernel 参数
>>> svm = SVC(kernel=chi2_kernel).fit(X, y)
>>> svm.predict(X)
array([0, 1, 0, 1])
卡方核由下式给出
假设数据是非负的,并且通常被归一化到L1范数为1。这种归一化是基于与卡方距离的联系而合理的,卡方距离是离散概率分布之间的距离。
卡方核最常用于视觉词的直方图(bag-of-words)。
参考文献
- Zhang, J. and Marszalek, M. and Lazebnik, S. and Schmid, C. Local features and kernels for classification of texture and object categories: A comprehensive study 国际计算机视觉杂志 2007 https://hal.archives-ouvertes.fr/hal-00171412/document 
