1. 程式人生 > >SVM的核函式之線性和高斯的選擇

SVM的核函式之線性和高斯的選擇

Table of Contents

關於SVM中線性核函式和高斯核函式的選擇

SVM中常用核函式一般是線性核函式和高斯核函式。以sklearn中的SVC,提供的’linear’和’rbf’做說明。面向[n,m]原始資料集,一般的選取準則:

  1. 相對於n,m很大。比如m≥n, m=10000, n=10~1000,即(m/n)>10。
    考慮’linear’
  2. m很小,n一般大小。比如m=1-1000, n=10~10000,即(m/n)在[0.0001,100].
    考慮’rbf’
  3. m很小,n很大。比如n=1-1000,m=50000+,即(m/n)在[~,0.02].
    增加m的量,考慮’linear’

補充:logistic約等同於’linear’的選擇

#!/usr/bin/python
# encoding: utf-8


"""
@author : jack_lu
@contact : [email protected]
@File : SVM
@time : 2018/12/12 12:12
"""
# 練習所用資料集
from sklearn.datasets import fetch_lfw_people,olivetti_faces

# 特徵提取方法
from sklearn.decomposition import PCA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
# 特徵轉換方法
from sklearn.preprocessing import StandardScaler

# sklearn模型方法
from sklearn.model_selection import
train_test_split # metric方法 from sklearn.metrics import accuracy_score # 機器學習模型 from sklearn.linear_model import LogisticRegression from sklearn.pipeline import Pipeline from sklearn.svm import SVC

1.基本資料準備

print('#'*50 + '  1.基本資料準備  ' + '#'*50)
lfw_people2 = fetch_lfw_people(min_faces_per_person=70, resize=0.4)  # 需要通過翻牆下載,C:\Users\Administrator\scikit_learn_data\lfw_home\joblib\sklearn\datasets\lfw\_fetch_lfw_people
##################################################  1.基本資料準備  ##################################################
n_samples, h, w = lfw_people2.images.shape
X = lfw_people2.data
y = lfw_people2.target
n_features = X.shape[1]

target_names = lfw_people2.target_names
n_class = target_names.shape[0]

print('#'*20,'資料集基本情況','#'*20)
print('**樣本數量**:%d' %(X.shape[0]))
print('**特徵維度**:%d' %(X.shape[1]))
print('**目標類別數**:%d' %(n_class))
print('#'*20,'資料集基本情況','#'*20)

#################### 資料集基本情況 ####################
**樣本數量**:1288
**特徵維度**:1850
**目標類別數**:7
#################### 資料集基本情況 ####################
X_train,X_test,y_train,y_test = train_test_split(X, y, test_size=0.25,random_state=1)

print('#'*20,'訓練資料集基本情況','#'*20)
print('**訓練樣本數量**:%d' %(X_train.shape[0]))
print('**訓練特徵維度**:%d' %(X_train.shape[1]))
print('**目標類別數**:%d' %(n_class))
print('#'*20,'訓練資料集基本情況','#'*20)

#################### 訓練資料集基本情況 ####################
**訓練樣本數量**:966
**訓練特徵維度**:1850
**目標類別數**:7
#################### 訓練資料集基本情況 ####################

2.各情況對比

print('#'*50 + '  2.建模與比較  ' + '#'*50)

##################################################  2.建模與比較  ##################################################

1. SVM(kernel=‘linear’):直接採用資料集[966,1850]

svm_origin = SVC(kernel='linear', C=1000, decision_function_shape='ovo')  # 根據官方說明,對於多分類任務宜採用'ovo'即onevsone策略
svm_origin.fit(X_train, y_train)
y_pred = svm_origin.predict(X_test)
print('**情況1-linear的準確率**: %s' %(accuracy_score(y_pred=y_pred, y_true=y_test)))
**情況1-linear的準確率**: 0.832298136646

2. SVM(kernel=‘rbf’):直接採用資料集[966,1850]

svm_rbf = SVC(kernel='rbf', C=1000, decision_function_shape='ovo')  # 根據官方說明,對於多分類任務宜採用'ovo'即onevsone策略
svm_rbf.fit(X_train, y_train)
y_pred = svm_rbf.predict(X_test)
print('**情況2-rbf的準確率**: %s' %(accuracy_score(y_pred=y_pred, y_true=y_test)))
**情況2-rbf的準確率**: 0.44099378882

3. LR:直接採用資料集[966,1850]

lr_origin = LogisticRegression()  # 對於多分類任務,multi_class可選擇'ovr'或者'auto'自動選擇,這裡按照預設'auto'
lr_origin.fit(X_train, y_train)
y_pred = lr_origin.predict(X_test)
print('**情況3-LR的準確率**: %s' %(accuracy_score(y_pred=y_pred, y_true=y_test)))
**情況3-LR的準確率**: 0.826086956522

4. 降維之後

print('#'*20,'維度由1850減少到150之後','#'*20)

#################### 維度由1850減少到150之後 ####################
def namestr(obj, namespace):
    return [name for name in namespace if namespace[name] is obj]
print(namestr(lr_origin,globals()),'\n',
namestr(lr_origin,globals())[0])

['lr_origin', 'model'] 
 lr_origin
def small_feature_model(model,X_train=X_train,y_train=y_train,X_test=X_test, y_test=y_test):
    pca = PCA(n_components=150,random_state=0,whiten=True)
    pipeline = Pipeline([('scale',StandardScaler()),('pca',pca)])
    processing = pipeline.fit(X_train)
    X_train = processing.transform(X_train)
    X_test = processing.transform(X_test)
    model.fit(X_train, y_train)
    y_pred = model.predict(X_test)
#     print(namestr(model,globals()))
    print('**small-%s的準確率**: %.3f' %(namestr(model, globals())[0],accuracy_score(y_pred=y_pred, y_true=y_test)))
for model in [svm_origin, svm_rbf, lr_origin]:
    small_feature_model(model)
**small-svm_origin的準確率**: 0.789
**small-svm_rbf的準確率**: 0.811
**small-lr_origin的準確率**: 0.835
print('#'*50 + '  完成  ' + '#'*50)

##################################################  完成  ##################################################

3.小結

從結果看到:

  1. 將維度減少到150之後,選擇kernel='rbf’的效果>‘linear’;
  2. 在沒有調參情況下,LR的效果還不錯,初期建模值得先嚐試。

當然,上面是指定了特定的引數,更主要的目的是對比SVM兩種核方法在n和m的比例當中的效果。在具體問題當中,在計算力有限條件下,建議還是通過網格搜尋的方法對比選出最優的kernel。