SVM使用與參數優化

轉載本文請註明出處:amazingwu:http://blog.csdn.net/u013668852/article/details/75007342

python機器學習庫 scikit-learn

對Python語言有所瞭解的科研人員可能都知道SciPy——一個開源的基於Python的科學計算工具包。基於SciPy,目前開發者們針對不同的應用領域已經發展出了爲數衆多的分支版本,它們被統一稱爲Scikits,即SciPy工具包的意思。而在這些分支版本中,最有名,也是專門面向機器學習的一個就是Scikit-learn。

Scikit-learn的六大功能

Scikit-learn的基本功能主要被分爲六大部分:分類,迴歸,聚類,數據降維,模型選擇和數據預處理。

  • 分類是指識別給定對象的所屬類別,屬於監督學習的範疇,最常見的應用場景包括垃圾郵件檢測和圖像識別等。目前Scikit-learn已經實現的算法包括:支持向量機(SVM),最近鄰,邏輯迴歸,隨機森林,決策樹以及多層感知器(MLP)神經網絡等等。
    需要指出的是,由於Scikit-learn本身不支持深度學習,也不支持GPU加速,因此這裏對於MLP的實現並不適合於處理大規模問題。有相關需求的讀者可以查看同樣對Python有良好支持的Keras和Theano等框架。

  • 迴歸是指預測與給定對象相關聯的連續值屬性,最常見的應用場景包括預測藥物反應和預測股票價格等。目前Scikit-learn已經實現的算法包括:支持向量迴歸(SVR),脊迴歸,Lasso迴歸,彈性網絡(Elastic Net),最小角迴歸(LARS ),貝葉斯迴歸,以及各種不同的魯棒迴歸算法等。可以看到,這裏實現的迴歸算法幾乎涵蓋了所有開發者的需求範圍,而且更重要的是,Scikit-learn還針對每種算法都提供了簡單明瞭的用例參考。

  • 聚類是指自動識別具有相似屬性的給定對象,並將其分組爲集合,屬於無監督學習的範疇,最常見的應用場景包括顧客細分和試驗結果分組。目前Scikit-learn已經實現的算法包括:K-均值聚類,譜聚類,均值偏移,分層聚類,DBSCAN聚類等。

  • 數據降維是指使用主成分分析(PCA)、非負矩陣分解(NMF)或特徵選擇等降維技術來減少要考慮的隨機變量的個數,其主要應用場景包括可視化處理和效率提升。

  • 模型選擇是指對於給定參數和模型的比較、驗證和選擇,其主要目的是通過參數調整來提升精度。目前Scikit-learn實現的模塊包括:格點搜索,交叉驗證和各種針對預測誤差評估的度量函數。

  • 數據預處理是指數據的特徵提取和歸一化,是機器學習過程中的第一個也是最重要的一個環節。這裏歸一化是指將輸入數據轉換爲具有零均值和單位權方差的新變量,但因爲大多數時候都做不到精確等於零,因此會設置一個可接受的範圍,一般都要求落在0-1之間。而特徵提取是指將文本或圖像數據轉換爲可用於機器學習的數字變量。

需要特別注意的是,這裏的特徵提取與上文在數據降維中提到的特徵選擇非常不同。特徵選擇是指通過去除不變、協變或其他統計上不重要的特徵量來改進機器學習的一種方法。

總結來說,Scikit-learn實現了一整套用於數據降維,模型選擇,特徵提取和歸一化的完整算法/模塊,雖然缺少按步驟操作的參考教程,但Scikit-learn針對每個算法和模塊都提供了豐富的參考樣例和詳細的說明文檔。

安裝運行Scikit-learn

如前所述,Scikit-learn需要NumPy和SciPy等其他包的支持,因此在安裝Scikit-learn之前需要提前安裝一些支持包. Python、Numpy、Scipy

最後安裝scikit-learn

sudo pip install -U scikit-learn

具體的使用方法,可以搜索 scikit user guidance,或者瀏覽http://scikit-learn.org/stable/user_guide.html
瞭解使用方法。

交叉驗證(CrossValidation)

主要使用K-fold Cross Validation(記爲K-CV)。
將原始數據分成K組(一般是均分),將每個子集數據分別做一次驗證集,其餘的K-1組子集數據作爲訓練集,這樣會得到K個模型,用這K個模型最終的驗證集的分類準確率的平均數作爲此K-CV下分類器的性能指標.K一般大於等於2,實際操作時一般從3開始取,只有在原始數據集合數據量小的時候纔會嘗試取2.K-CV可以有效的避免過學習以及欠學習狀態的發生,最後得到的結果也比較具有說服性.
具體的介紹可瀏覽交叉驗證(CrossValidation):

數據準備

程序使用的代碼源於UCI的Iris數據集,可在官網下載到:Iris數據集
使用到了其中的iris.data ,該數據集地址爲:iris.data數據集
該數據集的內容如下:

