ML:基礎技法學習
Package:scikit-learn
課程:機器學習技法
簡介:第一講 linear SVM (support vector machine)
根據 PLA
以下三個圖皆符合條件,但何者最好呢?相信大部分的人都會選擇右邊的圖,因為 margin 最大
注意:此時的 不包含 , 也不包含 ,而
因此將這些點稱作 support vector,由這些點支撐出來的 margin
Package:scikit-learn
課程:機器學習技法
簡介:第一講 linear SVM (support vector machine)
根據 PLA
以下三個圖皆符合條件,但何者最好呢?相信大部分的人都會選擇右邊的圖,因為 margin 最大
基本 Model
首先,可以先想成,當線性可分時,要取出最大 margin 的那條線
而 margin 的定義,為所有資料點遠離線的最小距離
假設變數如下
如何求距離呢?
如下圖,可看到距離即是 投影在法向量的長度
即是平面上的向量
只有法向量的內積為 0,故 為法向量
因 只差在正負值,大小一樣,不影響 margin 取最小值,所以可用來拿掉絕對值
故可重新定義 model
平面方程式,不因 scaling 而有所不同,如下平面是一樣的
那麼利用一特別的 scaling 使得 最小的值為 1 (當為 1 時, 其實就在邊界 )
可再重新定義 model,且因為
所以 可以去掉
可以再被取代嗎?如下
因 比較寬鬆
要確保即使放鬆條件,解出來的解仍落在 之中
試想一情況,假設解出來的解令
那麼此時最佳解為 ,但因為 scaling 的關係,可得另一個解為
結果發現後者比前者在 還最佳化
矛盾,故即使使用 也不會令解落在 之外
再將 max 改一下
故得
而 margin 的定義,為所有資料點遠離線的最小距離
如下圖,可看到距離即是
法向量為
只有法向量的內積為 0,故
那麼利用一特別的 scaling 使得 最小的值為 1 (當為 1 時,
所以
要確保即使放鬆條件,解出來的解仍落在
試想一情況,假設解出來的解令
那麼此時最佳解為
結果發現後者比前者在
矛盾,故即使使用
再將 max 改一下
SVM 命名簡單說明
可以看到只有在邊緣的點,才會影響得到的解因此將這些點稱作 support vector,由這些點支撐出來的 margin
Linear Hard-Margin SVM Algorithm
SVM 優點
- 一種 Regularization
- 只是反過來求
的最小值 - 條件為
甚至還多了相乘必須等於 1 的條件 - 降低 VC dimention
- 降低非線性的複雜度
- import numpy as np
- import matplotlib.pyplot as plt
- from sklearn import svm
- # 建立 40 筆資料
- np.random.seed(0)
- # np.r_ 詳細說明 https://www.ptt.cc/bbs/Python/M.1490169034.A.2D4.html
- # np.r_ 的功能為新建立一個 row 陣列
- X = np.r_[np.random.randn(20, 2) - [2, 2], np.random.randn(20, 2) + [2, 2]]
- Y = [0] * 20 + [1] * 20
- # C 越大表示越無法容忍錯誤,故設定一很大的值 for hard margin
- g_svm = svm.SVC(kernel='linear', C=1e10)
- # 訓練
- g_svm.fit(X, Y)
- # 得到係數,為 wx+b
- w = g_svm.coef_[0]
- b = g_svm.intercept_[0]
- # 直線方程式 y=a1*x+b1
- a1 = -w[0] / w[1]
- b1 = -b / w[1]
- xx = np.linspace(-5, 5)
- yy = a1 * xx + b1
- # 得到第一個 support vectors
- p = g_svm.support_vectors_[0]
- # 斜率不變,求截距為 b1 = y-a1*x
- yy_down = a1 * xx + (p[1] - a1 * p[0])
- # 得到最後一個 support vectors,與上面相反的 y
- p = g_svm.support_vectors_[-1]
- # 斜率不變,求截距為 b1 = y-a1*x
- yy_up = a1 * xx + (p[1] - a1 * p[0])
- # 畫圖
- plt.plot(xx, yy, 'k-')
- plt.plot(xx, yy_down, 'k--')
- plt.plot(xx, yy_up, 'k--')
- # 畫出所有點
- plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=plt.cm.Paired)
- # 將 support vector 標示出來
- plt.scatter(g_svm.support_vectors_[:, 0], g_svm.support_vectors_[:, 1], color='g', linewidths=3, linestyle='-', s=100, facecolors='none')
- plt.show()
留言
張貼留言