核方法(二)


接續〈核方法(一)〉,核函數必須滿足 K(A, B) = φ(A) . φ(B),有什麼實際的例子呢?嗯…有啊!就 K(A, B) = A . B…

有講等於沒講嗎?其實 K(A, B) = A . B 是最簡單的線性核(Linear Kernel),顯然地,對應的 φ(X) = X,也就是沒有提高維度,直接在既有的維度上學習分類,簡單來說,就相當於沒有用到核方法。

若是 K(A, B) = (A . B)2,則為平方核心(quadratic kernel)的一個例子,例如,若 A 為 (a1, a2),B 為 (b1, b2),K(A, B) = (a1 * b1 + a2 * b2)2,將等號右邊試著計算與重新整理後,可以找出對應的 φ(X) = (x12, x22, sqrt(2) * x1 * x2)。

也就是說,若 A = (a1, a2),φ(A) = (a12, a22, sqrt(2) * a1 * a2),特徵被提高至三維的空間後,a1 * a2 若為正,也就是原本第一或第三象限的特徵,會被提高維度後會是位於第一卦限,a1 * a2 若為負,也就是原本第二或第四象限的特徵,被提高維度後會是會是位於第五卦限。

也就是原本的這些點:

核方法(二)

在提高維度之後會變成:

核方法(二)

雖然提高維度之後,點分佈投影在圖中的二維平面時,已經不是原本二維資料的點分佈了,然而如果原本第一或第三象限的特徵是一個分類,原本第二或第四象限的特徵是另一個分類,在提高維度之後,從卦限來看,它們依舊可以區別出是兩個分類,

這不就可以用來分類以下的點嗎?

核方法(二)

因為點在提昇維度之後,會是這樣:

核方法(二)

透過以上的方式,可以理解核函數有對應的 φ(X),這有助於你理解與選擇核函數,sklearn.kernel_approximation 提供了運用了核方法的實作,可以在 Kernel Approximation 看到基本說明,不過,相對於單純地隱含 φ(X) 的核方法,sklearn.kernel_approximation 中的實作可以明確地進行維度轉換,也就是你可以取得轉換維度後的特徵。

PolynomialCountSketch 實作了多項式核函數,若 gamma 為 1(預設)、degree 為 2(預設)、coef0 為 0(預設),就是方才看到的平方核心例子,n_components 可以決定維度。

來試著使用以下的程式實現方才提高維度後的圖形(資料 ab2.csv):

import numpy as np
import matplotlib.pyplot as plt
from sklearn.kernel_approximation import PolynomialCountSketch

data = np.loadtxt('ab2.csv', delimiter=',')

a = data[:,0]
b = data[:,1]
label = data[:,2]

zero = label == 0
one = label == 1

# 使用多項式核函數
rbf_feature = PolynomialCountSketch(n_components = 3)
X_features = rbf_feature.fit_transform(data[:,0:2])

aa = X_features[:,0]
bb = X_features[:,1]
cc = X_features[:,2]

ax = plt.axes(projection='3d')
ax.set_xlabel('a')
ax.set_ylabel('b')
ax.set_zlabel('c')
ax.set_box_aspect((1, 1, 1))
ax.scatter(aa[zero], bb[zero], cc[zero], marker = 'o')
ax.scatter(aa[one], bb[one], cc[one], marker = 'x')

plt.show()

這會顯示以下的結果:

核方法(二)

如果要應用在分類時,以下是個簡單的例子:

na = 10
nb = 20

# 使用感知器
p = Perceptron()
p.fit(X_features, label)
print(
    p.predict(
        rbf_feature.fit_transform([[na, nb]])
    )
) # 預測為 1

在應用核方法時,核函數的選擇是個挑戰,出發點應該是觀察資料,認識核函數,再選擇適當的核函數與參數,或者說資料分析本身就是個挑戰,核方法的本質,就是一種認識資料的方式嘛!