ML:基礎技法學習
Package:scikit-learn
課程:
機器學習技法
簡介:第五講 Kernel Logistic Regression
SVM as Regularized Model
$$
\underset{b,\mathbf{w}}{min}\ \ \frac{1}{2}\mathbf{w}^T\mathbf{w}+C\sum_{n=1}^{N}max(1-y_n(\mathbf{w}^T\mathbf{z}_n+b),0)
$$
soft-margin SVM primal
$$
\begin{align*}
\underset{b,\mathbf{w},\boldsymbol\xi}{min} &\ \ \frac{1}{2}\mathbf{w}^T\mathbf{w}+C\cdot \sum_{n=1}^{N}\xi _n\\
subject\ to &\ \ y_n(\mathbf{w}^T\mathbf{x}_n+b) \geq 1-\xi _n\ and\ \xi _n\geq 0\ for\ all\ n
\end{align*}
$$
當 \((\mathbf{x}_n,y_n)\) 違反時,\(\xi _n=1-y_n(\mathbf{w}^T\mathbf{z}_n+b)\)
當 \((\mathbf{x}_n,y_n)\) 合法時,\(\xi _n=0\)
故可改寫為 \(\xi_n=max(1-y_n(\mathbf{w}^T\mathbf{z}_n+b),0)\)
得
$$
\underset{b,\mathbf{w}}{min}\ \ \frac{1}{2}\mathbf{w}^T\mathbf{w}+C\sum_{n=1}^{N}max(1-y_n(\mathbf{w}^T\mathbf{z}_n+b),0)
$$
仔細觀察,可發現這就是
L2 regularization 的變形而已
- large margin \(\Leftrightarrow \) fewer hyperplanes \(\Leftrightarrow \) L2 regularization of short W
- soft margin \(\Leftrightarrow \) special \(\widehat{err}\)
- larger C or C \(\Leftrightarrow \) smaller \(\lambda\) \(\Leftrightarrow \) less regularization
regularized LogReg \(\Rightarrow\) approximate SVM
- linear score \(s=\mathbf{w}^T\mathbf{z}_n+b\)
- \(err_{0/1}(s,y)=[ys \le 0]\)
- \(\color{Purple}{\widehat{err}_{SVM}}(s,y) = max(1-ys,0)\)
- \(\color{Orange}{err_{SCE} }(s,y)=log_2(1+e^{-ys})\)
從
Linear Models for Classification 得知
若 \(err \geq err_{0/1}\),當縮小 \(err\) 時,相當於也是在做分類
而從圖中看來
$$
\begin{matrix}
-\infty & \leftarrow & ys & \rightarrow & +\infty \\
\approx -ys & & \color{Purple}{ err_{SVM}}(s,y) & & \approx 0 \\
\approx -ys & & (ln\ 2)\cdot \color{Orange}{ err_{SCE}}(s,y) & & \approx 0
\end{matrix}
$$
故 L2-regularized logistic regression 其實就相當於在做 soft margin SVM
Platt's Model
$$
\begin{align*}
g(x) &= \theta (A\cdot (\mathbf{w}_{SVM}^T\boldsymbol\Phi (\mathbf{x})+b_{SVM})+B)\\
&=\theta (A\cdot (\sum_{SV}\alpha _ny_nK(\mathbf{x}_n,\mathbf{x})+b_{SVM})+B)\\
&=\theta (\sum_{SV}A\alpha _ny_nK(\mathbf{x}_n,\mathbf{x})+Ab_{SVM}+B)\\
\underset{A,B}{min} &\ \ \frac{1}{N}\sum_{n=1}^{N}log\left ( 1+e^{-y_n\left (A\cdot (\underset{\boldsymbol\Phi _{SVM}(\mathbf{x}_n)}{\underbrace{\mathbf{w}_{SVM}^T\boldsymbol\Phi (\mathbf{x})+b_{SVM}}})+B \right )} \right )
\end{align*}
$$
\(\boldsymbol\Phi _{SVM}(\mathbf{x}_n)\) 可視需求代入,像是 Kernel SVM 如上推導
該怎麼做,才能將 SVM 轉換為機率的表示呢?
簡單的想法如下圖
- 若像左邊一樣,最後再將結果用 logistic function 轉換,但這就喪失了 LogReg 的 maximum likelihood 的意義了
- 若像右邊一樣,先用 SVM 跑出初始值,再代入 LogReg,但這跟直接跑 LogReg 所得到的解是差不多的,所以 SVM 幾乎無任何作用,non-linear 也無法使用,像 kernel SVM 也無法應用在此
所以若改為先跑完 SVM,再運用 LogReg 修正一下呢?
$$
g(x) = \theta (A\cdot (\mathbf{w}_{SVM}^T\boldsymbol\Phi (\mathbf{x})+b_{SVM})+B)
$$
看起來可行,而且其實就是利用 A 調整 \(\mathbf{w}_{SVM}\),利用 A & B 調整 \(b_{SVM}\)
或是將 SVM 視為一種特別的轉換 \(\boldsymbol\Phi _{SVM}(\mathbf{x})\),從多維轉換至一維,再進行處理
骨子裡仍可使用 SVM 的各種方法,也就是 \(\boldsymbol\Phi _{SVM}(\mathbf{x})\) 可視需求代入,像是 Kernel SVM
- 這不是 Z 空間中最好的 LogReg 解,只是還不錯的解,需用 KLR 得最好解
- 若 \(
\mathbf{w}_{SVM}\) 夠好,通常 \(A > 0\)
假如 \(A < 0\),表示 SVM 在亂做,不然怎麼會完全反向
- 若 \( b_{SVM}\) 夠好,通常 \(B \approx 0\)
- 與原本 SVM 的邊界不一定一樣,因為 \(B\) 做了平移
- 如何解 LogReg
Kernel Logistic Regression (KLR)
Representer Theorem
claim: for any L2-regularized linear model
$$
\underset{\mathbf{w}}{min}\ \ \frac{\lambda}{N}\mathbf{w}^T\mathbf{w}+\frac{1}{N}\sum_{n=1}^{N}err(y_n,\mathbf{w}^T\mathbf{z}_n)
$$
optimal \(\mathbf{w}_*=\sum_{n=1}^{N}\beta _n\mathbf{z}_n\)
最佳化 \(\mathbf{w}_*\) 必是 \(\mathbf{z}_n\) 的線性組合
令 \(\mathbf{w}_*=\mathbf{w}_\parallel +\mathbf{w}_\perp \)
\(\mathbf{w}_\parallel \in span(\mathbf{z}_n)\) & \(\mathbf{w}_\perp \perp span(\mathbf{z}_n)\)
希望證得 \(\mathbf{w}_\perp=0\)
反證法
假設存在 \(\mathbf{w}_\perp\)
$$
\begin{align*}
err(y_n,\mathbf{w}_*^T\mathbf{z}_n) &= err(y_n,(\mathbf{w}_\parallel +\mathbf{w}_\perp)^T\mathbf{z}_n)\\
&= err(y_n,\mathbf{w}_\parallel^T\mathbf{z}_n +\underset{0}{\underbrace{\mathbf{w}_\perp^T\mathbf{z}_n}})\\
&= err(y_n,\mathbf{w}_\parallel^T\mathbf{z}_n)\\
\end{align*}
$$
err 的值,不因 \(\mathbf{w}_\perp\) 而變
$$
\begin{align*}
\mathbf{w}_*^T\mathbf{w}_* &= (\mathbf{w}_\parallel +\mathbf{w}_\perp)^T(\mathbf{w}_\parallel +\mathbf{w}_\perp)\\
&= \mathbf{w}_\parallel^T\mathbf{w}_\parallel + 2\mathbf{w}_\parallel ^T\mathbf{w}_\perp +\mathbf{w}_\perp^T\mathbf{w}_\perp\\
&= \mathbf{w}_\parallel^T\mathbf{w}_\parallel +\mathbf{w}_\perp^T\mathbf{w}_\perp\\
& >\mathbf{w}_\parallel^T\mathbf{w}_\parallel\\
\end{align*}
$$
矛盾,因 err 固定,而 \(\mathbf{w}_*\) 為最佳解,那麼在 \(\mathbf{w}^T\mathbf{w}\) 為何 \(\mathbf{w}_\parallel\) 還可以比 \(\mathbf{w}_*\) 更小
故最佳化 \(\mathbf{w}_*\) 必是 \(\mathbf{z}_n\) 的線性組合
$$
\begin{align*}
\underset{\boldsymbol\beta}{min}\ \ E_{in}(\boldsymbol\beta) &=\underset{\boldsymbol\beta }{min}\ \ \frac{\lambda}{N}\sum_{n=1}^{N}\sum_{m=1}^{N}\beta _n\beta _mK(\mathbf{x}_n,\mathbf{x}_m)+\frac{1}{N}\sum_{n=1}^{N}ln\left ( 1+e^{-y_n\sum_{m=1}^{N}\beta _mK(\mathbf{x}_m,\mathbf{x}_n)} \right )\\
&=\underset{\boldsymbol\beta }{min}\ \ \frac{\lambda}{N}\boldsymbol\beta^T\mathbf{K}\boldsymbol\beta+\frac{1}{N}\sum_{n=1}^{N}ln\left ( 1+e^{-y_n\boldsymbol\beta^T \mathbf{K}_{(:,n)}} \right )\\
\end{align*}
$$
因無限制條件,可利用 GD/SGD/... 求解
$$
$$
\begin{align*}
\bigtriangledown E_{in}(\boldsymbol\beta) &= \frac{\lambda}{N}2 \mathbf{K}^T\boldsymbol\beta+\frac{1}{N}\sum_{n=1}^{N}\frac{-y_n \mathbf{K}_{(:,n)}}{1+e^{y_n\boldsymbol\beta^T \mathbf{K}_{(:,n)}}}\\
\end{align*}
$$
$$
根據
機器學習基石:第十講 Logistic Regression &
機器學習基石:第十四講 Regularization 可得
L2-regularized logistic regression
$$
\begin{align*}
\underset{\mathbf{w}}{min}\ \ E_{in}(\mathbf{w}) &= \underset{\mathbf{w}}{min}\ \ \frac{\lambda }{N}\mathbf{w}^T\mathbf{w} + E_{in}(\mathbf{w}) \\
&=\underset{\mathbf{w}}{min}\ \ \frac{\lambda }{N}\mathbf{w}^T\mathbf{w} + \frac{1}{N}\sum_{n=1}^{N}ln (1+e^{-y_n\mathbf{w}^T\mathbf{z}_n})\\
(\because \mathbf{w}_*=\sum_{n=1}^{N}\beta _n\mathbf{z}_n)\ \underset{\boldsymbol\beta}{min}\ \ E_{in}(\boldsymbol\beta) &= \underset{\boldsymbol\beta}{min}\ \ \frac{\lambda}{N}(\sum_{n=1}^{N}\beta _n\mathbf{z}_n)^T\sum_{n=1}^{N}\beta _n\mathbf{z}_n + \frac{1}{N}\sum_{n=1}^{N}ln (1+e^{-y_n(\sum_{m=1}^{N}\beta _m\mathbf{z}_m)^T\mathbf{z}_n})\\
&= \underset{\boldsymbol\beta}{min}\ \ \frac{\lambda}{N}\sum_{n=1}^{N}\sum_{m=1}^{N}\beta _n\mathbf{z}_n^T\beta _m\mathbf{z}_m + \frac{1}{N}\sum_{n=1}^{N}ln (1+e^{-y_n(\sum_{n=1}^{N}\beta _m\mathbf{z}_m^T\mathbf{z}_n)})\\
(\because \mathbf{z}_n^T\mathbf{z}_m=K(\mathbf{x}_n,\mathbf{x}_m)) &= \underset{\boldsymbol\beta}{min}\ \ \frac{\lambda}{N}\sum_{n=1}^{N}\sum_{m=1}^{N}\beta _n\beta _m\mathbf{z}_n^T\mathbf{z}_m + \frac{1}{N}\sum_{n=1}^{N}ln (1+e^{-y_n(\sum_{n=1}^{N}\beta _mK(\mathbf{x}_m,\mathbf{x}_n))})\\
&= \underset{\boldsymbol\beta}{min}\ \ \frac{\lambda}{N}\sum_{n=1}^{N}\sum_{m=1}^{N}\beta _n\beta _mK(\mathbf{x}_n,\mathbf{x}_m) + \frac{1}{N}\sum_{n=1}^{N}ln (1+e^{-y_n(\sum_{n=1}^{N}\beta _mK(\mathbf{x}_m,\mathbf{x}_n))})\\
&=\underset{\boldsymbol\beta }{min}\ \ \frac{\lambda}{N}\sum_{n=1}^{N}\sum_{m=1}^{N}\beta _n\beta _mK(\mathbf{x}_n,\mathbf{x}_m)+\frac{1}{N}\sum_{n=1}^{N}ln\left ( 1+e^{-y_n\sum_{m=1}^{N}\beta _mK(\mathbf{x}_m,\mathbf{x}_n)} \right )\\
&=\underset{\boldsymbol\beta }{min}\ \ \frac{\lambda}{N}\boldsymbol\beta^T\mathbf{K}\boldsymbol\beta+\frac{1}{N}\sum_{n=1}^{N}ln\left ( 1+e^{-y_n\boldsymbol\beta^T \mathbf{K}_{(:,n)}} \right )\\
\\
\bigtriangledown E_{in}(\boldsymbol\beta) &= \frac{\lambda}{N}2 \mathbf{K}^T\boldsymbol\beta+\frac{1}{N}\sum_{n=1}^{N}\frac{1}{1+e^{-y_n\boldsymbol\beta^T \mathbf{K}_{(:,n)}}}e^{-y_n\boldsymbol\beta^T \mathbf{K}_{(:,n)}}(-y_n \mathbf{K}_{(:,n)})\\
&= \frac{\lambda}{N}2 \mathbf{K}^T\boldsymbol\beta+\frac{1}{N}\sum_{n=1}^{N}\frac{-y_n \mathbf{K}_{(:,n)}}{1+e^{y_n\boldsymbol\beta^T \mathbf{K}_{(:,n)}}}\\
\end{align*}
$$
- 兩種不同的角度
- KLR = linear model of \(\boldsymbol\beta\)
- \(\sum_{n=1}^{N}\sum_{m=1}^{N}\beta _n\beta _mK(\mathbf{x}_n,\mathbf{x}_m) = \boldsymbol\beta^T\mathbf{K}\boldsymbol\beta\),一種特別的 regularizer
- \(\sum_{m=1}^{N}\beta _mK(\mathbf{x}_m,\mathbf{x}_n)\) 可視同 \(\boldsymbol\beta\) 與 轉換過的資料 作內積
- kernel 作用在 轉換 與 regularizer
- KLR = linear model of \(\mathbf{w}\)
- 藏在 kernel 中,且為 L2 regularizer
- \(\boldsymbol\beta\)
- \(\beta_n\) 通常不為 0,與 \(\alpha_n\) 相反
import matplotlib.pyplot as plt
import numpy as np
from sklearn.svm import SVC
# kernel logistic regression
class KLR:
def __init__(self):
pass
# 高斯 kernel
def kernel_rbf(self, xn, xm):
kv = np.exp(-self.gamma * (np.linalg.norm(xn-xm)**2))
return kv
# 產生 kernel matrix
def kernelMatrix(self, x):
m = []
for xn in x:
row = [self.kernel_rbf(xn, xm) for xm in x]
m.append(row)
return np.array(m)
# error function
# lamda/N B^T K B + 1/N log(...)
def errFuc(self, x, y):
sum = 0
for n in range(self.N):
sum += np.log(1+np.exp(-y[n] * np.dot(self.beta,self.K[:,n])))
return self.lambda_/self.N * np.dot(self.beta, self.K).dot(self.beta) + sum/self.N
# 梯度方程式
def gradFuc(self, x, y):
err = np.array([0] * self.N)
for n in range(self.N):
val = y[n] * np.dot(self.beta, self.K[:,n])
temp = -y[n] * self.K[:,n] / (1 + np.exp(val))
err = np.add(err, temp)
val = self.lambda_/self.N * 2 * np.dot(self.K, self.beta) + 1/self.N * err
return val
# 訓練
def fit(self, x, y, gamma=0.5, lambda_=0.1, n=1, max_number=1000):
# 初始化
y[y==0] = -1
self.N = len(y)
self.beta = [1] * self.N
self.gamma = gamma
self.lambda_ = lambda_
self.x = x
self.K = self.kernelMatrix(x)
t = 0
while True:
g = self.gradFuc(x, y)
self.beta = self.beta - n*g
err = self.errFuc(x,y)
# print('{:4d} n:{:.3f} err : {}'.format(t, n, err))
t += 1
if t > max_number or err < 0.01:
break
# 預測結果
# w = sigma(b_n z_n)
# g = sigma(b_n kernel(x_n,x))
def predict(self, X):
k = []
for x in X:
m = []
for xn in self.x:
m.append(self.kernel_rbf(xn, x))
k.append(m)
k = np.array(k).T
p = np.dot(np.array(self.beta), k)
return p
# 訓練資料
X = np.c_[(.4, -.7),
(-1.5, -1),
(-1.4, -.9),
(-1.3, -1.2),
(-1.1, -.2),
(-1.2, -.4),
(-.5, 1.2),
(-1.5, 2.1),
(1, 1),
# --
(1.3, .8),
(1.2, .5),
(.2, -2),
(.5, -2.4),
(.2, -2.3),
(0, -2.7),
(1.3, 2.1)].T
Y = np.r_[[0] * 8 + [1] * 8]
# C 越大表示越無法容忍錯誤
C = 1.0
# exp(-2|x-x'|^2)
gamma = 2
classifiers = {"Platt's Model": SVC(kernel='rbf', gamma=gamma, C=C, probability=True),
'KLR': KLR(),
}
# 多少分類器
n_classifiers = len(classifiers)
# 產生 meshgrid,共 100x100 的點
XX1, XX2 = np.mgrid[-3:3:200j, -4:4:200j]
# 打平合併
Xfull = np.c_[XX1.ravel(), XX2.ravel()]
# 因是 dict 所以顯示不一定照順序
for index, (name, classifier) in enumerate(classifiers.items()):
# 訓練資料
classifier.fit(X, Y)
# 得到機率
if name == "Platt's Model":
# 取 1 的機率值,因接近 1 則機率越大,若取 0 會相反
probas = classifier.predict_proba(Xfull)[:, 1]
elif name == 'KLR':
probas = classifier.predict(Xfull)
plt.subplot(n_classifiers, 1, index + 1)
# 調整之間的空白高度
plt.subplots_adjust(hspace=.6)
# 重新排列結果,符合 XX1
probas = probas.reshape(XX1.shape)
# 畫圖,contour 不填滿顏色,contourf 填滿顏色
im = plt.contourf(XX1, XX2, probas, cmap="winter")
# 依圖畫出 colorbar
plt.colorbar(im)
# 畫出所有點
plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=plt.cm.Paired)
# 標題
plt.title("{}".format(name))
plt.show()
參考
sklearn.svm.SVC
sklearn.kernel_ridge.KernelRidge
留言
張貼留言