ML:基礎技法學習
Package:scikit-learn
課程:
機器學習技法
簡介:第六講 Support Vector Regression (SVR)
Kernel Ridge Regression (KRR)
時間複雜度為 ,且 大部分不為 0
L2-regularized linear model
By
Representer Theorem optimal
將 代入
若直接展開如下
借由
矩陣微分
區域最佳解,微分等於 0,故
因 且 為半正定,故反矩陣必定存在
時間複雜度為 ,且
大部分不為 0
Support Vector Regression (SVR)
Primal
QP of 個變數, 個條件
Dual
QP of 個變數, 個條件
只有在 tube 邊界和以外的才是 SV
希望 的特性與 一樣,大部分皆是 0
首先重新定義 err 從 square regression 改為 tube regression
也就是當錯誤在水管範圍內,則視為沒有錯誤,也就是 時,err=0
若超過時,則扣掉水管範圍部分,也就是 時,err=
可得
如圖,可看到 err 在兩者接近 s 時,大約相同,遠離時 tube 成長幅度比較沒那麼劇烈
於是得到 L2-Regularized Tube Regression
為了更接近標準的 SVM 定義,重新調整參數
最後加上 的原因,是為了更加符合標準的定義,且因為加上 但又對其最小化,不影響原先結果
用 表達錯誤,重新定義方程式,當 時,,不然就
絕對值仍存在,還不是線性方程式,故再將之展開,並將 定義上下限
且將 反向,符合常用定義
故可得 primal,QP of 個變數, 個條件
但這還不是想要的,dual 又該如何得到呢?
利用 Lagrange multipliers,隱藏限制條件,此處將 用 & & & 取代
當 會發現
- 違反限制條件時,會導致
-
又因 針對 取 max 的緣故, 越大越好
-
又因
針對 取 max 的緣故, 越大越好
-
又因
針對 取 max 的緣故, 越大越好
-
又因
針對 取 max 的緣故, 越大越好
- 使得
- 符合限制條件時,會導致
又因 針對 取 max 的緣故, 與 兩者至少有一個必須為 0
又因
針對 取 max 的緣故, 與
兩者至少有一個必須為 0
-
又因
針對 取 max 的緣故, 與 兩者至少有一個必須為 0
-
又因
針對 取 max 的緣故, 與 兩者至少有一個必須為 0
- 使得
故此式子與原本的求解一樣,如下,只是限制條件被隱藏到 max 中
此時 仍在式子最外面,如何把它跟裡面的 交換呢?
這樣才能初步得到 4N 個變數的式子
任取一個 with
因取 max 一定比任意還大,可得下式
那如果對 取 max,也不影響此等式,如下
比較直覺的想法,就像是「從最大的一群中取最小」一定 「從最小的一群中取最大」
目前的關係稱作 weak duality
但這還不夠,最好是 strong duality,才能初步得到 4N 個變數的式子
幸運的是,在 QP 中,只要滿足以下條件,便是 strong duality
- convex primal (原來的問題為 convex)
- feasible primal (原來的問題有解的,也就是線性可分)
- linear constraints (限制條件為線性的)
對於 SVM 滿足這些條件並不困難,故解以下的式子,如同解原本的式子
但如何把內部的 拿掉呢?
內部的問題,當最佳化時,必定符合
從以上的這些條件,可得
將限制條件移出
可得
求 共 個變數
限制條件 有 個,加上 ,共
已知
那如何得 呢?利用 KKT
利用以上其中一組條件可得
或是
故
而可以發現,當錯誤在 tube 內的話
- 若為下限處
&
故
- 若為上限處
&
故
- 此時
也就是
達到 sparse 的要求,只有在 tube 邊界和以外的才是 SV
Model 總結
- 分類
- linear
- kernel
- SVM
- ,dual SVM
- solver : QP
- librabry:LIBSVM
- 回歸
- linear
- kernel
- kernel ridge regression (KRR)
- SVR
-
- solver : QP
- librabry:LIBSVM
- 機率預測
- kernel model 務必小心 overfitting
程式碼
- from __future__ import division
- import time
- import numpy as np
- from sklearn.svm import SVR
- from sklearn.kernel_ridge import KernelRidge
- from sklearn.model_selection import learning_curve
- import matplotlib.pyplot as plt
-
- # 設定 seed
- rng = np.random.RandomState(0)
-
- # 訓練資料
- X = 5 * rng.rand(10000, 1)
- y = np.sin(X).ravel()
-
- # 加入 noise
- y[::5] += 3 * (0.5 - rng.rand(X.shape[0] // 5))
-
- # 畫圖的資料,新增二維維度
- X_plot = np.linspace(0, 5, 100000)[:, None]
-
- # 訓練大小
- train_size = 1000
-
- # model
- svr = SVR(kernel='rbf', gamma=0.1, epsilon=0.1)
- krr = KernelRidge(kernel='rbf', gamma=0.1)
-
- # 計算 SVR 訓練時間
- t0 = time.time()
- svr.fit(X[:train_size], y[:train_size])
- svr_fit = time.time() - t0
- print("SVR complexity and bandwidth selected and model fitted in %.3f s"
- % svr_fit)
-
- # 計算 KRR 訓練時間
- t0 = time.time()
- krr.fit(X[:train_size], y[:train_size])
- krr_fit = time.time() - t0
- print("KRR complexity and bandwidth selected and model fitted in %.3f s"
- % krr_fit)
-
- # 計算 SVR 預測時間
- t0 = time.time()
- y_svr = svr.predict(X_plot)
- svr_predict = time.time() - t0
- print("SVR prediction for %d inputs in %.3f s"
- % (X_plot.shape[0], svr_predict))
-
- # 計算 KRR 預測時間
- t0 = time.time()
- y_krr = krr.predict(X_plot)
- krr_predict = time.time() - t0
- print("KRR prediction for %d inputs in %.3f s"
- % (X_plot.shape[0], krr_predict))
-
- # SVR 的 support vector
- sv_ind = svr.support_
-
- plt.subplot(2,1,1)
- # 畫出 SV
- plt.scatter(X[sv_ind], y[sv_ind], c='b', s=50, label='SVR support vectors', zorder=2)
- # 畫出 data
- plt.scatter(X[:], y[:], c='k', label='data', zorder=1)
- # 畫出 SVR 的曲線
- plt.plot(X_plot, y_svr, c='r',
- label='SVR (fit: %.3fs, predict: %.3fs)' % (svr_fit, svr_predict))
- # 畫出 KRR 的曲線
- plt.plot(X_plot, y_krr, c='g',
- label='KRR (fit: %.3fs, predict: %.3fs)' % (krr_fit, krr_predict))
- plt.xlabel('data')
- plt.ylabel('target')
- plt.title('SVR versus Kernel Ridge')
- plt.legend()
-
- # Visualize learning curves
- plt.subplot(2,1,2)
-
- # model
- svr = SVR(kernel='rbf', C=1e1, gamma=0.1, epsilon=0.1)
- krr = KernelRidge(kernel='rbf', alpha=0.1, gamma=0.1)
-
- # cv = cross-validation,5 表示五份
- train_sizes, train_scores_svr, test_scores_svr = \
- learning_curve(svr, X[:100], y[:100], train_sizes=np.linspace(0.1, 1, 10),
- scoring="neg_mean_squared_error", cv=5)
- train_sizes_abs, train_scores_krr, test_scores_krr = \
- learning_curve(krr, X[:100], y[:100], train_sizes=np.linspace(0.1, 1, 10),
- scoring="neg_mean_squared_error", cv=5)
-
- plt.plot(train_sizes, -test_scores_svr.mean(1), 'o-', color="r",
- label="SVR")
- plt.plot(train_sizes, -test_scores_krr.mean(1), 'o-', color="g",
- label="KRR")
- plt.xlabel("Train size")
- plt.ylabel("Mean Squared Error")
- plt.title('Learning curves')
- plt.legend(loc="best")
-
- # 調整之間的空白高度
- plt.subplots_adjust(hspace=0.6)
- plt.show()
參考
sklearn.kernel_ridge.KernelRidge
sklearn.svm.SVR
sklearn.model_selection.learning_curve
留言
張貼留言