Python Scikit-learn ---- SVM算法

支持向量機(SVM)是一組用於分類、迴歸和異常值檢測的有監督學習方法。

SVMs: LinearSVC, Linear SVR, SVC, Nu-SVC, SVR, Nu-SVR, OneClassSVM

 

支持向量機的優點是:
高維空間中的有效性。
在維數大於樣本數的情況下仍然有效。
在決策函數中使用訓練點的子集(稱爲支持向量),因此它也是內存有效的。
多功能:可以爲決策函數指定不同的內核函數。提供了常見核函數,但也可以自定義核函數。

支持向量機的缺點包括:
如果特徵數遠大於樣本數,通過選擇核函數和正則項避免過擬合是至關重要的。
支持向量機不直接提供概率估計,這些計算使用計算量大的的5折-交叉驗證。

 

最簡單分類超平面,1維:x=0,2維:x1+x2=0

當θTXi與 θTX值大於1時,也就是距離分類邊界大於1,此時無損,損失爲1 - ||θTXi - θTX||,下限爲0無上限。

 

 

import time
import numpy as np
import scipy.io as scio
import pandas as pd
from numpy import newaxis
#from pylab import * #包含了NumPy和pyplot常用的函數
from sklearn.cluster import KMeans
from sklearn import svm
from sklearn.svm import SVC  
from sklearn.svm import LinearSVC
from sklearn.svm import NuSVC
from sklearn.svm import SVR
from sklearn.svm import LinearSVR
from sklearn.datasets import make_regression
from sklearn.datasets import make_classification

 

 

 

對於多分類問題,SVC採用的是one-vs-one投票機制,需要兩兩類別建立分類器,訓練時間可能比較長。

SVC參數解釋:

C: 誤差項的懲罰係數C ,用來平衡分類間隔margin (誤差距離平方和?cost1和cost2,大於1(-1)時損失爲0)和錯分樣本的 (default=1.0);  

kernel:  'linear', 'poly', 'rbf', 'sigmoid', 'precomputed' ,(default='rbf');

degree : 多項式核'poly'的階數,(default=3);

gamma : 'rbf', 'poly' 及'sigmoid'的核係數,默認時爲(1/特徵個數),(default='auto');

coef0 : 核函數中的獨立項,僅在'poly' 和 'sigmoid'中顯著,(default=0.0);

probability : 是否使用概率估計,必須在'fit'前使用,並會減慢速度,(default=False);

shrinking :是否使用shrinking heuristic,(default=True);

tol:停止準則的門檻,(default=1e-3);

cache_size :  核緩存(in MB);在大樣本的時候,緩存大小會影響訓練速度,因此如果機器內存大,推薦用500MB or 1000MB。默認是200MB;

class_weight :類別權重,設置每個類別權重係數。對於每一個類別i設置懲罰係數C = class_weight[i]*C。如果不給出 (default=1);樣本數量不均衡時設置爲'balanced',權重自動調整爲 n_samples / (n_classes * np.bincount(y)), 此時某種類型樣本量越多,則權重越低;樣本量越少,則權重越高;np.bincount(y)每個類的樣本數;
verbose: 如果啓用,可能無法在多線程環境正常工作,(default=False);

max_iter: 最大迭代次數,'-1'時無限制, (default=-1);

decision_function_shape : 返回一對多 'ovr'決策函數(n_samples, n_classes),或原始一對一'ovo'決策函數(n_samples, n_classes * (n_classes - 1) / 2),(default='ovr');

random_state: 設置隨機數種子,如果設置了隨機數種子,則每次實驗都能得到一樣的結果,即每次運行取隨機數都能得到相同的數 (default=None);

輸出:

support_ : 支持向量指數;

support_vectors_ : 支持向量;

n_support_ : 每一類的支持向量個數;

dual_coef_ : 決策函數中支持向量的係數,對於多分類爲1-vs-1分類器的係數;

coef_ : 返回每個特徵的權重,僅線性核時有效;

intercept_ : 決策函數中的常數,截距;

 

例子

 

#import blabla ,在開始那些先導入
#SVC,基於libsvm,不適用於數量大於10K的數據(時間複雜度高)
#數據準備
data = scio.loadmat("train and test top321.mat") #導入數據
test = data['test'] #待分類數據
testclass = data['testclass']
testclass = np.ravel(testclass)
train = data['train']
trainclass = data['trainclass']
trainclass = np.ravel(trainclass)
#建模分類
clf = SVC(kernel='linear')
clf.fit(train, trainclass)
weight = clf.coef_
print(clf.predict(test))
Pretest = clf.predict(test) #輸出分類標籤
a = Pretest ^ testclass
acc = (a.size-a.sum())/a.size
print("Accuracy:",acc)
print("支持向量指數:",clf.support_)
print("支持向量",clf.support_vectors_)
print("每一類的支持向量個數",clf.n_support_)
print("支持向量的係數:",clf.dual_coef_)
print("截距:",clf.intercept_)

 

 

