目錄html
更新、更全的《機器學習》的更新網站,更有python、go、數據結構與算法、爬蟲、人工智能教學等着你:http://www.javashuo.com/article/p-vozphyqp-cm.htmlpython
支持向量機(support vector machines,SVM)誕生二十多年,因爲它良好的分類性能席捲了機器學習領域,若是不考慮集成學習、不考慮特定的訓練數據集,SVM因爲泛化能力強,所以在分類算法中的表現排第一是沒有什麼異議的,一般狀況下它也是首選分類器。近幾年SVM在圖像分類領域雖有被深度學習趕超的趨勢,但因爲深度學習須要大量的數據驅動所以在某些領域SVM仍是沒法替代的。算法
SVM是一種二分類模型,它的基本模型是定義在特徵空間上的間隔最大的線性分類器,間隔最大化也使它不一樣於感知機;SVM還有核技巧,也所以它也是一個非線性分類器。數據結構
SVM經過學得模型構建的難度由簡至繁能夠劃分爲如下三種:dom
因爲《感知機》一文中詳細的介紹過線性可分與線性不可分的區別,這裏只給出圖例便於理解線性支持向量機和非線性支持向量機。機器學習
# 線性可分與線性不可分圖例 import numpy as np import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties %matplotlib inline font = FontProperties(fname='/Library/Fonts/Heiti.ttc') np.random.seed(1) x1 = np.random.random(20)+1.5 y1 = np.random.random(20)+0.5 x2 = np.random.random(20)+3 y2 = np.random.random(20)+0.5 # 一行二列第一個 plt.subplot(121) plt.scatter(x1, y1, s=50, color='b', label='男孩(+1)') plt.scatter(x2, y2, s=50, color='r', label='女孩(-1)') plt.vlines(2.8, 0, 2, colors="r", linestyles="-", label='$wx+b=0$') plt.title('線性可分', fontproperties=font, fontsize=20) plt.xlabel('x') plt.legend(prop=font) # 一行二列第二個 plt.subplot(122) plt.scatter(x1, y1, s=50, color='b', label='男孩(+1)') plt.scatter(x2, y2, s=50, color='r', label='女孩(-1)') plt.scatter(3.5, 1, s=50, color='b') plt.scatter(3.6, 1.2, s=50, color='b') plt.scatter(3.9, 1.3, s=50, color='b') plt.scatter(3.8, 1.3, s=50, color='b') plt.scatter(3.7, 0.6, s=50, color='b') plt.title('線性不可分', fontproperties=font, fontsize=20) plt.xlabel('x') plt.legend(prop=font) plt.show()
《感知機》一文中詳細講解過感知機模型的原理,此處很少贅述,簡單歸納。函數
在二維空間中,感知機模型試圖找到一條直線可以把二元數據分隔開;在高維空間中感知機模型試圖找到一個超平面\(S\),可以把二元數據隔離開。這個超平面\(S\)爲\(\omega{x}+b=0\),在超平面\(S\)上方的數據定義爲\(1\),在超平面\(S\)下方的數據定義爲\(-1\),即當\(\omega{x}>0\),\(\hat{y}=+1\);當\(\omega{x}<0\),\(\hat{y}=-1\)。性能
上張線性可分和線性不可分的區別圖第一張圖則找到了一條直線可以把二元數據分隔開,可是可以發現事實上可能不僅存在一條直線將數據劃分爲兩類,所以再找到這些直線後還須要找到一條最優直線,對於這一點感知機模型使用的策略是讓全部誤分類點到超平面的距離和最小,即最小化該式
\[ J(\omega)=\sum_{{x_i}\in{M}} {\frac{- y_i(\omega{x_i}+b)}{||\omega||_2}} \]
上式中能夠看出若是\(\omega\)和\(b\)成比例的增長,則分子的\(\omega\)和\(b\)擴大\(n\)倍時,分母的L2範數也將擴大\(n\)倍,也就是說分子和分母有固定的倍數關係,既能夠分母\(||\omega||_2\)固定爲\(1\),而後求分子的最小化做爲代價函數,所以給定感知機的目標函數爲
\[ J(\omega)=\sum_{{x_i}\in{M}} - y_i(\omega{x_i}+b) \]
既然分子和分母有固定倍數,那麼可不能夠固定分子,把分母的倒數做爲目標函數呢?必定是能夠的,固定分子就是支持向量機使用的策略。學習
# 確信度圖例 import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties %matplotlib inline font = FontProperties(fname='/Library/Fonts/Heiti.ttc') x1 = [1, 2, 2.5, 3.2] x11 = [4.5, 5, 6] x2 = [1, 1.2, 1.4, 1.5] x22 = [1.5, 1.3, 1] plt.scatter(x1, x2, s=50, color='b', label='+1') plt.scatter(x11, x22, s=50, color='r', label='-1') plt.vlines(3.5, 0.8, 2, colors="g", linestyles="-", label='$w*x+b=0$') plt.text(2, 1.3, s='A', fontsize=15, color='k', ha='center') plt.text(2.5, 1.5, s='B', fontsize=15, color='k', ha='center') plt.text(3.2, 1.6, s='C', fontsize=15, color='k', ha='center') plt.legend() plt.show()
上圖有均在超平面正類的A,B,C三個點。由於點A距離超平面遠,若是預測爲正類點,就比較確信預測時正確的;點C距離超平面較近,若是預測爲正類點就不那麼確信,由於超平面可能存在着多條,有可能有另外一條更優的超平面\(\omega{x}+b=0\);點B介於A和C之間,則其預測爲正類點的確信度介於A和C之間。優化
一個點距離超平面的遠近能夠表示分類預測的確信程度。在超平面固定位\(\omega{x}+b=0\)的狀況下,\(|\omega+b=0|\)表示點\(x\)到超平面的相對距離,而\(\omega{x}\)和\(y\)是否同號可以判斷分類是否正確,因此能夠用量\(y(\omega{x}+b)\)表示分類的正確性和確信度,這就是函數間隔(functional margin)的概念。
給定數據集\(T\)和超平面\((\omega,b)\),定義超平面\((\omega,b)\)關於樣本點\((x_i,y_i)\)的函數間隔爲
\[ \hat{\gamma_i} = y_i(\omega{x_i}+b) \]
對於訓練集\(T\)中\(m\)個樣本點對應的\(m\)個函數間隔的最小值,就是整個訓練集的函數間隔,即
\[ \hat{\gamma} = \underbrace{min}_{i=1,\ldots,m}\hat{\gamma_i} \]
函數間隔並不能正常反應點到超平面的距離,由於只要成比例的改變\(\omega\)和\(b\),超平面卻並無改變,但函數間隔卻會變爲原來的兩倍。
因爲函數間隔不能反應點到超平面的距離,所以能夠對超平面的法向量\(\omega\)加上約束條件,例如感知機模型中規範化\(||\omega||=1\),使得間隔是肯定的。此時的函數間隔將會變成幾何間隔(geometric margin)。
對於某一實例\(x_i\),其類標記爲\(y_i\),則改點的幾何間隔的定義爲
\[ \gamma_i = {\frac{y_i(\omega{x_i}+b)}{||\omega||}} \]
對於訓練集\(T\)中\(m\)個樣本點對應的\(m\)個函數間隔的最小值,就是整個訓練集的幾何間隔,即
\[ \gamma = \underbrace{min}_{i=1,\ldots,m}\gamma_i \]
幾何間隔纔是點到超平面的真正距離,感知機模型用到的距離就是幾何間隔。
由函數間隔和幾何間隔的定義可知函數間隔和幾何間隔有如下的關係
\[ \gamma = {\frac{\hat{\gamma}}{||\omega||}} \]
因爲能夠找到多個超平面將數據分開致使離超平面近的點不確信度高,所以感知機模型優化時但願全部的點都離超平面遠。可是離超平面較遠的點已經被正確分類,讓它們離超平面更遠毫無心義。因爲是離超平面近的點容易被誤分類,所以次可讓離超平面較近的點儘量的遠離超平面,這樣才能提高模型的分類效果,這正是SVM思想的起源。
# 間隔最大化圖例 import numpy as np import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties from sklearn import svm %matplotlib inline font = FontProperties(fname='/Library/Fonts/Heiti.ttc') np.random.seed(8) # 保證數據隨機的惟一性 # 構造線性可分數據點 array = np.random.randn(20, 2) X = np.r_[array-[3, 3], array+[3, 3]] y = [0]*20+[1]*20 # 創建svm模型 clf = svm.SVC(kernel='linear') clf.fit(X, y) # 構造等網個方陣 x1_min, x1_max = X[:, 0].min(), X[:, 0].max(), x2_min, x2_max = X[:, 1].min(), X[:, 1].max(), x1, x2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max)) # 獲得向量w: w_0x_1+w_1x_2+b=0 w = clf.coef_[0] # 加1後纔可繪製 -1 的等高線 [-1,0,1] + 1 = [0,1,2] f = w[0]*x1 + w[1]*x2 + clf.intercept_[0] + 1 # 繪製H1,即wx+b=-1 plt.contour(x1, x2, f, [0], colors='k', linestyles='--') plt.text(2, -4, s='$H_2={\omega}x+b=-1$', fontsize=10, color='r', ha='center') # 繪製分隔超平面,即wx+b=0 plt.contour(x1, x2, f, [1], colors='k') plt.text(2.5, -2, s='$\omega{x}+b=0$', fontsize=10, color='r', ha='center') plt.text(2.5, -2.5, s='分離超平面', fontsize=10, color='r', ha='center', fontproperties=font) # 繪製H2,即wx+b=1 plt.contour(x1, x2, f, [2], colors='k', linestyles='--') plt.text(3, 0, s='$H_1=\omega{x}+b=1$', fontsize=10, color='r', ha='center') # 繪製數據散點圖 plt.scatter(X[0:20, 0], X[0:20, 1], cmap=plt.cm.Paired, marker='x') plt.text(1, 1.8, s='支持向量', fontsize=10, color='gray', ha='center', fontproperties=font) plt.scatter(X[20:40, 0], X[20:40, 1], cmap=plt.cm.Paired, marker='o') plt.text(-1.5, -0.5, s='支持向量', fontsize=10, color='gray', ha='center', fontproperties=font) # plt.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,1) # 繪製支持向量點 plt.xlim(x1_min-1, x1_max+1) plt.ylim(x2_min-1, x2_max+1) plt.show()
如上圖所示,分離超平面爲\(\omega{x}+b=0\)。若是全部的樣本不光能夠被分離超平面分開,還和分離超平面保持必定的函數間隔(上圖的函數間隔爲1)。
對於\(y_i=1\)的正例點,支持向量在超平面\(H_1:\omega{x}+b=1\)上;對於\(y_i=-1\)的負例點,支持向量在超平面\(H_2:\omega{x}+b=-1\)上,即在\(H_1\)和\(H_2\)上的點就是支持向量(support vector)。
圖中虛線所示的兩個平行的超平面\(H_1\)和\(H_2\)之間的距離稱爲間隔(margin),間隔依賴於分離超平面的法向量\(\omega\),等於\({\frac{2}{||\omega||}}\)。
由此能夠看出只有支持向量決定分離超平面的位置,即其餘實例點對分離超平面沒有影響。正式因爲支持向量在肯定分離超平面的時候起着決定性的做用,因此將這種分類模型稱做支持向量機。因爲支持向量的個數通常不多,所以支持向量機由不多的重要的樣本肯定。
上一節講到了SVM的模型其實就是讓全部點到分離超平面的距離大於必定的距離,即全部已被分類的點要在各自類別的支持向量的兩邊,即但願最大化超平面\((\omega,b)\)關於訓練數據集的幾何間隔\(\gamma\),這個問題能夠表示爲下面的約束最優化問題
\[ \begin{align} & \underbrace{\max}_{\omega,b} \gamma \\ & s.t. \quad {\frac{y_i(\omega{x_i}+b)}{||\omega||}}\geq\gamma, \quad i=1,2,\ldots,m \end{align} \]
其中\(m\)表示\(m\)個樣本,\(s.t.\)表示「subject to(使得…知足…)」,即約束條件,該約束條件指的是超平面\((\omega,b)\)關於每一個訓練樣本的集合間隔至少是\(\gamma\)。
經過函數間隔和幾何間隔的關係,能夠把上述式子改寫成
\[ \begin{align} & \underbrace{\max}_{\omega,b} {\frac{\hat{\gamma}}{||\omega||}} \\ & s.t. \quad y_i(\omega{x_i}+b)\geq\hat{\gamma}, \quad i=1,2,\ldots,m \end{align} \]
若是將\(\omega\)和\(b\)按比例改變成\(\lambda{\omega}\)和\(\lambda{b}\),此時的函數間隔爲\(\lambda{\hat{\gamma}}\),即\(y_i(\omega{x_i}+b)\geq\hat{\gamma}\)必定成立,所以函數間隔\(\hat{\gamma}\)並不影響最優化問題的解,即函數間隔對上面的最優化問題的不等式約束沒有影響,所以能夠取\(\hat{\gamma}=1\)。這樣最優化問題變成了
\[ \begin{align} & \underbrace{\max}_{\omega,b} {\frac{1}{||\omega||}} \\ & s.t. \quad y_i(\omega{x_i}+b)\geq1, \quad i=1,2,\ldots,m \end{align} \]
能夠看出這個最優化問題和感知機的優化問題是不一樣的,感知機是固定分母優化分子,而SVM在加上了支持向量的同時固定分子優化分母。
注意最大化\({\frac{1}{||\omega||}}\)即最小化\(||\omega|||\),考慮到二範數的性質,所以加個平方,即最小化\({\frac{1}{2}}{||\omega||}^2\),則能夠獲得線性可分支持向量機的最優化問題,即目標函數的最優化問題,即硬間隔最大化爲
\[ \begin{align} & \underbrace{\min}_{\omega,b} {\frac{1}{2}}{||\omega||}^2 \\ & s.t. \quad y_i(\omega{x_i}+b)\geq1, \quad i=1,2,\ldots,m \end{align} \]
其中\({\frac{1}{2}}{||\omega||}^2\)爲目標函數
因爲目標函數的最優化問題中的目標函數是連續可微的凸函數,約束函數是仿射函數(注:若是\(f(x)=a*x+b\),則\(f(x)\)稱爲仿射函數),則該問題是一個凸最優化問題。又因爲目標函數是二次函數,則該凸最優化問題變成了凸二次規劃問題。
若是求出了目標函數最優化問題中的解\(\omega^*,b^*\),則能夠獲得最大間隔分離超平面\({\omega^*}^Tx+b^*=0\)和分類決策函數\(f(x)=sign({\omega^*}^Tx+b^*)\)(注:sign函數即符號函數,相似於Sigmoid函數的圖形),即線性可分支持向量機模型。
根據凸優化理論,能夠經過拉格朗日函數把優化有約束的目標函數轉化爲優化無約束的目標函數。既應用拉格朗日對偶性(注:詳見《拉格朗日對偶性》),經過求解對偶問題獲得原始問題的最優解,進而把線性可分支持向量機的最優化問題做爲原始最優化問題,有時也稱該方法爲線性可分支持向量機的對偶算法(dual algorithm)。
首先引進拉格朗日乘子(Lagrange multiplier)\(\alpha_i\geq0, \quad i=1,2,\ldots,m\),而後構建拉格朗日函數(Lagrange function)
\[ L(\omega,b,\alpha) = {\frac{1}{2}}{||\omega||}^2-\sum_{i=1}^m\alpha_iy_i(\omega{x_i}+b)+\sum_{i=1}^m\alpha_i \]
其中\(\alpha=(\alpha_1,\alpha_2,\ldots,\alpha_m)^T\)爲拉格朗日乘子向量。
所以優化問題變成
\[ \underbrace{\min}_{\omega,b} \underbrace{\max}_{\alpha_i\geq0} L(\omega,b,\alpha) \]
因爲這個優化問題知足Karush-Kuhn-Tucker(KKT)條件(注:詳見《拉格朗日對偶性》),既能夠經過拉格朗日對偶性把上述的優化問題轉化爲等價的對偶問題,即優化目標變成
\[ \underbrace{\max}_{\alpha_i\geq0} \underbrace{\min}_{\omega,b} L(\omega,b,\alpha) \]
從上式中,則能夠先求優化函數對於\(\omega\)和\(b\)的極小值,接着再求拉格朗日乘子\(\alpha\)的極大值。
經過對\(\omega\)和\(b\)分別求偏導並令其等於\(0\)便可得\(L(\omega,b,a)\)的極小值
\[ \begin{align} & \nabla_\omega{L}(\omega,b,\alpha) = \omega - \sum_{i=1}^m\alpha_iy_ix_i = 0 \\ & \nabla_bL(\omega,b,\alpha) = -\sum_{i=1}^m\alpha_iy_i =0 \end{align} \]
得
\[ \begin{align} & \omega = \sum_{i=1}^m \alpha_iy_ix_i \\ & \sum_{i=1}^m \alpha_iy_i = 0 \end{align} \]
從\(\omega\)和\(b\)求偏導等於\(0\)的結果能夠看出\(\omega\)和\(\alpha\)的關係,只要後面能接着求出優化函數極大化對應的\(\alpha\),便可以求出\(\omega\),因爲上述上式已經沒有了\(b\),所以最後的\(b\)可能有多個。
將上述式子便可代入拉格朗日函數(注:因爲推導過程十分複雜,對接下來的講解無心,此處不給出推導過程,有興趣的同窗能夠自行嘗試,其中會用到範數的定義即\({||\omega||}^2=\omega\omega\)以及乘法運算法則\((a+b+c+\ldots)(a+b+c+\ldots)=aa+ab+ac+ba+bb+bc+\ldots\)以及一些矩陣的運算),即得
\[ \begin{align} \underbrace{\min}_{\omega,b}L(\omega,b,\alpha) & = {\frac{1}{2}}\sum_{i=1}^m\sum_{j=1}^m\alpha_i\alpha_jy_iy_j(x_ix_j) - \sum_{i=1}^m\alpha_iy_i((\sum_{i=1}^m\alpha_jy_jx_j)x_i+b)+\sum_{i=1}^m\alpha_i \\ & = - {\frac{1}{2}}\sum_{i=1}^m\sum_{j=1}^m\alpha_i\alpha_jy_iy_j(x_ix_j)+\sum_{i=1}^m\alpha_i \end{align} \]
從上式能夠看出經過對\(\omega\)和\(b\)極小化之後,優化函數只剩下\(\alpha\)作參數,只要可以極大化\(\underbrace{\min}_{\omega,b}L(\omega,b,\alpha)\)便可求出相應的\(\alpha\),進而求出\(\omega\)和\(b\)。
對\(\underbrace{\min}_{\omega,b}L(\omega,b,\alpha)\)求極大化的數學表達式爲
\[ \begin{align} & \underbrace{\max}_{\alpha} - {\frac{1}{2}} \sum_{i=1}^m\sum_{j=1}^m\alpha_i\alpha_jy_iy_j(x_ix_j)+\sum_{i=1}^m\alpha_i \\ & s.t. \sum_{i=1}^m \alpha_iy_i =0 \\ & \quad \alpha_i\geq0, \quad i=1,2,\ldots,m \end{align} \]
經過去掉負號,便可轉化爲等價的極小問題以下
\[ \begin{align} & \underbrace{\min}_{\alpha} {\frac{1}{2}} \sum_{i=1}^m\sum_{j=1}^m\alpha_i\alpha_jy_iy_j(x_ix_j) - \sum_{i=1}^m\alpha_i \\ & s.t. \sum_{i=1}^m \alpha_iy_i =0 \\ & \quad \alpha_i\geq0, \quad i=1,2,\ldots,m \end{align} \]
通常經過SMO算法(注:詳見《序列最小最優化算法》)求出上式極小化對應的\(\alpha\),假設經過SMO算法獲得了該\(\alpha\)值記做\(\alpha^*\),便可根據\(\omega=\sum_{i=1}^m\alpha_iy_ix_i\)求得原始最優化問題的解\(\omega^*\)爲
\[ \omega^* = \sum_{i=1}^m {\alpha_i}^* y_ix_i \]
因爲對\(b\)求偏導得\(\sum_{i=1}^m \alpha_iy_i = 0\),所以有多少個支持向量則有多少個\(b^*\),而且這些\(b^*\)均可以做爲最終的結果,可是對於嚴格的線性可分支持向量機,\(b^*\)的值是惟一的,即這裏全部的\(b^*\)都是同樣的。
根據KKT條件中的對偶互補條件\({\alpha_j}^*(y_j(\omega^*x_j+b)-1)=0\),若是\({\alpha_j}^*>0\),則有\(y_j(\omega^*x_j+b^*)-1=0\)即點都在支持向量機上,不然若是\({\alpha_j}^*=0\),則有\(y_j(\omega^*x_j+b^*)-1\geq0\)即已被正確分類。因爲對於任意支持向量\((x_j,y_j)\)都有\(y_j(\omega^*x_j+b^*)-1=0\)即\(y_j(\omega^*x_j+b^*)y_j-y_i=0\),代入\(\omega^*\)便可得\(b^*\)爲
\[ b^* = y_j - \sum_{i=1}^m{\alpha_i}^*y_i(x_ix_j) \]
有\(m\)個樣本的線性可分訓練集\(T=\{(x_1,y_1),(x_2,y_2),\cdots,(x_m,y_m)\}\),其中\(x_i\)爲\(n\)維特徵向量,\(y_i\)爲二元輸出即值爲\(1\)或者\(-1\)。
分離超平面的參數\(w^*\)和\(b^*\)以及分類決策函數
由KKT互補條件可得對於\(\alpha^*>0\)樣本點\((x_j,y_j)\)有\(y_j(w^*x_j+b)-1=0\),而且間隔邊界\(H_1\)和\(H_2\)分別爲\(w^*x_j+b^*=1\)和\(w^*x_j+b^*=-1\),即支持向量必定在間隔邊界上。
支持向量機是基於感知機模型演化而來的,解決了感知機模型可能會獲得多個分類直線的問題,因爲使用了硬間隔最大化支持向量機的目標函數只和支持向量的位置有關,大大下降了計算量。
線性可分支持向量機是支持向量機最原始的形式,因爲使用了硬間隔最大化,所以沒法作到對異常值和非線性可分數據的處理,此處很少贅述,讓咱們看他的升級版——線性支持向量機。