5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
4.7,3.2,1.3,0.2,Iris-setosa
4.6,3.1,1.5,0.2,Iris-setosa
5.0,3.6,1.4,0.2,Iris-setosa
5.4,3.9,1.7,0.4,Iris-setosa
4.6,3.4,1.4,0.3,Iris-setosa
5.0,3.4,1.5,0.2,Iris-setosa

對於該數據集的描述,官網給出如下說明:

1. Number of Instances: 150 (50 in each of three classes)

2. Number of Attributes: 4 numeric, predictive attributes and the class

3. Attribute Information:
   1. sepal length in cm
   2. sepal width in cm
   3. petal length in cm
   4. petal width in cm
   5. class: 
      -- Iris Setosa
      -- Iris Versicolour
      -- Iris Virginica

4. Missing Attribute Values: None

Summary Statistics:
             Min  Max   Mean    SD   Class Correlation
   sepal length: 4.3  7.9   5.84  0.83    0.7826   
    sepal width: 2.0  4.4   3.05  0.43   -0.4194
   petal length: 1.0  6.9   3.76  1.76    0.9490  (high!)
    petal width: 0.1  2.5   1.20  0.76    0.9565  (high!)

5. Class Distribution: 33.3% for each of 3 classes.

參數優化

參數優化目前常用的方法是讓C和g在一定的範圍內取值,對於取定的c和g,把訓練集作爲原始數據集利用K-CV方法得到在此對c和g組合下驗證集的分類準確率,最終取得訓練集驗證分類準確率最高的那組c和g作爲最佳參數。對於可能會有多組的c和g對應着最高的驗證分類準備率的情況下,選取能夠達到最高驗證分類準確率中參數c最小的那對c和g作爲最佳的參數,在取最小c的情況下,可能還會存在多組g,那麼就選取搜索到的第一組c和g作爲最佳參數。因爲懲罰係數c值過大,會導致過於擬合的情況,模型泛化能力不好。

這種尋優思想可以用網格參數優化來實現。懲罰參數的變化範圍在[2^cmin,2^cmax],即在該範圍內尋找最佳的參數c,默認值爲cmin=-8,cmax=8,。RBF中的g變化範圍也在[2^gmin,2^gmax],,默認值同樣爲爲gmin=-8,gmax=8。c,g分別構成橫軸和縱軸,cstep,gstep分別是進行網格參數須有時 c和g的步進太小,即c的取值爲 2^cmin,2^(cmin+cstep),…,2^cmax ,同理g,默認步進取值爲1,通過這種方法找到最佳的c和g組合。

程序實現

import numpy as np
from sklearn.model_selection import train_test_split
from sklearn import svm
from sklearn.model_selection import cross_val_score

fr = open('iris.data')
lines = fr.readlines()
data = []
target = []
for line in lines:
    dt = line.strip('\n').split(',')
    dt1 = []
    for i in dt[0:4]:
        dt1.append(float(i))
    target.append(dt[4])
    data.append(dt1)
target_np = np.array(target)
data_np = np.array(data)
result =[]
for i in (-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5):
    C = 2 ** i
    for j in (-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5):
        G = 2 ** j
        rbf_svc = svm.SVC(kernel='rbf', gamma=G, C=C).fit(data_np, target_np) # 高斯kernel
        # rbf_svc = svm.LinearSVC(C=C).fit(data_np, target_np)
        scores = cross_val_score(rbf_svc, data_np, target_np, cv=10)
        result.append([C,G,scores.mean()])
result1 = sorted(result, key=lambda x:x[2])

for i in result1:
    print i

說明:
數據集的特徵數量爲4,數據集的大小爲150,因此,我採用了高斯kernel的SVM,該模型適合特徵數量較小數據集大小適中的情況。
c和g我從2^-5 ~ 2^5 尋值,設置了默認的步進大小爲1,通過該方法,我將得到的準確率進行了排序,以下是關鍵部分的情況(結果略大,忽略可以捨棄的部分):

[16, 0.125, 0.97333333333333338]
[32, 0.03125, 0.97333333333333338]
[32, 0.0625, 0.97333333333333338]
[0.5, 0.5, 0.98000000000000009]
[0.5, 1, 0.98000000000000009]
[1, 0.125, 0.98000000000000009]
[1, 0.25, 0.98000000000000009]
[1, 0.5, 0.98000000000000009]
[2, 0.0625, 0.98000000000000009]
[2, 0.125, 0.98000000000000009]
[2, 0.25, 0.98000000000000009]
[4, 0.03125, 0.98000000000000009]
[4, 0.0625, 0.98000000000000009]
[4, 0.125, 0.98000000000000009]
[8, 0.03125, 0.98000000000000009]
[8, 0.125, 0.98000000000000009]
[16, 0.0625, 0.98000000000000009]

該數據是最後的排序數據,可見c和g最優的值爲0.5,0.5

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