Nu-SVC的實現基於libsvm,通過一個參數控制支持向量,

 

 

Nu-SVC參數解釋:

nu : 取代了參數c,錯分樣本所佔比例的上界,支持向量所佔比列的下界,範圍是(0, 1],(default=0.5);
kernel : 'linear', 'poly', 'rbf', 'sigmoid', 'precomputed' ,(default='rbf');

degree : 多項式核'poly'的階數,(default=3);

gamma : 'rbf', 'poly' 及'sigmoid'的核係數,默認時爲(1/特徵個數),(default='auto');

coef0 : 核函數中的獨立項,僅在'poly' 和 'sigmoid'中顯著,(default=0.0);

probability : 是否使用概率估計,必須在'fit'前使用,並會減慢速度,(default=False);

shrinking :是否使用shrinking heuristic,(default=True);

tol:停止準則的門檻,(default=1e-3);

 

cache_size :  核緩存(in MB);在大樣本的時候,緩存大小會影響訓練速度,因此如果機器內存大,推薦用500MB or 1000MB。默認是200MB;

class_weight :類別權重,設置每個類別權重係數。對於每一個類別i設置懲罰係數C = class_weight[i]*C。如果不給出 (default=1);樣本數量不均衡時設置爲'balanced',權重自動調整爲 n_samples / (n_classes * np.bincount(y)), 此時某種類型樣本量越多,則權重越低;樣本量越少,則權重越高;np.bincount(y)每個類的樣本數;
verbose: 如果啓用,可能無法在多線程環境正常工作,(default=False);

max_iter: 最大迭代次數,'-1'時無限制, (default=-1);

decision_function_shape : 返回一對多 'ovr'決策函數(n_samples, n_classes),或原始一對一'ovo'決策函數(n_samples, n_classes * (n_classes - 1) / 2),(default='ovr');

random_state: 設置隨機數種子,如果設置了隨機數種子,則每次實驗都能得到一樣的結果,即每次運行取隨機數都能得到相同的數 (default=None);

輸出:

support_ : 支持向量指數;

support_vectors_ : 支持向量;

n_support_ : 每一類的支持向量個數;

dual_coef_ : 決策函數中支持向量的係數,對於多分類爲1-vs-1分類器的係數;

coef_ : 返回每個特徵的權重,僅線性核時有效;

intercept_ : 決策函數中的常數,截距;

例子
#import blabla ,在開始那些先導入
#NuSVC,基於libsvm,通過一個參數控制支持向量
#數據準備
data = scio.loadmat("train and test top321.mat") #導入數據
test = data['test'] #待分類數據
testclass = data['testclass']
testclass = np.ravel(testclass)
train = data['train']
trainclass = data['trainclass']
trainclass = np.ravel(trainclass)
#建模分類
clf = NuSVC(kernel='linear')
clf.fit(train, trainclass)
weight = clf.coef_
print(clf.predict(test))
Pretest = clf.predict(test) #輸出分類標籤
a = Pretest ^ testclass
acc = (a.size-a.sum())/a.size
print("Accuracy:",acc)
print("支持向量指數:",clf.support_)
print("支持向量",clf.support_vectors_)
print("每一類的支持向量個數",clf.n_support_)
print("支持向量的係數:",clf.dual_coef_)
print("截距:",clf.intercept_)
 

LinearSVC(Linear Support Vector Classification):線性支持向量分類,類似於SVC,但是其使用的核函數是”linear“,其實現基於LIBLINEAR,所以它具有更大的靈活性在選擇penalty和loss時,而且可以適應更大的數據集,他支持密集和稀疏的輸入是通過一對一的方式解決的。

LinearSVC 參數解釋  
C: 誤差項的懲罰係數C,用來平衡分類間隔margin和錯分樣本的 (default=1.0);  
loss: 指定損失函數 ,'hinge' 或squared_hinge' (default='squared_hinge');

penalty:  正則項L1或L2 (default='l2');

