7.8. 对偶度量、亲和性与核函数#

sklearn.metrics.pairwise子模块实现了评估样本集对偶距离或亲和性的实用工具。

此模块包含距离度量和核函数。此处将简要概述这两者。

距离度量是函数d(a, b),如果对象ab被认为比对象ac“更相似”,则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

核函数是相似性的度量,即如果对象ab被认为比对象ac“更相似”,则s(a, b) > s(a, c)。核函数还必须是半正定的。

有多种方法可以将距离度量转换为相似性度量,例如核函数。设D为距离,S为核函数

  1. S = np.exp(-D * gamma),其中一个选择

    gamma的启发式方法是1 / num_features

  2. S = 1. / (D / np.max(D))

可以使用pairwise_distances来评估X的行向量和Y的行向量之间的距离。如果省略Y,则计算X行向量之间的对偶距离。类似地,pairwise.pairwise_kernels可用于使用不同的核函数计算XY之间的核。更多详细信息请参阅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.]])

7.8.1. 余弦相似度#

cosine_similarity计算向量的L2范数归一化点积。也就是说,如果\(x\)\(y\)是行向量,它们的余弦相似度\(k\)定义为

\[k(x, y) = \frac{x y^\top}{\|x\| \|y\|}\]

这被称为余弦相似度,因为欧氏(L2)归一化将向量投影到单位球体上,此时它们的点积就是由这些向量所表示点之间的夹角的余弦值。

此核函数是计算表示为tf-idf向量的文档相似度的常用选择。cosine_similarity接受scipy.sparse矩阵。(请注意,sklearn.feature_extraction.text中的tf-idf功能可以生成归一化向量,在这种情况下,cosine_similarity等同于linear_kernel,只是速度较慢。)

参考文献

7.8.2. 线性核函数#

函数linear_kernel计算线性核,它是polynomial_kerneldegree=1coef0=0(齐次)时的特例。如果xy是列向量,它们的线性核为

\[k(x, y) = x^\top y\]

7.8.3. 多项式核函数#

函数polynomial_kernel计算两个向量之间的d次多项式核函数。多项式核函数表示两个向量之间的相似度。从概念上讲,多项式核函数不仅考虑同一维度下向量之间的相似性,还考虑跨维度之间的相似性。当在机器学习算法中使用时,这允许考虑特征交互。

多项式核函数的定义为

\[k(x, y) = (\gamma x^\top y +c_0)^d\]

其中

  • x, y是输入向量

  • d是核函数的次数

如果\(c_0 = 0\),则该核函数被称为齐次核函数。

7.8.4. Sigmoid核函数#

函数sigmoid_kernel计算两个向量之间的sigmoid核函数。sigmoid核函数也称为双曲正切或多层感知器(因为在神经网络领域,它常被用作神经元激活函数)。其定义为

\[k(x, y) = \tanh( \gamma x^\top y + c_0)\]

其中

  • x, y是输入向量

  • \(\gamma\)称为斜率

  • \(c_0\)称为截距

7.8.5. RBF核函数#

函数rbf_kernel计算两个向量之间的径向基函数(RBF)核。此核函数定义为

\[k(x, y) = \exp( -\gamma \| x-y \|^2)\]

其中xy是输入向量。如果\(\gamma = \sigma^{-2}\),则该核函数被称为方差为\(\sigma^2\)的高斯核函数。

7.8.6. 拉普拉斯核函数#

函数laplacian_kernel是径向基函数核的一个变体,定义为

\[k(x, y) = \exp( -\gamma \| x-y \|_1)\]

其中xy是输入向量,\(\|x-y\|_1\)是输入向量之间的曼哈顿距离。

它已被证明在应用于无噪声数据的机器学习中非常有用。例如参见量子力学的机器学习简述

7.8.7. 卡方核函数#

卡方核函数是计算机视觉应用中训练非线性支持向量机的热门选择。它可以使用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])

卡方核函数的定义为

\[k(x, y) = \exp \left (-\gamma \sum_i \frac{(x[i] - y[i]) ^ 2}{x[i] + y[i]} \right )\]

数据被假定为非负,并且通常归一化使其L1范数为一。这种归一化与卡方距离(离散概率分布之间的距离)有联系,从而得到了合理的解释。

卡方核函数最常用于视觉词袋直方图。

参考文献