libsvm 训练后的模型参数讲解
主要就是讲解利用libsvm-mat工具箱建立分类(回归模型)后,得到的模型model里面参数的意义都是神马?以及如果通过model得到相应模型的表达式,这里主要以分类问题为例子。 测试数据使用的是libsvm-mat自带的heart_scale.mat数据(270*13的一个属性据矩阵,共有270个样本,每个样本有13个属性),方便大家自己测试学习。 首先上一个简短的测试代码:
- %% ModelDecryption
- % by faruto @ faruto’s Studio~
- % http://blog.sina.com.cn/faruto
- % Email:faruto@163.com
- % http://www.matlabsky.com
- % http://www.mfun.la
- % http://video.ourmatlab.com
- % last modified by 2011.01.06
- %% a litte clean work
- tic;
- close all;
- clear;
- clc;
- format compact;
- %%
- % 首先载入数据
- load heart_scale;
- data = heart_scale_inst;
- label = heart_scale_label;
- % 建立分类模型
- model = svmtrain(label,data,’-s 0 -t 2 -c 1.2 -g 2.8’);
- model
- % 利用建立的模型看其在训练集合上的分类效果
- [PredictLabel,accuracy] = svmpredict(label,data,model);
- accuracy
- %%
toc;
运行结果:
model =
- Parameters: [5x1 double]
- nr_class: 2
- totalSV: 259
- rho: 0.0514
- Label: [2x1 double]
- ProbA: []
- ProbB: []
- nSV: [2x1 double]
- sv_coef: [259x1 double]
- SVs: [259x13 double]
- Accuracy = 99.6296% (269/270) (classification)
- accuracy =
- 99.6296
- 0.0148
- 0.9851
Elapsed time is 0.040155 seconds.
这里面为了简单起见没有将测试数据进行训练集和测试集的划分,这里仅仅是为了简单明了而已,分类结果估计可以不要管,参数优化也不要管,另有帖子讲解。 下面我们就看看 model这个结构体里面的各种参数的意义都是神马,model如下: model = Parameters: [5x1 double] nr_class: 2 totalSV: 259 rho: 0.0514 Label: [2x1 double] ProbA: [] ProbB: [] nSV: [2x1 double] sv_coef: [259x1 double] SVs: [259x13 double] model.Parameters 我们先来看一下model.Parameters里面承装的都是什么:
> model.Parameters
- ans =
- 0
- 2.0000
- 3.0000
- 2.8000
0
重要知识点: model.Parameters参数意义从上到下依次为: -s svm类型:SVM设置类型(默认0) -t 核函数类型:核函数设置类型(默认2) -d degree:核函数中的degree设置(针对多项式核函数)(默认3) -g r(gama):核函数中的gamma函数设置(针对多项式/rbf/sigmoid核函数) (默认类别数目的倒数) -r coef0:核函数中的coef0设置(针对多项式/sigmoid核函数)((默认0) 即在本例中通过model.Parameters我们可以得知 –s 参数为0;-t 参数为 2;-d 参数为3;-g 参数为2.8(这也是我们自己的输入);-r 参数为0。 关于libsvm参数的一点小说明: Libsvm中参数设置可以按照SVM的类型和核函数所支持的参数进行任意组合,如果设置的参数在函数或SVM类型中没有也不会产生影响,程序不会接受该参数;如果应有的参数设置不正确,参数将采用默认值。 model.Label model.nr_class
> model.Label
- ans =
- 1
- -1
> model.nr_class
- ans =
2
重要知识点: model.Label表示数据集中类别的标签都有什么,这里是 1,-1; model.nr_class表示数据集中有多少类别,这里是二分类。 model.totalSV model.nSV
> model.totalSV
- ans =
- 259
> model.nSV
- ans =
- 118
141
重要知识点: model.totalSV代表总共的支持向量的数目,这里共有259个支持向量; model.nSV表示每类样本的支持向量的数目,这里表示标签为1的样本的支持向量有118个,标签为-1的样本的支持向量为141。 注意:这里model.nSV所代表的顺序是和model.Label相对应的。 model.ProbA model.ProbB 关于这两个参数这里不做介绍,使用-b参数时才能用到,用于概率估计。 -b probability_estimates: whether to train a SVC or SVR model for probability estimates, 0 or 1 (default 0) model.sv_coef model.SVs model.rho
sv_coef: [259x1 double]
- SVs: [259x13 double]
model.rho = 0.0514
重要知识点: model.sv_coef是一个259*1的矩阵,承装的是259个支持向量在决策函数中的系数; model.SVs是一个259*13的稀疏矩阵,承装的是259个支持向量。 model.rho是决策函数中的常数项的相反数(-b) 在这里首先我们看一下 通过 –s 0 参数(C-SVC模型)得到的最终的分类决策函数的表达式是怎样的? 这里如果有关于C-SVC模型不懂的地方,请看这个pdf文件: libsvm_library.pdf 附件: 最终的决策函数为: 在由于我们使用的是RBF核函数(前面参数设置 –t 2),故这里的决策函数即为: 其中|| x-y ||是二范数距离 ; 这里面的 b就是-model.rho(一个标量数字); b = -model.rho; n代表支持向量的个数即 n = model.totalSV(一个标量数字); 对于每一个i: wi =model.sv_coef(i); 支持向量的系数(一个标量数字) xi = model.SVs(i,:) 支持向量(1*13的行向量) x 是待预测标签的样本 (1*13的行向量) gamma 就是 -g 参数 好的下面我们通过model提供的信息自己建立上面的决策函数如下:
%% DecisionFunction
function plabel = DecisionFunction(x,model)
gamma = model.Parameters(4);
RBF = @(u,v)( exp(-gamma.*sum( (u-v).^2) ) );
len = length(model.sv_coef);
y = 0;
for i = 1:len
- u = model.SVs(i,:);
- y = y + model.sv_coef(i)*RBF(u,x);
- end
- b = -model.rho;
y = y + b;
if y >= 0
- plabel = 1;
- else
- plabel = -1;
end
有了这个决策函数,我们就可以自己预测相应样本的标签了:
%%
- plable = zeros(270,1);
- for i = 1:270
- x = data(i,:);
- plabel(i,1) = DecisionFunction(x,model);
end
%% 验证自己通过决策函数预测的标签和svmpredict给出的标签相同
- flag = sum(plabel == PredictLabel)
over = 1;
最终可以看到 flag = 270 ,即自己建立的决策函数是正确的,可以得到和svmpredict得到的一样的样本的预测标签,事实上svmpredict底层大体也就是这样实现的。 最后我们来看一下,svmpredict得到的返回参数的意义都是什么 在下面这段代码中 :
%%
- % 首先载入数据
- load heart_scale;
- data = heart_scale_inst;
- label = heart_scale_label;
- % 建立分类模型
- model = svmtrain(label,data,’-s 0 -t 2 -c 1.2 -g 2.8’);
- model
- % 利用建立的模型看其在训练集合上的分类效果
- [PredictLabel,accuracy] = svmpredict(label,data,model);
accuracy
运行可以看到
model =
- Parameters: [5x1 double]
- nr_class: 2
- totalSV: 259
- rho: 0.0514
- Label: [2x1 double]
- ProbA: []
- ProbB: []
- nSV: [2x1 double]
- sv_coef: [259x1 double]
- SVs: [259x13 double]
- Accuracy = 99.6296% (269/270) (classification)
- accuracy =
- 99.6296
- 0.0148
0.9851
这里面要说一下返回参数accuracy的三个参数的意义。 重要的知识点: 返回参数accuracy从上到下依次的意义分别是: 分类准率(分类问题中用到的参数指标) 平均平方误差(MSE (mean squared error)) [回归问题中用到的参数指标] 平方相关系数(r2 (squared correlation coefficient))[回归问题中用到的参数指标] 其中mse 和r2的计算公式分别为: 插图: 写在后面的话,至此关于model中相应参数的一些意义,以及到底如果得到决策函数的表达式或者计算方式的就算是说的很明了了。 可能还有的同学会问,如何得到分类决策函数中的那个alpha系数【这个肯定会有人问】,还是再磨叽说一下吧: 上面的wi其实是alpha和支持向量的类别标签(1或-1的乘积),原始决策函数的表达式如下: 插图: 上面的yi是支持向量的类别标签(1或者-1),在libsvm中将yi和alpha的乘积放在一起用model.sv_coef(w)来承装。 都说到这份上,应该能明白了吗? 再说点废话:就是在关于SVM的学习中,我发现很多朋友都不主动思考和尝试,老是在问,这样很不好,这样很被动,上面这些也没有人教我,都是我自己思考出来,然后编程验证,如果出现不合理的地方就再继续思考,反正道理和书籍里面都有讲解,总能洞穿的啊。O(∩_∩)O•
svm-train的用法
用法: svm-train [options] training_set_file [model_file] 其中, -s svm训练,默认0, 其中前三种用来做分类问题,后两种用来实现回归问题。 0 c-SVC, 1 nu-SVC,
2 one-class SVM,
3 epsilon-SVR,
4. v-SVR,
-t 核函数类型 0 线性核函数,
1 多项式核函数,
2 RBF核函数,
3 sigmoid核函数,
4 自定义核函数 -v n, n-fold交叉验证。 -d degree,设置多项式核函数的参数d,默认为3。 -g gamma,设置多项式、RBF 、sigmoid核函数的参数,在多项式和sigmoid中gamma表示为a,在RBF中表示为r,默认为1/num_features。 -r 设置多项式和sigmoid核函数中的常数项c,默认为0。 -c cost,设置c-svc,epsilon-SVR,nu-SVR类型的惩罚系数C,默认为1。 -n nu,设置nu-SVC,one-class SVM,nu-SVR类型的参数v,默认为0.5。 -p epsilon,设置epsilon-SVR的loss function参数,默认为0.1。 -m cachesize ,设置cache大小,默认为100MB。 -e epsilon,设置终止条件,默认为0.001。 -h shrinking,是否运用shrinking启发式,默认为1。 -b probability_estimates,是否使用概率估计模型,默认0。 -wi weight,将i类的参数C设置为weight*C,默认为1。 -v n, n-fold交叉验证。 使用示例: svmtrain train3.scale train3.model 训练 train3.scale, 将模型保存于文件 train3.model, 并在 dos 窗口中输出如下结果:
optimization finished, #iter = 1756
nu = 0.464223
obj = -551.002342, rho = -0.337784
nSV = 604, nBSV = 557
Total nSV = 604
- 1
- 2
- 3
- 4
5
1
- 2
- 3
- 4
- 5
其中,#iter 为迭代次数,nu 与前面的操作参数-n ν 相同,obj 为 SVM 文件转换为的二次规划求解得到的最小值,rho 为判决函数的常数项 b ,nSV 为支持向量个数,nBSV 为边界上的支持向量个数,Total nSV 为支持向量总个数。 模型文件介绍:
svm_type c_svc % 训练所采用的svm类型,此处为C SVC −
kernel_type rbf % 训练采用的核函数类型,此处为RBF核
gamma 0.047619 % 与操作参数设置中的 γ 含义相同
nr_class 2 % 分类时的类别数,此处为两分类问题
total_sv 604 % 总共的支持向量个数
rho -0.337784 % 决策函数中的常数项 b
label 0 1 % 类别标签
nr_sv 314 290 % 各类别标签对应的支持向量个数
SV % 以下为支持向量
1 1:-0.963808 2:0.906788 ... 19:-0.197706 20:-0.928853 21:-1
1 1:-0.885128 2:0.768219 ... 19:-0.452573 20:-0.980591 21:-1
... ... ...
1 1:-0.847359 2:0.485921 ... 19:-0.541457 20:-0.989077 21:-1
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
13
1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
svm-predict的用法
用法:svm-predict [options] test_file model_file output_file 其中 -b probability_estimates,是否需要进行概率估计预测,可选值为 0 或者 1,默认值为 0。 est_file 是要进行预测的数据文件; model_file 是由 svmtrain 产生的模型文件; output_file 是 svmpredict 的输出文件,表示预测的结果值。 svmpredict 没有其它的选项。