tol :  svm結束標準的精度 (default = 1e - 3);  
multi_class:如果y輸出類別包含多類,用來確定多類策略, ovr表示一對多,“crammer_singer”優化所有類別的一個共同的目標  ;如果選擇“crammer_singer”,損失、懲罰和優化將會被被忽略 (default='ovr');
fit_intercept :  截距設置 (default=True);
intercept_scaling :  (default=1);
class_weight :類別權重,設置每個類別權重係數。對於每一個類別i設置懲罰係數C = class_weight[i]*C。如果不給出 (default=1);設置爲'balanced'時權重自動調整爲 n_samples / (n_classes * np.bincount(y)), 樣本數量不均衡時使用,此時某種類型樣本量越多,則權重越低;樣本量越少,則權重越高;np.bincount(y)每個類的樣本數;

verbose: 如果啓用,可能無法在多線程環境正常工作,(default=0);

 

random_state: 設置隨機數種子,如果設置了隨機數種子,則每次實驗都能得到一樣的結果,即每次運行取隨機數都能得到相同的數 (default=None);

max_iter: 最大迭代次數 (default=1000);

輸出:

 

coef_ : 返回每個特徵的權重,僅線性核時有效;class = 2時爲m*1,class>2時爲n_class*m

intercept_ : 決策函數中的常數,截距;

 

 

 

例子

 

 

#LinearSVC 適用於大數據,線性核,等同於Liblinear,比libsvm快得多,dual=False時可以調節penalty和loss
#數據準備
data = scio.loadmat("train and test top321.mat") #導入數據
test = data['test'] #待聚類數據
testclass = data['testclass']
testclass = np.ravel(testclass)
train = data['train']
trainclass = data['trainclass']
trainclass = np.ravel(trainclass)
#建模分類
clf = LinearSVC()
clf.fit(train, trainclass)
weight = clf.coef_
#print(clf.intercept_)
print(clf.predict(test))
Pretest = clf.predict(test)
a = Pretest ^ testclass
acc = (a.size-a.sum())/a.size
print("Accuracy:",acc)

 

 

SVR(epsilon-SVR),基於libsvm實現,可以靈活調節懲罰參數C與epsilon

 

SVR 參數解釋  

 

C: 誤差項的懲罰係數C, (default=1.0);  

epsilon: 距離誤差,指定了當沒有正則項時的epsilon-tube,(default=0.1);

 

kernel:  'linear', 'poly', 'rbf', 'sigmoid', 'precomputed' ,(default='rbf');

degree : 多項式核'poly'的階數,(default=3);

gamma : 'rbf', 'poly' 及'sigmoid'的核係數,默認時爲(1/特徵個數),(default='auto');

coef0 : 核函數中的獨立項,僅在'poly' 和 'sigmoid'中顯著,(default=0.0);

shrinking :是否使用shrinking heuristic,(default=True);

tol:停止準則的門檻,(default=1e-3);

cache_size :  核緩存(in MB);在大樣本的時候,緩存大小會影響訓練速度,因此如果機器內存大,推薦用500MB or 1000MB。默認是200MB;

verbose: 如果啓用,可能無法在多線程環境正常工作,(default=False);

max_iter: 最大迭代次數,'-1'時無限制, (default=-1);

輸出:

support_ : 支持向量指數;

support_vectors_ : 支持向量;

dual_coef_ : 決策函數中支持向量的係數,對於多分類爲1-vs-1分類器的係數;

coef_ : 返回每個特徵的權重,僅線性核時有效;

intercept_ : 決策函數中的常數,截距;

sample_weight : 每個樣本的權重 (???使用時候顯示無此屬性 )

例子:

 

X, y = make_regression(n_features=4, random_state=0)
regr = SVR(kernel='linear')
regr.fit(X, y) #x爲數據,y爲變量,a1x11+a2x12...=y1
print("特徵權重:",regr.coef_)
#print("樣本權重:",regr.sample_weight)
print("截距:",regr.intercept_)
print(regr.predict([[0,0,0,0]])) #預測

 

 

 

LinearSVR,是用liblinear實現,可靈活設置懲罰參數C和損失函數(loss),適用於大數據,用的sqaured L2正則項

 

LinearSVR 參數解釋  

 

C: 誤差項的懲罰係數C,用的squared L2正則項,隨着C增大正則項效果減弱,(default=1.0);  
loss: 指定損失函數 ,'epsilon_insensitive' (即L1)或squared_epsilon_insensitive' (即L2),(default='epsilon_insensitive');

 

epsilon: 距離誤差,與目標變量y的scale有關,如果不確定設置``epsilon=0``,(default=0.1);

dual: 控制使用對偶形式來優化算法或原始優化問題(default=True) ;當n_samples > n_features 時計算量大推薦dual=false;  
tol :  svm結束標準的精度 (default = 1e - 3);  
fit_intercept : 是否計算該模型的截距。如果設置爲False則截距不會被用於計算(當時距被centered時可以設爲False), (default=True);

