Python中使用支援向量機(SVM)實踐
阿新 • • 發佈:2019-01-03
在機器學習領域,支援向量機SVM(Support Vector Machine)是一個有監督的學習模型,通常用來進行模式識別、分類(異常值檢測)以及迴歸分析。
其具有以下特徵:
(1)SVM可以表示為凸優化問題,因此可以利用已知的有效演算法發現目標函式的全域性最小值。而其他分類方法都採用一種基於貪心學習的策略來搜尋假設空間,這種方法一般只能獲得區域性最優解。
(2) SVM通過最大化決策邊界的邊緣來實現控制模型的能力。儘管如此,使用者必須提供其他引數,如使用核函式型別和引入鬆弛變數等。
(3)SVM一般只能用在二類問題,對於多類問題效果不好。 1程式碼及詳細解釋(基於sklearn包):from sklearn import svm
import numpy as np import matplotlib.pyplot as plt
#準備訓練樣本 x=[[1,8],[3,20],[1,15],[3,35],[5,35],[4,40],[7,80],[6,49]] y=[1,1,-1,-1,1,-1,-1,1]
##開始訓練 clf=svm.SVC() ##預設引數:kernel='rbf' clf.fit(x,y)
##根據訓練出的模型繪製樣本點 for i in x: res=clf.predict(np.array(i).reshape(1, -1))if res > 0: plt.scatter(i[0],i[1],c='r',marker='*') else : plt.scatter(i[0],i[1],c='g',marker='*') ##生成隨機實驗資料(15行2列) rdm_arr=np.random.randint(1, 15, size=(15,2)) ##回執實驗資料點 for i in rdm_arr: res=clf.predict(np.array(i).reshape(1, -1)) if res > 0: plt.scatter(i[0],i[1],c='r',marker='.') else : plt.scatter(i[0],i[1],c='g',marker='.') ##顯示繪圖結果 plt.show()
從圖上可以看出,資料明顯被藍色分割線分成了兩類。但是紅色箭頭標示的點例外,所以這也起到了檢測異常值的作用。
上面的程式碼中提到了kernel='rbf',這個引數是SVM的核心:核函式
重新整理後的程式碼如下:
from sklearn import svm import numpy as np import matplotlib.pyplot as plt ##設定子圖數量 fig, axes = plt.subplots(nrows=2, ncols=2,figsize=(7,7)) ax0, ax1, ax2, ax3 = axes.flatten() #準備訓練樣本 x=[[1,8],[3,20],[1,15],[3,35],[5,35],[4,40],[7,80],[6,49]] y=[1,1,-1,-1,1,-1,-1,1] ''' 說明1: 核函式(這裡簡單介紹了sklearn中svm的四個核函式,還有precomputed及自定義的) LinearSVC:主要用於線性可分的情形。引數少,速度快,對於一般資料,分類效果已經很理想 RBF:主要用於線性不可分的情形。引數多,分類結果非常依賴於引數 polynomial:多項式函式,degree 表示多項式的程度-----支援非線性分類 Sigmoid:在生物學中常見的S型的函式,也稱為S型生長曲線 說明2:根據設定的引數不同,得出的分類結果及顯示結果也會不同 ''' ##設定子圖的標題 titles = ['LinearSVC (linear kernel)', 'SVC with polynomial (degree 3) kernel', 'SVC with RBF kernel', ##這個是預設的 'SVC with Sigmoid kernel'] ##生成隨機試驗資料(15行2列) rdm_arr=np.random.randint(1, 15, size=(15,2)) def drawPoint(ax,clf,tn): ##繪製樣本點 for i in x: ax.set_title(titles[tn]) res=clf.predict(np.array(i).reshape(1, -1)) if res > 0: ax.scatter(i[0],i[1],c='r',marker='*') else : ax.scatter(i[0],i[1],c='g',marker='*') ##繪製實驗點 for i in rdm_arr: res=clf.predict(np.array(i).reshape(1, -1)) if res > 0: ax.scatter(i[0],i[1],c='r',marker='.') else : ax.scatter(i[0],i[1],c='g',marker='.') if __name__=="__main__": ##選擇核函式 for n in range(0,4): if n==0: clf = svm.SVC(kernel='linear').fit(x, y) drawPoint(ax0,clf,0) elif n==1: clf = svm.SVC(kernel='poly', degree=3).fit(x, y) drawPoint(ax1,clf,1) elif n==2: clf= svm.SVC(kernel='rbf').fit(x, y) drawPoint(ax2,clf,2) else : clf= svm.SVC(kernel='sigmoid').fit(x, y) drawPoint(ax3,clf,3) plt.show()
由於樣本資料的關係,四個核函式得出的結果一致。在實際操作中,應該選擇效果最好的核函式分析。