• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

matlab-SVM(支持向量机)—转 机器学习&数据挖掘笔记_16( ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

http://blog.csdn.net/jiejinquanil/article/details/52270178(机器学习常用算法总结

http://www.jianshu.com/p/55a67c12d3e9(轻松看懂机器学习十大常用算法)

http://www.cnblogs.com/darkknightzh/p/5554551.html

http://www.cnblogs.com/lwflourish/p/4121892.html

http://blog.csdn.net/u010412719/article/details/46794051

http://blog.sina.com.cn/s/blog_631a4cc40101df0f.html

http://blog.csdn.net/wenyusuran/article/details/35987813

http://blog.sina.com.cn/s/blog_71152aa70101tl62.html

 

可分离数据:SVM可以用于将已知数据分为两类,SVM分类器主要是找到两类之间最佳的超平面,将两类彻底分开,

  1.   用已知数据去训练SVM分类器
SVMstruct =svmtrain(data,groups,\'Kernel_Function\',\'rbf\');

data :数据点矩阵,每一行代表一个观测对象,每一列代表每一个观测对象提取的特征;

groups:

kernel_Function:默认为用超平面将数据线性分开.’rbf’用了高斯径向基函数;建议首先用‘rbf’尝试;

SVMstruct的结果结构体包含从SVM算法中获得的最佳参数值,因而可以用于将一些新的数据分开; 

2.将待测数据用SVM分类器分开:

newClasses=svmclassify(SVMstruct,newData)

newClasses 产生的结果代表了在新数据里面每一行的分类;

3.调整SVM分类器

Hsu,chang and Lin建议遵循如下的方案,调整分类器的参数:

1. 首先使用‘rbf’kernel 函数;

2. 尝试使用不同的参数进行训练,然后通过交叉检验验证得到的最合适的参数

3. 最重要的尝试改变的参数:

boxconstraint-尽量以等比数列的方式去调整约束参数值;

rbf-sigma-尽量以等比数列的方式去调整RBF的sigma约束参数值;

4. 不同的参数设置,通过交叉检验去检测结果,通过crossval

5. 当获得合理的初始化参数值时,你可能想要重新定义你的参数去火的更加好的准确率,以更加小的等比的公因子,去调整参数,最优化你的参数,通过fminsearch,

 

 

支持向量机(SVM)的matlab的实现

支持向量机是一种分类算法之一,matlab中也有相应的函数来对其进行求解;下面贴一个小例子,这个例子来源于我们实际的项目。

clc;
clear;
N=10;
%下面的数据是我们实际项目中的训练样例(样例中有8个属性)
correctData=[0,0.2,0.8,0,0,0,2,2];
errorData_ReversePharse=[1,0.8,0.2,1,0,0,2,2];
errorData_CountLoss=[0.2,0.4,0.6,0.2,0,0,1,1];
errorData_X=[0.5,0.5,0.5,1,1,0,0,0];
errorData_Lower=[0.2,0,1,0.2,0,0,0,0];
errorData_Local_X=[0.2,0.2,0.8,0.4,0.4,0,0,0];
errorData_Z=[0.53,0.55,0.45,1,0,1,0,0];
errorData_High=[0.8,1,0,0.8,0,0,0,0];
errorData_CountBefore=[0.4,0.2,0.8,0.4,0,0,2,2];
errorData_Local_X1=[0.3,0.3,0.7,0.4,0.2,0,1,0];
 sampleData=[correctData;errorData_ReversePharse;errorData_CountLoss;errorData_X;errorData_Lower;errorData_Local_X;errorData_Z;errorData_High;errorData_CountBefore;errorData_Local_X1];%训练样例

type1=1;%正确的波形的类别,即我们的第一组波形是正确的波形,类别号用 1 表示
type2=-ones(1,N-2);%不正确的波形的类别,即第2~10组波形都是有故障的波形,类别号用-1表示
groups=[type1 ,type2]\';%训练所需的类别号
j=1;
%由于没有测试数据,因此我将错误的波形数据轮流从训练样例中取出作为测试样例
for i=2:10
   tempData=sampleData;
   tempData(i,:)=[];
    svmStruct = svmtrain(tempData,groups);
    species(j) = svmclassify(svmStruct,sampleData(i,:));
    j=j+1;
end
species

输出结果如下:

 -1    -1    -1    -1    -1    -1    -1     1    -1

从结果可以看出:只有第九个被误判,其它的都是正确的。

上面只是用于说明matlab中支持向量机中函数的用法,因为在训练集中我只用了一个正确的波形和九组有故障的波形作为训练集,因此这种超平面的选取可能不好。但是,在我们的实际的项目中,我们是用到了许多的训练集的。

上面是调用matlab中的函数实现多维属性中的支持向量机对其进行分类。

下面是自己实现此功能,不调用matlab中的支持向量机的函数。代码如下:

%主函数
clear all;
clc;
C = 10;
kertype = \'linear\';
%训练样本
n = 50;
randn(\'state\',6);%可以保证每次每次产生的随机数一样
x1 = randn(2,n);    %2行N列矩阵
y1 = ones(1,n);       %1*N个1
x2 = 5+randn(2,n);   %2*N矩阵
y2 = -ones(1,n);      %1*N个-1

figure;
plot(x1(1,:),x1(2,:),\'bx\',x2(1,:),x2(2,:),\'k.\'); 
axis([-3 8 -3 8]);
xlabel(\'x轴\');
ylabel(\'y轴\');
hold on;

X = [x1,x2];        %训练样本d*n矩阵,n为样本个数,d为特征向量个数,在这里,X为一个2*100的数组
Y = [y1,y2];        %训练目标1*n矩阵,n为样本个数,值为+1或-1,在这里,Y为一个1*100的数组
svm = svmTrain(X,Y,kertype,C);
plot(svm.Xsv(1,:),svm.Xsv(2,:),\'ro\');

%测试
[x1,x2] = meshgrid(-2:0.05:7,-2:0.05:7);  %x1和x2都是181*181的矩阵
[rows,cols] = size(x1);  
nt = rows*cols;                  
Xt = [reshape(x1,1,nt);reshape(x2,1,nt)];
Yt = ones(1,nt);
result = svmTest(svm, Xt, Yt, kertype);

Yd = reshape(result.Y,rows,cols);
contour(x1,x2,Yd,\'m\');


训练集函数如下:

function svm = svmTrain(X,Y,kertype,C)
options = optimset;    % Options是用来控制算法的选项参数的向量
options.LargeScale = \'off\';%LargeScale指大规模搜索,off表示在规模搜索模式关闭
options.Display = \'off\';%这样设置意味着没有输出

n = length(Y);%数组Y的长度
H = (Y\'*Y).*kernel(X,X,kertype);%调用kernel函数,

f = -ones(n,1); %f为1*n个-1,f相当于Quadprog函数中的c
A = [];
b = [];
Aeq = Y; %相当于Quadprog函数中的A1,b1
beq = 0;
lb = zeros(n,1); %相当于Quadprog函数中的LB,UB
ub = C*ones(n,1);
a0 = zeros(n,1);  % a0是解的初始近似值
[a,fval,eXitflag,output,lambda]  = quadprog(H,f,A,b,Aeq,beq,lb,ub,a0,options);

epsilon = 1e-8;                     
sv_label = find(abs(a)>epsilon);  %0<a<a(max)则认为x为支持向量     
svm.a = a(sv_label);
svm.Xsv = X(:,sv_label);
svm.Ysv = Y(sv_label);
svm.svnum = length(sv_label);
%svm.label = sv_label;

 

核函数如下:

function K = kernel(X,Y,type)
%X 维数*个数
switch type
case \'linear\'
    K = X\'*Y;
case \'rbf\'
    delta = 5;
    delta = delta*delta;
    XX = sum(X\'.*X\',2);%sum(a,2)代码中参数2的意思是将a矩阵a中的按“行”为单位进行求和
    YY = sum(Y\'.*Y\',2);
    XY = X\'*Y;
    K = abs(repmat(XX,[1 size(YY,1)]) + repmat(YY\',[size(XX,1) 1]) - 2*XY);
    K = exp(-K./delta);
end

测试函数如下

function result = svmTest(svm, Xt, Yt, kertype)
temp = (svm.a\'.*svm.Ysv)*kernel(svm.Xsv,svm.Xsv,kertype);
total_b = svm.Ysv-temp;
b = mean(total_b);
w = (svm.a\'.*svm.Ysv)*kernel(svm.Xsv,Xt,kertype);
result.score = w + b;
Y = sign(w+b);
result.Y = Y;
result.accuracy = size(find(Y==Yt))/size(Yt);

要说明的是,上面的代码是实现的关于我们样本只有2个属性的情况;当我们的样本用多个属性时,我们需要修改部分代码即可。

 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

学习支持向量机SVM及其代码



    先简要说一下支持向量机(support vector machine, SVM)吧。感知机(perceptron)是二分类的线性模型,但是由于不同初值或选取不同的样本顺序,解是不同的,也就是不唯一的。在此基础上svm引入间隔最大化(margin maximization)不仅是样本更容易分开,而且解是唯一的。之后,为了容忍奇异点(outlier)引入松弛变量(slack variable)(注:引入松弛变量之后w依然是唯一的,但是b不是唯一的)。但是并不是所有问题都是线性的,所以用kernel track变成非线性模型。
     在求解SVM的时候一般都用其对偶形式,主要有两个优点,其一提供了一种方便的方法去解决约束问题,其二对偶问题中的点积能够很好地处理kernel function。而这个对偶函数又是一个二次规划问题。所以我们可以说求解SVM的本质就是在再生核希尔伯特空间(RKHS)上的二次优化问题。
     如果你想详细了解,我建议看《支持向量机——理论、算法与拓展》邓乃扬 田英杰著。
     这篇博文的主要是目的是把svm的matlab代码贴出来,供大家学习,代码有一部分是在网上找的一部分是我写的,解二次规划是用matlab的自带函数。把下面的代码直接复制就可运行,能够提高你对svm的理解。运行以下程序就能得到上面的图。
 
%主函数
clear all;
close all;
C = 10;
kertype = \'linear\';
%训练样本
n = 50;
randn(\'state\',6);
x1 = randn(2,n);    %2行N列矩阵
y1 = ones(1,n);       %1*N个1
x2 = 5+randn(2,n);   %2*N矩阵
y2 = -ones(1,n);      %1*N个-1
 
figure;
plot(x1(1,:),x1(2,:),\'bx\',x2(1,:),x2(2,:),\'k.\'); 
axis([-3 8 -3 8]);
hold on;
 
X = [x1,x2];        %训练样本d*n矩阵,n为样本个数,d为特征向量个数
Y = [y1,y2];        %训练目标1*n矩阵,n为样本个数,值为+1或-1
svm = svmTrain(X,Y,kertype,C);
plot(svm.Xsv(1,:),svm.Xsv(2,:),\'ro\');
 
%测试
[x1,x2] = meshgrid(-2:0.05:7,-2:0.05:7);  %x1和x2都是181*181的矩阵
[rows,cols] = size(x1);  
nt = rows*cols;                  
Xt = [reshape(x1,1,nt);reshape(x2,1,nt)];
Yt = ones(1,nt);
result = svmTest(svm, Xt, Yt, kertype);
 
Yd = reshape(result.Y,rows,cols);
contour(x1,x2,Yd,\'m\');
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function svm = svmTrain(X,Y,kertype,C)
 
options = optimset;    % Options是用来控制算法的选项参数的向量
options.LargeScale = \'off\';
options.Display = \'off\';
 
n = length(Y);
H = (Y\'*Y).*kernel(X,X,kertype);
f = -ones(n,1); %f为1*n个-1,f相当于Quadprog函数中的c
A = [];
b = [];
Aeq = Y; %相当于Quadprog函数中的A1,b1
beq = 0;
lb = zeros(n,1); %相当于Quadprog函数中的LB,UB
ub = C*ones(n,1);
a0 = zeros(n,1);  % a0是解的初始近似值
[a,fval,eXitflag,output,lambda]  = quadprog(H,f,A,b,Aeq,beq,lb,ub,a0,options);
 
epsilon = 1e-8;                     
sv_label = find(abs(a)>epsilon);  %0<a<a(max)则认为x为支持向量     
svm.a = a(sv_label);
svm.Xsv = X(:,sv_label);
svm.Ysv = Y(sv_label);
svm.svnum = length(sv_label);
%svm.label = sv_label;
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function result = svmTest(svm, Xt, Yt, kertype)
temp = (svm.a\'.*svm.Ysv)*kernel(svm.Xsv,svm.Xsv,kertype);
total_b = svm.Ysv-temp;
b = mean(total_b);
w = (svm.a\'.*svm.Ysv)*kernel(svm.Xsv,Xt,kertype);
result.score = w + b;
Y = sign(w+b);
result.Y = Y;
result.accuracy = size(find(Y==Yt))/size(Yt);
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function K = kernel(X,Y,type)
%X 维数*个数
switch type
case \'linear\'
    K = X\'*Y;
case \'rbf\'
    delta = 5;
    delta = delta*delta;
    XX = sum(X\'.*X\',2);
    YY = sum(Y\'.*Y\',2);
    XY = X\'*Y;
    K = abs(repmat(XX,[1 size(YY,1)]) + repmat(YY\',[size(XX,1) 1]) - 2*XY);
    K = exp(-K./delta);
end

 

第八讲. 支持向量机进行机器学习——Support Vector Machine

 

===============================

(一)、SVM 的 Cost Function

(二)、SVM —— Large Margin Classifier

(三)、数学角度解析为什么SVM 能形成 Large Margin Classifier(选看)

(四)、SVM Kernel 1 —— Gaussian Kernel

(五)、SVM 中 Gaussian Kernel 的使用

(六)、SVM的使用与选择

 

 

本章内容为支持向量机Support Vector Machine(SVM)的导论性讲解,在一般机器学习模型的理解上,引入SVM的概念。原先很多人,也包括我自己觉得SVM是个很神奇的概念,读完本文你会觉得,其实只是拥有不同的目标函数, 不同的模型而已,Machine Learning的本质还没有变,呵呵~

完成本文花了我很长时间,为了搞懂后面还有程序方便和参考网站大家实验,希望对大家有所帮助。

 

 

 

=====================================

(一)、SVM 的 Cost Function

 

前面的几章中我们分别就linear regressionlogistic regression以及神经网络的cost function进行了讲解。这里我们通过logistic regression的cost function引入SVM。

首先回忆一下logistic regression的模型:

 

还是原先的假设,suppose我们只有两个类,y=0和y=1。那么根据上图h(x)的图形我们可以看出,

当y=1时,希望h(x)≈1,即z>>0;

当y=0时,希望h(x)≈0,即z<<0;

那么逻辑回归的cost function公式如下:

cost function我们之前已经讲过了,这里不予赘述。现在呢,我们来看看下面的两幅图,这两幅图中灰色的curve是logistic regression的cost function分别取y=1和y=0的情况,

y=1时,随着z↑,h(x)逐渐逼近1,cost逐渐减小。

y=0时,随着z↓,h(x)逐渐逼近0,cost逐渐减小。

这正是图中灰色曲线所示的曲线。

ok,现在我们来看看SVM中cost function的定义。请看下图中玫瑰色的曲线,这就是我们希望得到的cost function曲线,和logistic regression的cost function非常相近,但是分为两部分,下面呢,我们将对这个cost function进行详细讲解。

logistic regression的cost function:

现在呢,我们给出SVM的目标函数(cost function)定义:

该式中,cost0和cost1分别对应y=0和y=1时的目标函数定义,最后一项regularization项和logistic regression中的类似。感觉系数少了什么?是的,其实它们的最后一项本来是一样的,但是可以通过线性变换化简得到SVM的归一化项。

 

 

 

 

 

=====================================

(二)、SVM —— Large Margin Classifier

 

本节给出一个简单的结论——SVM是一个large margin classifier。什么是margin呢?下面我们做详细讲解,其理论证明将在下一节中给出。

 

在引入margin之前,我们回顾一下上一节中的SVM cost function curve,如下图所示分别是y取1和0时的情况。先给出一个结论,常数C取一个很大的值比较好(比如100000),这是为什么呢?

我们来看哈,C很大,就要求[]中的那部分很小(令[]中的那部分表示为W),不如令其为0,这时来分析里面的式子:

※需求1:

y=1时,W只有前一项,令W=0,就要求Cost1Tx)=0,由右图可知,这要求θTx>=1;

y=0时,W只有后一项,令W=0,就要求Cost0Tx)=0,由右图可知,这要求θTx<=-1;

 

由以上说明可知,对C的取值应该在分类是否犯错和margin的大小上做一个平衡。那么C取较大的值会带来什么效果呢?就是我们开头说的结论——SVM是一个large margin classifier。那么什么是margin?在第三章中我们已经讲过了decision boundary,它是能够将所有数据点进行很好地分类的h(x)边界。如下图所示,我们可以把绿线、粉线、蓝线或者黑线中的任意一条线当做decision boundary,但是哪一条最好呢?这里我们可以看出,绿色、粉色、蓝色这三类boundary离数据非常近,i.e.我们再加进去几个数据点,很有可能这个boundary就能很好的进行分类了,而黑色的decision boundary距离两个类都相对较远,我们希望获得的就是这样的一个decision boundary。margin呢,就是将该boundary进行平移所得到的两条蓝线的距离,如图中所指。

相对比:

C小,decision boundary则呈现为黑线;若C很大,就呈现粉线;

这个结论大家可以记住,也可以进行数学上的分析,下一节中我们将从数学角度分析,为什么SVM选用大valeu的C会形成一个large margin classifier。


再给出一个数学上对geometry margin的说明:

任意一个点x到分类平面的距离γ的表示如上图所示,其中y是{+1,-1}表示分类结果,x0是分类面上距x最短的点,分类平面的方程为wx+b=0,将x0带入该方程就有上面的结果了。对于一个数据集x,margin就是这个数据及所有点的margin中离hyperplane最近的距离,SVM的目的就是找到最大margin的hyperplane。

 

 

练习:

 

 

 

 

 

 

=====================================

(三)、数学角度解析为什么SVM 能形成 Large Margin Classifier(选看)

 

这一节主要为了证明上一节中的结论,为什么SVM是Large Margin Classification,能形成很好的decision boundary,如果仅仅处于应用角度考虑的朋友可以略过此节。

首先我们来看两个向量内积的表现形式。假设向量uv均为二维向量我们知道u,v的内积uTv=u1v1+u2v2。表现在坐标上呢,就如下图左边所示:

首先将v投影至u向量,记其长度为p(有正负,与u同向为正,反相为负,标量),则两向量的内积uTv = ||u|| · ||v|| · cosθ = ||u|| · p = u1v1+u2v2。

 

 

这样一来,我们来看SVM的cost function:

由于将C设的很大,cost function只剩下后面的那项。采取简化形式,意在说明问题即可,设θ0=0,只剩下θ1和θ2

则cost function J(θ)=1/2×||θ||^2

 


而根据上面的推导,有θTx=p·||θ||,其中p是x在θ上的投影,则

※需求2:

y=1时,W只有前一项,令W=0,就要求Cost1Tx)=0,由右图可知,这要求p·||θ||>=1;

 

y=0时,W只有后一项,令W=0,就要求Cost0Tx)=0,由右图可知,这要求p·||θ||<=-1;

如下图所示:

 

 

我们集中精力看为什么SVM的decision boundary有large margin(这里稍微有点儿复杂,好好看哈):

对于一个给定数据集,依旧用X表示正样本,O表示负样本,绿色的线表示decision boundary,蓝色的线表示θ向量的方向,玫瑰色表示数据在θ上的投影。

我们已知boundary的角度和θ向量呈的是90°角(自己画一下就知道了)。

先看这个图,对于这样一个decision boundary(没有large margin),θ与其呈90°角如图所示,这样我们可以画出数据集X和O在θ上的投影,如图所示,非常小;如果想满足[需求2]中说的

对正样本p·||θ||>=1,

对负样本p·||θ||<=-1,

就需要令||θ||很大,这就和cost function的愿望(min 1/2×||θ||^2)相违背了,因此SVM的不出来这个图中所示的decision boundary结果。

 

那么再来看下面这个图,

它选取了上一节中我们定义的“比较好的”decision boundary,两边的margin都比较大。看一下两边数据到θ的投影,都比较大,这样就可以使||θ||相对较小,满足SVM的cost function。因此按照SVM的cost function进行求解(optimization)得出的decision boundary一定是有large margin的。说明白了吧?!

练习:

分析:由图中我们可以看出,decision boundary的最优解是y=x1,这时所有数据集中的数据到θ上的投影最小值为2,换言之,想满足

 

对正样本p·||θ||>=1,

对负样本p·||θ||<=-1,

只需要

对正样本2·||θ||>=1,

对负样本(-2)·||θ||<=-1,

因此需要||θ||>=1/2,本着令cost function最小的原则,我们可知||θ||=1/2.

 

 

 

 

 

=====================================

(四)、SVM Kernel 1 —— Gaussian Kernel

 

对于一个非线性Decision boundary,我们之前利用多项式拟合的方法进行预测:

  • f1, f2, ... fn为提取出来的features。
  • 定义预测方程hθ(x)为多项式的sigmod函数值:hθ(x)=g(θ0f01f1+…+θnfn),其中fn为x的幂次项组合(如下图)
  • 当θ0f01f1+…+θnfn>=0时hθ(x)=1;else hθ(x)=0;

那么,除了将fn定义为x的幂次项组合,还有没有其他方法表示 f 呢?本节就引入了Kernel,核的概念。即用核函数表示f。

对于上图的非线性拟合,我们通过计算输入原始向量与landmark之间的相似度来计算核值f:

发现相似度计算公式很像正态分布(高斯分布)对不对?是的!这就是高斯核函数。由下图可以看出,

x和l越相似,f越接近于1;

x与l相差越远,f越接近于0;

下图中的横纵坐标为x的两个维度值,高为f(new feature)。制高点为x=l的情况,此时f=1。

随着x与l的远离,f逐渐下降,趋近于0.

 

下面我们来看SVM核分类预测的结果:

引入核函数后,代数上的区别在于f变了,原来f是x1/x1^2/...,即xi幂次项乘积

引入核函数后,几何上来说可以更直观的表示是否应该归为该类了(如下图)

  • 比如我们想将坐标上的所有数据点分为两类(如下图中)红色圈内希望预测为y=1;圈外希望预测为y=0。通过训练数据集呢,我们得到了一组θ值(θ0,θ1,θ2,θ3)=(-0.5,1,1,0)以及三个点(L1,L2,L3),(具体怎么训练而成的大家先不要过分纠结,后面会讲)
  • 对于每个test数据集中的点,我们首先计算它到(L1,L2,L3)各自的相似度,也就是核函数的值(f1,f2,f3),然后带入多项式θ0f01f1+…+θnfn计算,当它>=0时,预测结果为类内点(正样本,y=1),else预测为负样本,y=0

 

 

 

 

 

 

 

 

=====================================

(五)、SVM 中 Gaussian Kernel 的使用

 

§5.1.    landmark的选取和参数向量θ的求解

 

上一节中我们遗留了两个问题,一个是一些L点的选取,一个是向量θ计算。这一节我们就来讲讲这两个问题。

首先来看L的选取。上一节中一提到Gaussian kernel fi 的计算:

这里呢,我们选择m个训练数据,并取这m个训练数据为m个landmark(L)点(不考虑证样本还是负样本),如下图所示:

 

PS:那么在这m个训练数据中,每一个训练数据x(i)所得的特征向量(核函数)f中,总有一维向量的值为1(因为这里x(i)=l(i))

于是,每个特征向量f有m+1维(m维训练数据[f1,f2,...,fm]附加一维f0=1)

在SVM的训练中,将Gaussian Kernel带入cost function,通过最小化该函数就可与得到参数θ,并根据该参数θ进行预测:

θTf>=0,predicty=1;

else predict y=0;

如下图所示,这里与之前讲过的cost function的区别在于用kernel f 代替了x。

 

 

 

§5.2.    landmark的选取和参数向量θ的求解

 

好了,至此Landmark点和θ的求取都解决了,还有一个问题,就是cost function中两个参数的确定:C和σ2

 

对于C,由于C=1/λ,所以

C大,λ小,overfit,产生low bias,high variance

C小,λ大,underfit,产生high bias,low variance

详细原因请参考第六章中关于bias和variance的讲解。

 

对于方差σ2,和正态分布中的定义一样,

σ2大,x-f 图像较为扁平;

σ2小,x-f 图像较为窄尖;

 

关于C和σ2的选取,我们来做个练习:

 

 

解析,过拟合说明应该适当加强cost function中的正则项所起的作用,因此应增大λ,即减小C;同时,过拟合是的只有一小部分范围内的x享有较大f,或者说x的覆盖面太窄了,所以应当增大σ2

 

 

 

 

 

 

=====================================

(六)、SVM 的 使用与选择

 

本节中主要介绍SVM在matlab中用libsvm中的应用,给大家一个用SVM进行实践的平台。

 

前面几节中我们已知用SVM进行机器学习的过程就是一个optimize参数θ的过程,这里呢,我们首先介绍一个 Chih-Chung Chang 和 Chih-Jen Lin 做的 matlab/C/Ruby/Python/Java...中通用的机器学习tool,libsvm,其基本讲解和测试我以前讲过(在这里),算是入门篇,并不详细,这里呢,我们将结合本章课程近一步学习,并用matlab实现。

 

首先大家来看看,想要进行SVM学习,有哪两类:

 

一种是No kernel(linear kernel),hθ(x)=g(θ0x01x1+…+θnxn),predict y=1 if θTx>=0;

另一种是使用kernel f(比如Gaussian Kernel),hθ(x)=g(θ0f01f1+…+θnfn),这里需要选择方差参数σ2

如下图所示:

 

需要注意的是,不管用那种方法,都需要在ML之前进行Normalization归一化!

当然,除了Gaussian kernel,我们还有很多其他的kernel可以用,比如polynomial kernel等,如下图所示,但andrew表示他本人不会经常去用(或者几乎不用)以下"more esoteric"中的核,一个原因是其他的核不一定起作用。我们讲一下polynomial kernel:

polynomial 核形如 K(x,l)= (xTl+c)d,也用来表示两个object的相似度

首先给大家引入一个数据集,在该数据集中,我们可以进行初步的libsvm训练和预测,如这篇文章中所说,这个也是最基本的no kernel(linear kernel)。

然后呢,给大家一个reference,这是libsvm中traing基本的语法:

 

 

[cpp] view plaincopy
 
  1. Usage: model = svmtrain(training_label_vector, training_instance_matrix, \'libsvm_options\');  
  2. libsvm_options:  
  3. -s svm_type : set type of SVM (default 0)  
  4.     0 -- C-SVC  
  5.     1 -- nu-SVC  
  6.     2 -- one-class SVM  
  7.     3 -- epsilon-SVR  
  8.     4 -- nu-SVR  
  9. -t kernel_type : set type of kernel function (default 2)  
  10.     0 -- linear: u\'*v  
  11.     1 -- polynomial: (gamma*u\'*v + coef0)^degree  
  12.     2 -- radial basis function: exp(-gamma*|u-v|^2)  
  13.     3 -- sigmoid: tanh(gamma*u\'*v + coef0)  
  14.     4 -- precomputed kernel (kernel values in training_instance_matrix)  
  15. -d degree : set degree in kernel function (default 3)  
  16. -g gamma : set gamma in kernel function (default 1/num_features)  
  17. -r coef0 : set coef0 in kernel function (default 0)  
  18. -c cost : set the parameter C of C-SVC, epsilon-SVR, and nu-SVR (default 1)  
  19. -n nu : set the parameter nu of nu-SVC, one-class SVM, and nu-SVR (default 0.5)  
  20. -p epsilon : set the epsilon in loss function of epsilon-SVR (default 0.1)  
  21. -m cachesize : set cache memory size in MB (default 100)  
  22. -e epsilon : set tolerance of termination criterion (default 0.001)  
  23. -h shrinking : whether to use the shrinking heuristics, 0 or 1 (default 1)  
  24. -b probability_estimates : whether to train a SVC or SVR model for probability estimates, 0 or 1 (default 0)  
  25. -wi weight : set the parameter C of class i to weight*C, for C-SVC (default 1)  
  26. -v n : n-fold cross validation mode  
  27. -q : quiet mode (no outputs)  


下面给大家一个例子:

 

 

[cpp] view plaincopy
 
  1. function [ output_args ] = Nonlinear_SVM( input_args )  
  2. %NONLINEAR_SVM Summary of this function goes here  
  3. %   Detailed explanation goes here  
  4.   
  5. %generate data1  
  6. r=sqrt(rand(100,1));%generate 100 random radius  
  7. t=2*pi*rand(100,1);%generate 100 random angles, in range [0,2*pi]  
  8. data1=[r.*cos(t),r.*sin(t)];%points  
  9.   
  10. %generate data2  
  11. r2=sqrt(3*rand(100,1)+1);%generate 100 random radius  
  12. t2=2*pi*rand(100,1);%generate 100 random angles, in range [0,2*pi]  
  13. data2=[r2.*cos(t2),r2.*sin(t2)];%points  
  14.   
  15. %plot datas  
  16.  plot(data1(:,1),data1(:,2),\'r.\')  
  17.  hold on  
  18. plot(data2(:,1),data2(:,2),\'b.\')  
  19. ezpolar(@(x)1);%在极坐标下画ρ=1,θ∈[0,2π]的图像,即x^2+y^2=1  
  20. ezpolar(@(x)2);  
  21. axis equal %make x and y axis with equal scalar  
  22. hold off  
  23.   
  24. %build a vector for classification  
  25. data=[data1;data2];     %merge the two dataset into one  
  26. datalabel=ones(200,1);  %label for the data  
  27. datalabel(1:100)=-1;  
  28.   
  29. %train with Non-linear SVM classifier use Gaussian Kernel  
  30.   
  31. model=svmtrain(datalabel,data,\'-c 100 -g 4\');   
  32.   
  33. end  



该例中我们分别生成了100个正样本和100个负样本,如下图所示,因为kernel type default=2(即Gaussian kernel),通过svmtrain(datalabel,data,\'-c 100 -g 4\')我们设置了第五节中奖的参数——C(c)和 2σ2(g)分别为100和4。

运行结果:

 

[cpp] view plaincopy
 
  1. >> Nonlinear_SVM  
  2. *  
  3. optimization finished, #iter = 149  
  4. nu = 0.015538  
  5. obj = -155.369263, rho = 0.634344  
  6. nSV = 33, nBSV = 0  
  7. Total nSV = 33  



 

 

最后,我们比较一下logistic regresion和 SVM:

用n表示feature个数,m表示training exampl个数。

 

①当n>=m,如n=10000,m=10~1000时,建议用logistic regression, 或者linear kernel的SVM

②如果n小,m不大不小,如n=1~1000,m=10~10000,建议用Gaussian Kernel的SVM

③如果n很小,m很大,如n=1~1000,m>50000,建议增加更多的feature并使用logistic regression, 或者linear kernel的SVM

原因,①模型简单即可解决,③如果还用Gaussian kernel会导致很慢,所以还选择logistic regression或者linear kernel

神经网络可以解决以上任何问题,但是速度是一个很大的问题。

 

详见下图:

 

 

 

我们可以把所有数据分为testset和training set两部分进行训练,example:

 

[cpp] view plaincopy
 
  1. load heart_scale  
  2. [N D] = size(heart_scale_inst);  
  3.   
  4. % Determine the train and test index,select top 200 as training data  
  5. else as test data  
  6. trainIndex = zeros(N,1); trainIndex(1:200) = 1;  
  7. testIndex = zeros(N,1); testIndex(201:N) = 1;  
  8. trainData = heart_scale_inst(trainIndex==1,:);  
  9. trainLabel = heart_scale_label(trainIndex==1,:);  
  10. testData = heart_scale_inst(testIndex==1,:);  
  11. testLabel = heart_scale_label(testIndex==1,:);  
  12.   
  13. % Train the SVM  
  14. model = svmtrain(trainLabel, trainData, \'-c 1 -g 0.07 -b 1\');  
  15. % Use the SVM model to classify the data  
  16. [predict_label, accuracy, prob_values] = svmpredict(testLabel, testData, model, \'-b 1\'); % run the SVM model on the test data  



运行结果:

 

[cpp] view plaincopy
 
    1. optimization finished, #iter = 87  
    2. nu = 0.426369  
    3. obj = -56.026822, rho = -0.051128  
    4. nSV = 77, nBSV = 62  
    5. Total nSV = 77  
    6. *  
    7. optimization finished, #iter = 99  
    8. nu = 0.486493  
    9. obj = -64.811759, rho = 0.328505  
    10. nSV = 87, nBSV = 68  
    11. Total nSV = 87  
    12. *  
    13. optimization finished, #iter = 101  
    14. nu = 0.490332  
    15. obj = -64.930603, rho = 0.424679  
    16. nSV = 87, nBSV = 67  
    17. Total nSV = 87  
    18. *  
    19. optimization finished, #iter = 121  
    20. nu = 0.483649  
    21. obj = -64.046644, rho = 0.423762  
    22. nSV = 87, nBSV = 65  
    23. Total nSV = 87  
    24. *  
    25. optimization finished, #iter = 93  
    26. nu = 0.470980  
    27. obj = -63.270339, rho = 0.458209  
    28. nSV = 83, nBSV = 67  
    29. Total nSV = 83  
    30. *  
    31. optimization finished, #iter = 137  
    32. nu = 0.457422  
    33. obj = -76.730867, rho = 0.435233  
    34. nSV = 104, nBSV = 81  
    35. Total nSV = 104  
    36. Accuracy = 81.4286% (57/70) (classification)  
    37. >>  

    38.  


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Delphi XE5 Lite v8.2 下载地址发布时间:2022-07-18
下一篇:
delphi获取可执行文件的当前路径发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap