6.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 的一種啟發式方法是

    gamma1 / 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.]])

6.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,只是速度較慢。)

參考文獻

6.8.2. 線性核函數#

函數 linear_kernel 計算線性核函數,也就是 polynomial_kernel 的特例,其中 degree=1coef0=0(同質)。如果 xy 是行向量,則它們的線性核函數為

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

6.8.3. 多項式核函數#

函數 polynomial_kernel 計算兩個向量之間 d 次多項式核函數。多項式核函數表示兩個向量之間的相似性。從概念上講,多項式核函數不僅考慮相同維度下向量之間的相似性,還考慮不同維度之間的相似性。當在機器學習演算法中使用時,這可以考慮特徵互動。

多項式核函數定義為

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

其中

  • xy 是輸入向量

  • d 是核函數次數

如果 \(c_0 = 0\),則該核函數被稱為同質的。

6.8.4. Sigmoid 核函數#

函數 sigmoid_kernel 計算兩個向量之間的 Sigmoid 核函數。Sigmoid 核函數也稱為雙曲正切函數或多層感知器(因為在神經網路領域中,它經常被用作神經元激活函數)。其定義為

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

其中

  • xy 是輸入向量

  • \(\gamma\) 被稱為斜率

  • \(c_0\) 被稱為截距

6.8.5. RBF 核函數#

函數 rbf_kernel 計算兩個向量之間的徑向基函數 (RBF) 核函數。此核函數定義為

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

其中 xy 是輸入向量。如果 \(\gamma = \sigma^{-2}\),則此核心函數被稱為變異數為 \(\sigma^2\) 的高斯核。

6.8.6. 拉普拉斯核#

函式 laplacian_kernel 是徑向基底函數核的一種變體,其定義如下:

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

其中 xy 是輸入向量,而 \(\|x-y\|_1\) 是輸入向量之間的曼哈頓距離。

它已證明在應用於無雜訊資料的機器學習中很有用。請參閱例如 Machine learning for quantum mechanics in a nutshell

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])

卡方核的公式如下:

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

假設資料是非負的,並且通常正規化為 L1 範數為 1。正規化的理由是它與卡方距離有關,卡方距離是離散機率分佈之間的距離。

卡方核最常在視覺單字的直方圖(袋)上使用。

參考文獻