LibSVM for Python 使用
經歷手寫SVM的慘烈教訓(還是太年輕)之後,我決定使用工具箱/第三方庫
Python
libsvm的GitHub倉庫
LibSVM是開源的SVM實現,支持C, C++, Java,Python , R 和 Matlab 等, 這裏選擇使用Python版本。
安裝LibSVM
將LibSVM倉庫的所有內容放入Python的包目錄\Lib\site-packages或者工程目錄中。
在libsvm根目錄和python子目錄下中分別新建名為__init__.py
的空文件,這兩個空文件將標識所在的目錄為python包可以直接導入。
允許草民吐槽一下各種Blog裏切換根目錄的奇怪的解決方案:這個和這個
因為經常使用svm,所以草民將libsvm包放入\Lib\site-packages目錄下。在Python交互環境或在任意腳本中都可以使用import libsvm.python
使用LibSVM
LibSVM的使用非常簡單,只需調用有限的接口
示例1:
from libsvm.python.svmutil import * from libsvm.python.svm import * y, x = [1,-1], [{1:1, 2:1}, {1:-1,2:-1}] prob = svm_problem(y, x) param = svm_parameter(‘-t 0 -c 4 -b 1‘) model = svm_train(prob, param) yt = [1] xt = [{1:1, 2:1}] p_label, p_acc, p_val = svm_predict(yt, xt, model) print(p_label)
輸出結果:
optimization finished, #iter = 1
nu = 0.062500
obj = -0.250000, rho = 0.000000
nSV = 2, nBSV = 0
Total nSV = 2
test:
Model supports probability estimates, but disabled in predicton.
Accuracy = 100% (1/1) (classification)
[1.0]
在SVM數據中下載train1.txt和test1.txt。
LibSVM可以在文件中讀取訓練數據,這樣便於大規模數據的使用。
示例:
from libsvm.python.svmutil import * from libsvm.python.svm import * y, x = svm_read_problem(‘train1.txt‘) yt, xt = svm_read_problem(‘test1.txt‘) model = svm_train(y, x ) print(‘test:‘) p_label, p_acc, p_val = svm_predict(yt[200:202], xt[200:202], model) print(p_label)
可以看到輸出:
optimization finished, #iter = 5371
nu = 0.606150
obj = -1061.528918, rho = -0.495266
nSV = 3053, nBSV = 722
Total nSV = 3053
test:
Accuracy = 40.809% (907/2225) (classification)
LibSVM接口
訓練數據格式
libsvm的訓練數據格式如下:
<label> <index1>:<value1> <index2>:<value2> ...
示例:
1 1:2.927699e+01 2:1.072510e+02 3:1.149632e-01 4:1.077885e+02
主要類型
svm_problem
保存定義SVM模型的訓練數據
svm_parameter
存儲訓練SVM模型所需的各種參數
svm_model
完成訓練的SVM模型
svm_node
模型中一個特征的值,只包含一個整數索引和一個浮點值屬性。
主要接口:
-svm_problem(y, x)
由訓練數據y,x創建svm_problem對象
svm_train()
svm_train有3個重載:
model = svm_train(y, x [, ‘training_options‘])
model = svm_train(prob [, ‘training_options‘])
model = svm_train(prob, param)
用於訓練svm_model模型
- `svm_parameter(cmd)
創建svm_parameter對象,參數為字符串。
示例:
param = svm_parameter(‘-t 0 -c 4 -b 1‘)
svm_predict()
調用語法:
p_labs, p_acc, p_vals = svm_predict(y, x, model [,‘predicting_options‘])
參數:
y
測試數據的標簽
x
測試數據的輸入向量
model
為訓練好的SVM模型。
返回值:
p_labs
是存儲預測標簽的列表。
p_acc
存儲了預測的精確度,均值和回歸的平方相關系數。
p_vals
在指定參數‘-b 1‘時將返回判定系數(判定的可靠程度)。
這個函數不僅是測試用的接口,也是應用狀態下進行分類的接口。比較奇葩的是需要輸入測試標簽y才能進行預測,因為y不影響預測結果可以用0向量代替。
svm_read_problem
讀取LibSVM格式的訓練數據:
y, x = svm_read_problem(‘data.txt‘)
svm_save_model
將訓練好的svm_model存儲到文件中:
svm_save_model(‘model_file‘, model)
model_file的內容:
svm_type c_svc
kernel_type linear
nr_class 2
total_sv 2
rho 0
label 1 -1
probA 0.693147
probB 2.3919e-16
nr_sv 1 1
SV
0.25 1:1 2:1
-0.25 1:-1 2:-1
svm_load_model
讀取存儲在文件中的svm_model:
model = svm_load_model(‘model_file‘)
調整SVM參數
LibSVM在訓練和預測過程中需要一系列參數來調整控制。
svm_train的參數:
-
-s
SVM的類型(svm_type)-
0 -- C-SVC(默認)
使用懲罰因子(Cost)的處理噪聲的多分類器
-
1 -- nu-SVC(多分類器)
按照錯誤樣本比例處理噪聲的多分類器
-
2 -- one-class SVM
一類支持向量機,可參見"SVDD"的相關內容
-
3 -- epsilon-SVR(回歸)
epsilon支持向量回歸
-
4 -- nu-SVR(回歸)
-
-
-t
核函數類型(kernel_type)-
0 -- linear(線性核):
u‘*v
-
1 -- polynomial(多項式核):
(gamma*u‘*v + coef0)^degree
-
2 -- radial basis function(RBF,徑向基核/高斯核):
exp(-gamma*|u-v|^2)
-
3 -- sigmoid(S型核):
tanh(gamma*u‘*v + coef0)
-
4 -- precomputed kernel(預計算核):
核矩陣存儲在
training_set_file
中
-
下面是調整SVM或核函數中參數的選項:
-
-d
調整核函數的degree參數,默認為3 -
-g
調整核函數的gamma參數,默認為1/num_features
-
-r
調整核函數的coef0參數,默認為0
-
-c
調整C-SVC, epsilon-SVR 和 nu-SVR中的Cost參數,默認為1
-
-n
調整nu-SVC, one-class SVM 和 nu-SVR中的錯誤率nu參數,默認為0.5
-
-p
調整epsilon-SVR的loss function中的epsilon參數,默認0.1
-
-m
調整內緩沖區大小,以MB為單位,默認100
-
-e
調整終止判據,默認0.001
-
-wi
調整C-SVC中第i個特征的Cost參數
調整算法功能的選項:
-
-b
是否估算正確概率,取值0 - 1,默認為0
-
-h
是否使用收縮啟發式算法(shrinking heuristics),取值0 - 1,默認為0
-
-v
交叉校驗 -
-q
靜默模式
Matlab
LibSVM的Matlab接口用法類似,Matlab豐富的標準工具箱提供了各種方便。
Statistic Tools工具箱提供了svmtrain和svmclassify函數進行SVM分類。
traindata = [0 1; -1 0; 2 2; 3 3; -2 -1;-4.5 -4; 2 -1; -1 -3];
group = [1 1 -1 -1 1 1 -1 -1]‘;
testdata = [5 2;3 1;-4 -3];
svm_struct = svmtrain(traindata,group);
Group = svmclassify(svm_struct,testdata);
svmtrain接受traindata和group兩個參數,traindata以一行表示一個樣本,group是與traindata中樣本對應的分類結果,用1和-1表示。
svmtrain返回一個存儲了訓練好的svm所需的參數的結構體svm_struct。
svmclassify接受svm_struct和以一行表示一個樣本的testdata,並以1和-1列向量的形式返回分類結果。
LibSVM for Python 使用