libsvm的安装及使用

libsvm–下载台湾林老师的版本,现在更新到libsvm3.21。当做一般的工具箱的使用方法就可以了。
1、保存路径,选择在D:\Program Files\MATLAB\R2015a\toolbox\libsvm-3.21。将这个路径以及子文件夹添加到matlab路径中。其实只要windows文件夹下的就可以,为了方便吧,要是自己写的一些扩展的相关库函数捏。
2、libsvm-3.21\matlab\make.m运行,生成的.mexw64剪切进windows文件夹。
3、运行自带有测试数据,为软件包根目录下的heart_scale文件,可以用来测试LIBSVM是否安装成功。这里的heart_scale文件不能用Matlab的load进行读取,需要使用libsvmread读取。

[heart_scale_label, heart_scale_inst] = libsvmread('heart_scale');
model = libsvmtrain(heart_scale_label, heart_scale_inst, '-c 1 -g 0.07');
[predict_label, accuracy, dec_values] = libsvmpredict(heart_scale_label, heart_scale_inst, model);

%注,heart_scale用txt打开可以看到格式,这个格式和特征矩阵和标签之间的转换,可以使用同学给的exe工具https://yunpan.cn/cSHvRW8JCTaBX 访问密码 4fa6。转成libsvm的特征格式就可以使用libsvm-3.21\tools中grid.py(网格寻参)、checkdata.py、easy.py、subset.py。grid.py参数寻优,是用来寻找RBF核中的C,gamma参数的。固定gamma,即可用来对线性核寻优。如c从2的-4次到2的0次

 grid.py -log2c -4,0,1 -log2g 1,1,1 -t 0 -svmtrain c:\svm-train.exe -gnuplot c:\gnuplot\binary\gnuplot.exe -v 4 hog1.dat

然而因为python不太懂,没有用libsvm自带的tools,主要是用matlab,以下就是用matlab,libsvm的方法。

一、libsvmtrain训练参数选择
用默认参数训练的效果如果不好的话(偶的数据集只有4.5%),就要试试寻参了,寻参之前先做归一化。从网上dang了一个normalization的小程序:

function normal = normalization(x,kind)
%输入:
%x:样本数据,每列为1个样本,每行为一类特征(属性)
% kind :1 or 2 表示第一类或第二类规范化。默认归一化到[-1,1]

%输出:
%normal:归一化后的数据
if nargin < 2
    kind = 2;%kind = 1 or 2 表示第一类或第二类规范化
end

[m,n]  = size(x);
normal = zeros(m,n);
%% normalize the data x to [0,1]
if kind == 1
    for i = 1:m
        ma = max( x(i,:) );
        mi = min( x(i,:) );
        normal(i,:) = ( x(i,:)-mi )./( ma-mi );
    end
end
%% normalize the data x to [-1,1]
if kind == 2
    for i = 1:m
        mea = mean( x(i,:) );
        va = var( x(i,:) );
        normal(i,:) = ( x(i,:)-mea )/va;
    end
end
归一化结束特征就可以用网格寻参来寻找bestc,bestg了。因为我用的feature维数是3772*655932,101类别,因为样本数<<特征数,所以一般情况下不需要svm从低维到高维的映射,也应该能找到分类的超平面,所以是用线性核,只需要寻找bestc,惩罚系数,寻参就是遍历c的不同值,测试当下的acc,寻找最高的acc对应的c,这里面可能会有多个最优解,选择min的c作为bestc,因为惩罚系数越大,train的结果的泛化能力越差,test的acc越低。贴下线性核函数的寻参代码:
function [bestacc,bestc] = findcforlinearkenrl(groups,feature)
    cstep = 0.8;
    v = 5;
    cmax = 8;
    cmin = -8;
X = meshgrid(cmin:cstep:cmax);
[m,n] = size(X);
cg = zeros(m);
eps = 10^(-4);
%% record acc with different c & g,and find the bestacc with the smallest c
bestc = 1;
bestacc = 0;
basenum = 2;
for i = 1:m%c

        cmd = [' -c ',num2str( basenum^X(i) ),' -v ',num2str(v),' -t 0'];
        cg(i) = svmtrain(groups, feature, cmd);

        if cg(i) <= 55 
            continue;
        end

        if cg(i) > bestacc
            bestacc = cg(i);
            bestc = basenum^X(i);
        end        

        if abs( cg(i)-bestacc )<=eps && bestc > basenum^X(i) 
            bestacc = cg(i);
            bestc = basenum^X(i);
        end        

end

三、寻参结束以后就可以train和test,因为对train和test的样本没有要求,所以是随机选择的。

[train,test] = crossvalind('holdOut',groups);
cp = classperf(groups);
svmStruct = svmtrain(normal_feature(train,:),groups(train),'-v 0 -c ');
%classes = svmclassify(svmStruct,feature(test,:));
[predict_label, accuracy, dec_values] =svmpredict(groups(test), normal_feature(test,:), svmStruct);

%%注:k-folder cross-validation(k折交叉验证)
K-fold cross-validation (k-CV)则是Double cross-validation的延伸,做法是将数据集分成k个子集,每个子集均做一次测试集,其余的作为训练集。k-CV交叉验证重复k次,每次选择一个子集作为测试集,并将k次的平均交叉验证识别率作为结果。
优点:所有的样本都被作为了训练集和测试集,每个样本都被验证一次。本文使用的是K=5。
抄了一段定义:交叉验证(Cross validation)是一种评估统计分析、机器学习算法对独立于训练数据的数据集的泛化能力(generalize), 能够避免过拟合问题。交叉验证一般要尽量满足:
1)训练集的比例要足够多,一般大于一半
2)训练集和测试集要均匀抽样
%%svm的多分类策略有one-vs-rest 和 one-vs-one,这里显然用的是后者,训练很多分类器,再加上寻参c的遍历,运行时间真是’棒棒’的,这里估计要采取一些策略,但是我还不知道怎么做合适。