intercept_scaling : 當fit_intercept 爲True時,合成的特徵被加入,x變爲 [x, intercept_scaling], 截距變爲intercept_scaling * 合成的特徵權重,合成的特徵權重受到L1/L2正則化影響,增加intercept_scaling值以減少正則化對合成的特徵(即截距)的影響,(default=1);

 

verbose: 如果啓用,可能無法在多線程環境正常工作,(default=0);

random_state: 設置隨機數種子,如果設置了隨機數種子,則每次實驗都能得到一樣的結果,即每次運行取隨機數都能得到相同的數(default=None);

max_iter: 最大迭代次數 (default=1000);

輸出:

 

coef_ : 返回每個特徵的權重,僅線性核時有效;

intercept_ : 決策函數中的常數,截距;

 

例子:

 

#LinearSVR,是用liblinear實現,可靈活設置懲罰參數C和損失函數,適用於大數據
X, y = make_regression(n_features=4, random_state=0)
regr = LinearSVR(random_state=0)
regr.fit(X, y) #x爲數據,y爲變量,a1x11+a2x12...=y1
print(regr.coef_) #擬合出的係數
print(regr.intercept_) #截距
print(regr.predict([[0,0,0,0]])) #預測

 

 

OneClassSvm,用於異常行爲檢測,基於libsvm的無監督方法;相似的有基於高斯分佈的異常點檢測算法

 

 

常用SVM算法是通過訓練兩類樣本從而建立模型,而一類SVM則是識別與某一類樣本不同的點,這些不同的點可能屬於n個其它類別。

類似於svdd,構造一個高維超球,把數據包起來,儘可能緊,又儘可能包括更多的數據。

 

#OneClassSvm,基於libvm的無監督方法用於檢測異常數據]
#nu參數調節很重要
data = scio.loadmat("train and test top321.mat") #導入數據
test = data['test'] 
testclass = data['testclass']
testclass = np.ravel(testclass)
train = data['train']
trainclass = data['trainclass']
trainclass = np.ravel(trainclass)
train = train[:,0:2]
test = test[:,0:2]
#建模檢測
clf = OneClassSVM(kernel='rbf')
print(clf.fit(train))
#print(clf.decision_function(train))
print(clf.predict(test))
Pretest = clf.predict(test)
a = Pretest ^ testclass
acc = (a.size-a.sum())/a.size
print("Accuracy:",acc)
normal = test[Pretest==1]
abnormal = test[Pretest==-1]
plt.plot(normal[:,0],normal[:,1],'bx')
plt.plot(abnormal[:,0],abnormal[:,1],'ro')

 

 

 

 

 

 

 

 

 

 

SVM解決多分類問題的方法 

 

SVM算法最初是爲二值分類問題設計的,當處理多類問題時,就需要構造合適的多類分類器。目前,構造SVM多類分類器的方法主要有兩類:一類是直接法,直接在目標函數上進行修改,將多個分類面的參數求解合併到一個最優化問題中,通過求解該最優化問題“一次性”實現多類分類。這種方法看似簡單,但其計算複雜度比較高,實現起來比較困難,只適合用於小型問題中;另一類是間接法,主要是通過組合多個二分類器來實現多分類器的構造,常見的方法有one-against-one和one-against-all兩種。 
a.一對多法(one-versus-rest,簡稱1-v-r SVMs)。訓練時依次把某個類別的樣本歸爲一類,其他剩餘的樣本歸爲另一類,這樣k個類別的樣本就構造出了k個SVM。分類時將未知樣本分類爲具有最大分類函數值的那類。 
b.一對一法(one-versus-one,簡稱1-v-1 SVMs)。其做法是在任意兩類樣本之間設計一個SVM,因此k個類別的樣本就需要設計k(k-1)/2個SVM。當對一個未知樣本進行分類時,最後得票最多的類別即爲該未知樣本的類別。Libsvm中的多類分類就是根據這個方法實現的。 
c.層次支持向量機(H-SVMs)。層次分類法首先將所有類別分成兩個子類,再將子類進一步劃分成兩個次級子類,如此循環,直到得到一個單獨的類別爲止。 
對c和d兩種方法的詳細說明可以參考論文《支持向量機在多類分類問題中的推廣》(計算機工程與應用。2004) 

 

d.其他多類分類方法。除了以上幾種方法外,還有有向無環圖SVM(Directed Acyclic Graph SVMs,簡稱DAG-SVMs)和對類別進行二進制編碼的糾錯編碼SVMs。 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章