機器學習筆記8 支援向量機(3 3)

2021-09-05 10:01:21 字數 4100 閱讀 3787

scikit-learn中的svm函式

機器學習庫scikit-learn中也整合了svm的函式,可以方便的進行呼叫,可用來分類、回歸和異常點檢測。

支援向量機的優點有:

i)在高維空間效果很好

ii)當維度數大於樣本點數時,效果仍然不錯

iii)決策函式只取決於資料集中的支援向量,能夠減輕記憶體壓力

iv)決策函式中可以選不同的核函式從而實現多種功能。可以使用現有的核函式,也可以自定義核函式。

支援向量機的缺點有:

i)如果特徵數量比樣本數量多很多,為了避免過擬合,需要謹慎選擇核函式和正則化項

ii)svm不支援概率估計。如果需要概率估計的話,需要通過5折交叉驗證的方法。

(1)分類

svc、nusvc和linearsvc都可以用來進行多分類。svc和nusvc是類似的方法,只是數學形式不一樣,引數設定不一樣而已。linearsvc是專門用來線性分類的,所以沒有kernel這個引數。對於這三個分類器,如果想檢視支援向量,可檢視屬性support_vectors_。

from sklearn import svm

x = [[0, 0], [1, 1]]

y = [0, 1]

clf = svm.svc(gamma='scale')

clf.fit(x, y)

clf.predict([[2., 2.]])

clf.support_vectors_

對於多分類,svc和nusvc預設實行的是「one-against-one」的方法。假設有n個類,就需要有n*(n-1)/2個分類器。其中每乙個分類器只會訓練兩個類的資料。最後用decision_function_shape引數來彙總結果。還有另一種多分類方法:「one-vs-the-rest」方法,這種方法只需要n個分類器。每個分類器會訓練乙個類+其餘類的資料。如果只有兩個類,則只需要乙個分類器。linearsvc使用的就是這個方法。
>>> x = [[0], [1], [2], [3]]

>>> y = [0, 1, 2, 3]

>>> clf = svm.svc(gamma='scale', decision_function_shape='ovo')#decision_function_shape採用的是「1vs1」模式

>>> clf.fit(x, y)

svc(c=1.0, cache_size=200, class_weight=none, coef0=0.0,

decision_function_shape='ovo', degree=3, gamma='scale', kernel='rbf',

max_iter=-1, probability=false, random_state=none, shrinking=true,

tol=0.001, verbose=false) #kernel是'rbf',因此這個是非線性分類器

>>> dec = clf.decision_function([[1]])

>>> dec.shape[1] # 有四個類,因此需要4*(4-1)/2=6個分類器

6>>> clf.decision_function_shape = "ovr" #將decision_function_shape改為「1vsr」模式

>>> dec = clf.decision_function([[1]])

>>> dec.shape[1] # 此時四個類就只需要四個分類器

4

(2)回歸

支援向量分類可以用來解決回歸問題,稱為支援向量回歸。與支援向量分類類似,支援向量回歸也只跟訓練資料的一小部分子集有關。不同的地方是分類的輸入y

yy是個整數,而回歸的輸入y

yy是個浮點數。支援向量回歸總共包括三個函式:svr,nusvr和linearsvr。

(3)複雜度

svm的時間複雜度和空間複雜度會隨著訓練資料的容量增加而迅速增加。svm的核心是將支援向量從訓練資料中分離,這是乙個二次規劃問題。它的求解利用了libsvm,複雜度在o(n

feat

ures

×nsa

mple

s2

)o(n_\times n_^2)

o(nfea

ture

s​×n

samp

les2

​)和o (n

feat

ures

×nsa

mple

s3

)o(n_\times n_^3)

o(nfea

ture

s​×n

samp

les3

​)之間。但如果是線性的svm,它的複雜度是o(n

feat

ures

×nsa

mple

s)

o(n_\times n_)

o(nfea

ture

s​×n

samp

les​

)。(4)tips

i)核函式的大小:對於svc、svr等,核函式的大小會極大地影響大型資料問題的執行時間。預設的cache_size是200mb,如果記憶體足夠,可以提公升到500mb或者1000mb

ii)懲罰引數c:c值的意義可以參看上一節的線性支援向量機。c預設為1。如果資料的雜訊很大,應該減小c值。當c值很大時,linearsvc和linearsvr會對c值變得不敏感(**結果也不會再改善)。而且較大的c值會增加訓練的時間。

iii)svm演算法不是尺度不變的。所以在用svm之前,強烈建議將輸入資料的每乙個特徵變換到[0,1]或[-1,1]之間,或將其標準化為均值為零方差為1。對於測試資料也需用到同樣的尺度變換。

iv)如果資料是不平衡的(比如很多的正例項點和極少的負例項點),建議設定class_weight=『balanced』,並嘗試設定不同的懲罰引數c值。

v)如果有經驗知道資料是線性可以擬合的,那麼使用linearsvc去分類 或者linearsvr去回歸,它們不需要我們去慢慢的調參去選擇各種核函式以及對應引數, 速度也快。如果我們對資料分布沒有什麼經驗,一般使用svc去分類或者svr去回歸,這就需要我們選擇核函式以及對核函式調參了。對於分類或回歸中,函式其它引數的設定,包括核函式引數degree、核函式引數gamma、核函式引數coef0、 這篇部落格有詳盡的解釋。

以下是利用svc實現的一小段**,資料集是sklearn中的內建資料集:

from sklearn.datasets import fetch_olivetti_faces

from sklearn.model_selection import train_test_split

from sklearn import preprocessing

from sklearn.svm import svc

faces=fetch_olivetti_faces()

x_train,x_test,y_train,y_test=train_test_split(faces['data'],faces['target'],test_size=0.25,random_state=17)

scaler=preprocessing.standardscaler()

x_train=scaler.fit_transform(x_train)

x_test=scaler.fit_transform(x_test)

svc_linear=svc(c=0.2,kernel='linear')

svc_linear.fit(x_train,y_train)

y_predict_train=svc_linear.predict(x_train)

y_predict_test=svc_linear.predict(x_test)

from sklearn import metrics

print(metrics.accuracy_score(y_train,y_predict_train))

print(metrics.accuracy_score(y_test,y_predict_test))

參考:

李航《統計學習方法》

機器學習筆記(二 支援向量機)

本次筆記基於mooc平台浙江大學的機器學習課程 對於乙個訓練樣本集,i 1 n,若存在 w,b 使得使得滿足下式,則是線性可分問題。要求這樣的乙個超平面 在二維平面中是一條直線 則要滿足以下公式 證明過程如下 首先要確認兩個事實,即 和 則可以根據線性可分問題的滿足式,用a來縮放 w,b 使得找到某...

機器學習筆記 六 支援向量機

對於給定的訓練集d yi 分類學習的初衷就是基於訓練集在樣本空間中找到乙個可以有效劃分樣本的超平面。可能存在很多可將樣本分開的超平面,選擇分類結果最魯棒 泛化能力最強的超平面便是支援向量機模型的重點。通過二維樣本點分布的圖示看,最直觀上,找到兩類樣本正中間的超平面是最佳的。如此,在樣本空間中,劃分超...

機器學習筆記三 支援向量機

給定訓練集d,在樣本空間上找到最魯棒的超平面,將不同類別的樣本分開。對於線性可分問題,超平面的線性方程為 優化目標 找到引數w和b在劃分正確的前提下使得間隔最大,即 上述問題等價於 此為支援向量機 svm 的基本型,將引數求解問題轉化為凸二次規劃問題,為了方便求解且易於推廣到非線性情況下的核函式,採...