常用的SVM库实现有:libsvm、liblinear、svm-pref
svm-pref 是康奈尔大学的 Thorsten Joachims 实现的
libsvm 和 liblinear 都是由国立台湾大学的 Chih-Jen Lin 博士开发的,本文主要考虑该实现
libsvm 和 liblinear 的区别
两者均以 c/c++ 实现底层,接口支持完善(MATLAB、Python、Java、C#、R等)
- libsvm 用来解决通用分类问题
- liblinear 主要为大规模数据的线性模型设计,仅包含线性核,计算速度比 libsvm 快得多
此外,文章还给出了几条经验:
- 若特征数远大于样本数,使用线性核就可以(liblinear)
- 若特征数和样本数都很大,一般也使用线性核
- 若特征数远小于样本数,一般使用 RBF 核。如果一定要用线性核,建议 -s 2
使用 libsvm
重点参考文章《libsvm使用说明》和项目主页
数据格式
# <label> <index1>:<value1> <index2>:<value2>...
1 1:-0.55556 2:0.5 3:-0.69491 4:-0.75
3 1:-0.16667 2:-0.33333 3:0.38983 4:0.91667
label 为该组样本的类别(libsvm 支持多类)
index 为该样本特征序号
value 为第 index 特征的值
数据归一化
libsvm 提供了接口 svm-scale
svm-scale [options]filename
options:
-l -u : 上下界(默认[-1,1])
-s -r : save/read scalefile
-y : 类别的标准化(如:-y 0 1)
数据的训练
svm-train [options] datafile [modelfile]
options:
-s : svm 类型,默认第0种
一共有5种:0 -- C-SVC(多类别分类)
1 -- nu-SVC(多类别分类)
2 -- one-class SVM(分布估计)
3 -- epsilon-SVR(回归)
4 -- nu-SVR(回归)
-t : 核函数类型,默认第2种
一共有5种:0 -- 线性核(u'*v)
1 -- 多项式核((gamma*u'*v + coef0)^degree)
2 -- RBF核(exp(-gamma*|u-v|^2))
3 -- sigmoid核(tanh(gamma*u'*v + coef0))
4 -- precompute kernel(使用训练数据生成)
-d : degree,默认 3
-g :gamma,默认 1/num_features
-r :coef0,默认 0
-c :cost,针对 C-SVC, epsilon-SVR, and nu-SVR,默认 1
-n :nu,针对 nu-SVC, one-class SVM, and nu-SVR,默认 0.5
-p :e,设置epsilon-SVR中的 e,默认0.1
-m :cachesize,内存大小,默认 100MB
-e : 终止条件的可容忍偏差,默认 0.001
-h :shrinking,是否使用启发式,默认 1
-b :概率估计,是否估计SVC或SVR的概率分布,默认0
-wi :weight,对各类样本的惩罚系数C加权,默认 1
-v n :n-折 交叉验证模式,不会生成模型文件
调参
使用 libsvm 提供的 grid.py 实现自动寻参
#适用于 分类问题 RBF核和线性核
python [options] grid.py datafile
预测
svm-predict [options] test_file model_file output_file
options:
-b :概率估计,是否估计SVC或SVR的概率分布,默认0
C/C++接口
工程里加入 libsvm 的 “svm.h”和“svm.cpp”即可
调用方法参考文件 “svm-scale.c”、“svm-train.c”和“svm-predict.c”
Python接口
参考“libsvm/python/README”
#通过文件读取
from svmutil import *
# Read data in LIBSVM format
y, x = svm_read_problem('../heart_scale')
m = svm_train(y[:200], x[:200], '-c 4')
p_label, p_acc, p_val = svm_predict(y[200:], x[200:], m)
#输入数据
# Dense data
y, x = [1,-1], [[1,0,1], [-1,0,-1]]
# Sparse data
y, x = [1,-1], [{1:1, 3:1}, {1:-1,3:-1}]
prob = svm_problem(y, x)
param = svm_parameter('-t 0 -c 4 -b 1')
m = svm_train(prob, param)
#precomputed kernel 模式
# Dense data
y, x = [1,-1], [[1, 2, -2], [2, -2, 2]]
# Sparse data
y, x = [1,-1], [{0:1, 1:2, 2:-2}, {0:2, 1:-2, 2:2}]
# isKernel=True must be set for precomputed kernel
prob = svm_problem(y, x, isKernel=True)
param = svm_parameter('-t 4 -c 4 -b 1')
m = svm_train(prob, param)
#模型保存与读取
svm_save_model('heart_scale.model', m)
m = svm_load_model('heart_scale.model')
p_label, p_acc, p_val = svm_predict(y, x, m, '-b 1')
ACC, MSE, SCC = evaluations(y, p_label)