libsvm的使用就结束了,但是调参和原理特别值得学习,经典的都是好的嘛。支持向量机的三重门,JUJY大神写的,值得好好学习
http://blog.csdn.net/v_july_v/article/details/7624837
以及libsvm程序的注释:
http://www.pami.sjtu.edu.cn/people/gpliu/document/libsvm_src.pdf

ps:附录,便于以后查阅撒
1、训练参数
Options:
-s svm类型:设置SVM模型类型(默认0)
0 – C-SVC
1 – nu-SVC
2 – one-class SVM
3 – epsilon-SVR
4 – nu-SVR
-t 核函数类型:核函数设置类型(默认2)
0 – 线性核函数: u’*v
1 – 多项式核函数: (gamma*u’*v + coef0)^degree
2 – RBF核函数: exp(-gamma*|u-v|^2)
3 – sigmoid核函数: tanh(gamma*u’*v + coef0)
4 – 预定义核函数(指定核矩阵)
-d degree:核函数中的degree设置(针对多项式核函数)(默认3)
-g gama:核函数中的gamma函数设置(针对多项式/rbf/sigmoid核函数)(默认1/num_features,即属性数目的倒数)
-r coef0:核函数中的coef0设置(针对多项式/sigmoid核函数)(默认0)
-c cost:设置C-SVC,epsilon-SVR和nu-SVC的参数(损失函数)(默认1)
-n nu:设置nu-SVC,one-class SVM和nu-SVR的参数(默认0.5)
-p epsilon:设置epsilon-SVR中损失函数epsilon的值(默认0.1)
-m cachesize:设置cache内存大小,以MB为单位(默认100)
-e eps:设置允许的终止判据(默认0.001)
-h shrinking:是否使用启发式,0或1(默认1)
-wi weight:设置第几类的参数C为weight*C(C-SVC中的C)(默认1)
-v n: n-fold交互检验模式,n为fold的个数,必须大于等于2
参数 -v 随机地将数据剖分为n部分并计算交互检验准确度和均方根误差。
以上这些参数设置可以按照SVM的类型和核函数所支持的参数进行任意组合,如果设置的参数在函数或SVM类型中没有也不会产生影响,程序不会接受该参数;如果应有的参数设置不正确,参数将采用默认值。
2、 训练返回的内容
libsvmtrain函数返回训练好的SVM分类器模型,可以用来对未知的样本进行预测。这个模型是一个结构体,包含以下成员:

-Parameters: 一个5 x 1的矩阵,从上到下依次表示:
    -s SVM类型(默认0);
    -t 核函数类型(默认2)
    -d 核函数中的degree设置(针对多项式核函数)(默认3);
    -g 核函数中的r(gamma)函数设置(针对多项式/rbf/sigmoid核函数) (默认类别数目的倒数);
    -r 核函数中的coef0设置(针对多项式/sigmoid核函数)((默认0)
-nr_class: 表示数据集中有多少类别,比如二分类时这个值即为2。
-totalSV: 表示支持向量的总数。
-rho: 决策函数wx+b中的常数项的相反数(-b)。
-Label: 表示数据集中类别的标签,比如二分类常见的1和-1。
-ProbA: 使用-b参数时用于概率估计的数值,否则为空。
-ProbB: 使用-b参数时用于概率估计的数值,否则为空。
-nSV: 表示每类样本的支持向量的数目,和Label的类别标签对应。如Label=[1; -1],nSV=[63; 67],则标签为1的样本有63个支持向量,标签为-1的有67个。
-sv_coef: 表示每个支持向量在决策函数中的系数。
-SVs: 表示所有的支持向量,如果特征是n维的,支持向量一共有m个,则为m x n的稀疏矩阵。
另外,如果在训练中使用了-v参数进行交叉验证时,返回的不是一个模型,而是交叉验证的分类的正确率或者回归的均方根误差。

  1. 预测返回的内容
    libsvmtrain函数有三个返回值,不需要的值在Matlab可以用~进行代替。

-predicted_label:第一个返回值,表示样本的预测类标号。
-accuracy:第二个返回值,一个3 x 1的数组,表示分类的正确率、回归的均方根误差、回归的平方相关系数。
-decision_values/prob_estimates:第三个返回值,一个矩阵包含决策的值或者概率估计。对于n个预测样本、k类的问题,如果指定“-b 1”参数,则n x k的矩阵,每一行表示这个样本分别属于每一个类别的概率;如果没有指定“-b 1”参数,则为n x k*(k-1)/2的矩阵,每一行表示k(k-1)/2个二分类SVM的预测结果。
4. 读取或保存
libsvmread函数可以读取以LIBSVM格式存储的数据文件。

[label_vector, instance_matrix] = libsvmread(‘data.txt’);

这个函数输入的是文件的名字,输出为样本的类标和对应的特征。

libsvmwrite函数可以把Matlab的矩阵存储称为LIBSVM格式的文件。

libsvmwrite(‘data.txt’, label_vector, instance_matrix]

这个函数有三个输入,分别为保存的文件名、样本的类标和对应的特征(必须为double类型的稀疏矩阵)。

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