精华内容
下载资源
问答
  • 题目:支持向量机非线性回归通用MATLAB源码支持向量机和BP神经网络都可以用来做非线性回归拟合,但它们的原理是不相同的,支持向量机基于结构风险最小化理论,普遍认为其泛化能力要比神经网络的强。GreenSim团队编写...

    题目:支持向量机非线性回归通用MATLAB源码支持向量机和BP神经网络都可以用来做非线性回归拟合,但它们的原理是不相同的,支持向量机基于结构风险最小化理论,普遍认为其泛化能力要比神经网络的强。GreenSim团队编写了支持向量机非线性回归的通用Matlab程序,并且和BP网络进行了比较,大量仿真结果证实,支持向量机的泛化能力强于BP网络,而且能避免神经网络的固有缺陷——训练结果不稳定。本源码可以用于线性回归、非线性回归、非线性函数拟合、数据建模、预测、分类等多种应用场合,由于接口规范,注释详细,非常好用,GreenSim团队推荐您使用。本源码已经删掉了关键的一些代码,一般人难以将其补充完整,有意购买此源码,请与GreenSim团队联系。function [Alpha1,Alpha2,Alpha,Flag,B]=SVMNR(X,Y,Epsilon,C,TKF,Para1,Para2)

    %%

    %  SVMNR.m

    %  Support Vector Machine for Nonlinear Regression

    %  All rights reserved

    %%

    %  支持向量机非线性回归通用程序

    %  GreenSim团队原创作品,转载请注明

    %  Email:greensim@163.com

    %  GreenSim团队主页:http://blog.sina.com.cn/greensim

    %  程序功能:

    %  使用支持向量机进行非线性回归,得到非线性函数y=f(x1,x2,…,xn)的支持向量解析式,

    %  求解二次规划时调用了优化工具箱的quadprog函数。本函数在程序入口处对数据进行了

    %  [-1,1]的归一化处理,所以计算得到的回归解析式的系数是针对归一化数据的,仿真测

    %  试需使用与本函数配套的Regression函数。

    %  主要参考文献:

    %  朱国强,刘士荣等.支持向量机及其在函数逼近中的应用.华东理工大学学报

    %  输入参数列表

    %  X        输入样本原始数据,n×l的矩阵,n为变量个数,l为样本个数

    %  Y        输出样本原始数据,1×l的矩阵,l为样本个数

    %  Epsilon   ε不敏感损失函数的参数,Epsilon越大,支持向量越少

    %  C        惩罚系数,C过大或过小,泛化能力变差

    %  TKF      Type of Kernel Function 核函数类型

    %  TKF=1    线性核函数,注意:使用线性核函数,将进行支持向量机的线性回归

    %  TKF=2    多项式核函数

    %  TKF=3    径向基核函数

    %  TKF=4    指数核函数

    %  TKF=5    Sigmoid核函数

    %  TKF=任意其它值,自定义核函数

    %  Para1    核函数中的第一个参数

    %  Para2    核函数中的第二个参数

    %  注:关于核函数参数的定义请见Regression.m和SVMNR.m内部的定义

    %  输出参数列表

    %  Alpha1   α系数

    %  Alpha2   α*系数

    %  Alpha    支持向量的加权系数(α-α*)向量

    %  Flag      1×l标记,0对应非支持向量,1对应边界支持向量,2对应标准支持向量

    %  B        回归方程中的常数项

    %--------------------------------------------------------------------------%%

    %-----------------------数据归一化处理--------------------------------------

    nntwarn off

    X=premnmx(X);

    Y=premnmx(Y);

    %%

    %%

    %-----------------------核函数参数初始化------------------------------------

    switch TKF

    case 1

    %线性核函数  K=sum(x.*y)

    %没有需要定义的参数

    case 2

    %多项式核函数  K=(sum(x.*y)+c)^p

    c=Para1;%c=0.1;

    p=Para2;%p=2;

    case 3

    %径向基核函数  K=exp(-(norm(x-y))^2/(2*sigma^2))

    sigma=Para1;%sigma=6;

    case 4

    %指数核函数  K=exp(-norm(x-y)/(2*sigma^2))

    sigma=Para1;%sigma=3;

    case 5

    %Sigmoid核函数  K=1/(1+exp(-v*sum(x.*y)+c))

    v=Para1;%v=0.5;

    c=Para2;%c=0;

    otherwise

    %自定义核函数,需由用户自行在函数内部修改,注意要同时修改好几处!

    %暂时定义为  K=exp(-(sum((x-y).^2)/(2*sigma^2)))

    sigma=Para1;%sigma=8;

    end

    %%

    %%

    %-----------------------构造K矩阵-------------------------------------------

    l=size(X,2);

    K=zeros(l,l);%K矩阵初始化

    for i=1:l

    for j=1:l

    x=X(:,i);

    y=X(:,j);

    switch TKF%根据核函数的类型,使用相应的核函数构造K矩阵

    case 1

    K(i,j)=sum(x.*y);

    case 2

    K(i,j)=(sum(x.*y)+c)^p;

    case 3

    K(i,j)=exp(-(norm(x-y))^2/(2*sigma^2));

    case 4

    K(i,j)=exp(-norm(x-y)/(2*sigma^2));

    case 5

    K(i,j)=1/(1+exp(-v*sum(x.*y)+c));

    otherwise

    K(i,j)=exp(-(sum((x-y).^2)/(2*sigma^2)));

    end

    end

    end

    %%

    %%

    %------------构造二次规划模型的参数H,Ft,Aeq,Beq,lb,ub------------------------

    %支持向量机非线性回归,回归函数的系数,要通过求解一个二次规划模型得以确定

    Ft=[Epsilon*ones(1,l)-Y,Epsilon*ones(1,l)+Y];

    Aeq=[ones(1,l),-ones(1,l)];

    Beq=0;

    ub=C*ones(2*l,1);

    %%

    %%

    %--------------调用优化工具箱quadprog函数求解二次规划------------------------

    OPT=optimset;

    OPT.LargeScale='off';

    OPT.Display='off';

    %%

    %%

    %------------------------整理输出回归方程的系数------------------------------

    Alpha1=(Gamma(1:l,1))';

    Alpha2=(Gamma((l+1):end,1))';

    Alpha=Alpha1-Alpha2;

    Flag=2*ones(1,l);

    %%

    %%

    %---------------------------支持向量的分类----------------------------------

    Err=0.000000000001;

    for i=1:l

    AA=Alpha1(i);

    BB=Alpha2(i);

    if (abs(AA-0)<=Err)&&(abs(BB-0)<=Err)

    Flag(i)=0;%非支持向量

    end

    if (AA>Err)&&(AA

    Flag(i)=2;%标准支持向量

    end

    if (abs(AA-0)<=Err)&&(BB>Err)&&(BB

    Flag(i)=2;%标准支持向量

    end

    if (abs(AA-C)<=Err)&&(abs(BB-0)<=Err)

    Flag(i)=1;%边界支持向量

    end

    if (abs(AA-0)<=Err)&&(abs(BB-C)<=Err)

    Flag(i)=1;%边界支持向量

    end

    end

    %%

    %%

    %--------------------计算回归方程中的常数项B---------------------------------

    B=0;

    counter=0;

    for i=1:l

    AA=Alpha1(i);

    BB=Alpha2(i);

    if (AA>Err)&&(AA

    %计算支持向量加权值

    SUM=0;

    for j=1:l

    if Flag(j)>0

    switch TKF

    case 1

    SUM=SUM+Alpha(j)*sum(X(:,j).*X(:,i));

    case 2

    SUM=SUM+Alpha(j)*(sum(X(:,j).*X(:,i))+c)^p;

    case 3

    SUM=SUM+Alpha(j)*exp(-(norm(X(:,j)-X(:,i)))^2/(2*sigma^2));

    case 4

    SUM=SUM+Alpha(j)*exp(-norm(X(:,j)-X(:,i))/(2*sigma^2));

    case 5

    SUM=SUM+Alpha(j)*1/(1+exp(-v*sum(X(:,j).*X(:,i))+c));

    otherwise

    SUM=SUM+Alpha(j)*exp(-(sum((X(:,j)-X(:,i)).^2)/(2*sigma^2)));

    end

    end

    end

    b=Y(i)-SUM-Epsilon;

    B=B+b;

    counter=counter+1;

    end

    if (abs(AA-0)<=Err)&&(BB>Err)&&(BB

    SUM=0;

    for j=1:l

    if Flag(j)>0

    switch TKF

    case 1

    SUM=SUM+Alpha(j)*sum(X(:,j).*X(:,i));

    case 2

    SUM=SUM+Alpha(j)*(sum(X(:,j).*X(:,i))+c)^p;

    case 3

    SUM=SUM+Alpha(j)*exp(-(norm(X(:,j)-X(:,i)))^2/(2*sigma^2));

    case 4

    SUM=SUM+Alpha(j)*exp(-norm(X(:,j)-X(:,i))/(2*sigma^2));

    case 5

    SUM=SUM+Alpha(j)*1/(1+exp(-v*sum(X(:,j).*X(:,i))+c));

    otherwise

    SUM=SUM+Alpha(j)*exp(-(sum((X(:,j)-X(:,i)).^2)/(2*sigma^2)));

    end

    end

    end

    b=Y(i)-SUM+Epsilon;

    B=B+b;

    counter=counter+1;

    end

    end

    if counter==0

    B=0;

    else

    B=B/counter;

    end欢迎访问GreenSim团队主页:http://blog.sina.com.cn/greensim  QQ:761222791

    展开全文
  • 本文介绍了python 支持向量机非线性回归SVR模型,废话不多说,具体如下:import numpy as npimport matplotlib.pyplot as pltfrom sklearn import datasets, linear_model,svmfrom sklearn.model_selection import ...

    本文介绍了python 支持向量机非线性回归SVR模型,废话不多说,具体如下:

    import numpy as np

    import matplotlib.pyplot as plt

    from sklearn import datasets, linear_model,svm

    from sklearn.model_selection import train_test_split

    def load_data_regression():

    '''

    加载用于回归问题的数据集

    '''

    diabetes = datasets.load_diabetes() #使用 scikit-learn 自带的一个糖尿病病人的数据集

    # 拆分成训练集和测试集,测试集大小为原始数据集大小的 1/4

    return train_test_split(diabetes.data,diabetes.target,test_size=0.25,random_state=0)

    #支持向量机非线性回归SVR模型

    def test_SVR_linear(*data):

    X_train,X_test,y_train,y_test=data

    regr=svm.SVR(kernel='linear')

    regr.fit(X_train,y_train)

    print('Coefficients:%s, intercept %s'%(regr.coef_,regr.intercept_))

    print('Score: %.2f' % regr.score(X_test, y_test))

    # 生成用于回归问题的数据集

    X_train,X_test,y_train,y_test=load_data_regression()

    # 调用 test_LinearSVR

    test_SVR_linear(X_train,X_test,y_train,y_test)

    def test_SVR_poly(*data):

    '''

    测试 多项式核的 SVR 的预测性能随 degree、gamma、coef0 的影响.

    '''

    X_train,X_test,y_train,y_test=data

    fig=plt.figure()

    ### 测试 degree ####

    degrees=range(1,20)

    train_scores=[]

    test_scores=[]

    for degree in degrees:

    regr=svm.SVR(kernel='poly',degree=degree,coef0=1)

    regr.fit(X_train,y_train)

    train_scores.append(regr.score(X_train,y_train))

    test_scores.append(regr.score(X_test, y_test))

    ax=fig.add_subplot(1,3,1)

    ax.plot(degrees,train_scores,label="Training score ",marker='+' )

    ax.plot(degrees,test_scores,label= " Testing score ",marker='o' )

    ax.set_title( "SVR_poly_degree r=1")

    ax.set_xlabel("p")

    ax.set_ylabel("score")

    ax.set_ylim(-1,1.)

    ax.legend(loc="best",framealpha=0.5)

    ### 测试 gamma,固定 degree为3, coef0 为 1 ####

    gammas=range(1,40)

    train_scores=[]

    test_scores=[]

    for gamma in gammas:

    regr=svm.SVR(kernel='poly',gamma=gamma,degree=3,coef0=1)

    regr.fit(X_train,y_train)

    train_scores.append(regr.score(X_train,y_train))

    test_scores.append(regr.score(X_test, y_test))

    ax=fig.add_subplot(1,3,2)

    ax.plot(gammas,train_scores,label="Training score ",marker='+' )

    ax.plot(gammas,test_scores,label= " Testing score ",marker='o' )

    ax.set_title( "SVR_poly_gamma r=1")

    ax.set_xlabel(r"$\gamma$")

    ax.set_ylabel("score")

    ax.set_ylim(-1,1)

    ax.legend(loc="best",framealpha=0.5)

    ### 测试 r,固定 gamma 为 20,degree为 3 ######

    rs=range(0,20)

    train_scores=[]

    test_scores=[]

    for r in rs:

    regr=svm.SVR(kernel='poly',gamma=20,degree=3,coef0=r)

    regr.fit(X_train,y_train)

    train_scores.append(regr.score(X_train,y_train))

    test_scores.append(regr.score(X_test, y_test))

    ax=fig.add_subplot(1,3,3)

    ax.plot(rs,train_scores,label="Training score ",marker='+' )

    ax.plot(rs,test_scores,label= " Testing score ",marker='o' )

    ax.set_title( "SVR_poly_r gamma=20 degree=3")

    ax.set_xlabel(r"r")

    ax.set_ylabel("score")

    ax.set_ylim(-1,1.)

    ax.legend(loc="best",framealpha=0.5)

    plt.show()

    # 调用 test_SVR_poly

    test_SVR_poly(X_train,X_test,y_train,y_test)

    def test_SVR_rbf(*data):

    '''

    测试 高斯核的 SVR 的预测性能随 gamma 参数的影响

    '''

    X_train,X_test,y_train,y_test=data

    gammas=range(1,20)

    train_scores=[]

    test_scores=[]

    for gamma in gammas:

    regr=svm.SVR(kernel='rbf',gamma=gamma)

    regr.fit(X_train,y_train)

    train_scores.append(regr.score(X_train,y_train))

    test_scores.append(regr.score(X_test, y_test))

    fig=plt.figure()

    ax=fig.add_subplot(1,1,1)

    ax.plot(gammas,train_scores,label="Training score ",marker='+' )

    ax.plot(gammas,test_scores,label= " Testing score ",marker='o' )

    ax.set_title( "SVR_rbf")

    ax.set_xlabel(r"$\gamma$")

    ax.set_ylabel("score")

    ax.set_ylim(-1,1)

    ax.legend(loc="best",framealpha=0.5)

    plt.show()

    # 调用 test_SVR_rbf

    test_SVR_rbf(X_train,X_test,y_train,y_test)

    def test_SVR_sigmoid(*data):

    '''

    测试 sigmoid 核的 SVR 的预测性能随 gamma、coef0 的影响.

    '''

    X_train,X_test,y_train,y_test=data

    fig=plt.figure()

    ### 测试 gammam,固定 coef0 为 0.01 ####

    gammas=np.logspace(-1,3)

    train_scores=[]

    test_scores=[]

    for gamma in gammas:

    regr=svm.SVR(kernel='sigmoid',gamma=gamma,coef0=0.01)

    regr.fit(X_train,y_train)

    train_scores.append(regr.score(X_train,y_train))

    test_scores.append(regr.score(X_test, y_test))

    ax=fig.add_subplot(1,2,1)

    ax.plot(gammas,train_scores,label="Training score ",marker='+' )

    ax.plot(gammas,test_scores,label= " Testing score ",marker='o' )

    ax.set_title( "SVR_sigmoid_gamma r=0.01")

    ax.set_xscale("log")

    ax.set_xlabel(r"$\gamma$")

    ax.set_ylabel("score")

    ax.set_ylim(-1,1)

    ax.legend(loc="best",framealpha=0.5)

    ### 测试 r ,固定 gamma 为 10 ######

    rs=np.linspace(0,5)

    train_scores=[]

    test_scores=[]

    for r in rs:

    regr=svm.SVR(kernel='sigmoid',coef0=r,gamma=10)

    regr.fit(X_train,y_train)

    train_scores.append(regr.score(X_train,y_train))

    test_scores.append(regr.score(X_test, y_test))

    ax=fig.add_subplot(1,2,2)

    ax.plot(rs,train_scores,label="Training score ",marker='+' )

    ax.plot(rs,test_scores,label= " Testing score ",marker='o' )

    ax.set_title( "SVR_sigmoid_r gamma=10")

    ax.set_xlabel(r"r")

    ax.set_ylabel("score")

    ax.set_ylim(-1,1)

    ax.legend(loc="best",framealpha=0.5)

    plt.show()

    # 调用 test_SVR_sigmoid

    test_SVR_sigmoid(X_train,X_test,y_train,y_test)

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

    时间: 2019-06-23

    展开全文
  • SVM的英文全称是Support Vector Machines,我们叫它支持向量机支持向量机是我们用于分类的一种算法。让我们以一个小故事的形式,开启我们的SVM之旅吧。 在很久以前的情人节,一位大侠要去救他的爱人,但天空中的...

    一、什么是SVM?

    SVM的英文全称是Support Vector Machines,我们叫它支持向量机。支持向量机是我们用于分类的一种算法。让我们以一个小故事的形式,开启我们的SVM之旅吧。

    在很久以前的情人节,一位大侠要去救他的爱人,但天空中的魔鬼和他玩了一个游戏。

    魔鬼在桌子上似乎有规律放了两种颜色的球,说:“你用一根棍分开它们?要求:尽量在放更多球之后,仍然适用。”

    img

    于是大侠这样放,干的不错?

    img

    然后魔鬼,又在桌上放了更多的球,似乎有一个球站错了阵营。显然,大侠需要对棍做出调整。

    img

    SVM就是试图把棍在最佳位置,好让在棍的两边有尽可能大的间隙。这个间隙就是球到棍的距离。

    img

    现在好了,即使魔鬼放了更多的球,棍仍然是一个好的分界线。

    img

    魔鬼看到大侠已经学会了一个trick(方法、招式),于是魔鬼给了大侠一个新的挑战。

    img

    现在,大侠没有棍可以很好帮他分开两种球了,现在怎么办呢?当然像所有武侠片中一样大侠桌子一拍,球飞到空中。然后,凭借大侠的轻功,大侠抓起一张纸,插到了两种球的中间。

    img

    现在,从空中的魔鬼的角度看这些球,这些球看起来像是被一条曲线分开了。

    img

    再之后,无聊的大人们,把这些球叫做data,把棍子叫做classifier, 找到最大间隙的trick叫做optimization,拍桌子叫做kernelling, 那张纸叫做hyperplane

    概述一下:

    当一个分类问题,数据是线性可分的,也就是用一根棍就可以将两种小球分开的时候,我们只要将棍的位置放在让小球距离棍的距离最大化的位置即可,寻找这个最大间隔的过程,就叫做最优化。但是,现实往往是很残酷的,一般的数据是线性不可分的,也就是找不到一个棍将两种小球很好的分类。这个时候,我们就需要像大侠一样,将小球拍起,用一张纸代替小棍将小球进行分类。想要让数据飞起,我们需要的东西就是核函数(kernel),用于切分小球的纸,就是超平面。

    也许这个时候,你还是似懂非懂,没关系。根据刚才的描述,可以看出,问题是从线性可分延伸到线性不可分的。那么,我们就按照这个思路,进行原理性的剖析。

    二、线性SVM

    先看下线性可分的二分类问题。

    img

    上图中的(a)是已有的数据,红色和蓝色分别代表两个不同的类别。数据显然是线性可分的,但是将两类数据点分开的直线显然不止一条。上图的(b)和©分别给出了B、C两种不同的分类方案,其中黑色实线为分界线,术语称为“决策面”。每个决策面对应了一个线性分类器。虽然从分类结果上看,分类器A和分类器B的效果是相同的。但是他们的性能是有差距的,看下图:

    img

    在"决策面"不变的情况下,我又添加了一个红点。可以看到,分类器B依然能很好的分类结果,而分类器C则出现了分类错误。显然分类器B的"决策面"放置的位置优于分类器C的"决策面"放置的位置,SVM算法也是这么认为的,它的依据就是分类器B的分类间隔比分类器C的分类间隔大。

    这里涉及到第一个SVM独有的概念"分类间隔"。在保证决策面方向不变且不会出现错分样本的情况下移动决策面,会在原来的决策面两侧找到两个极限位置(越过该位置就会产生错分现象),如虚线所示。虚线的位置由决策面的方向和距离原决策面最近的几个样本的位置决定。而这两条平行虚线正中间的分界线就是在保持当前决策面方向不变的前提下的最优决策面。

    两条虚线之间的垂直距离就是这个最优决策面对应的分类间隔。显然每一个可能把数据集正确分开的方向都有一个最优决策面(有些方向无论如何移动决策面的位置也不可能将两类样本完全分开),而不同方向的最优决策面的分类间隔通常是不同的,那个具有“最大间隔”的决策面就是SVM要寻找的最优解。

    而这个真正的最优解对应的两侧虚线所穿过的样本点,就是SVM中的支持样本点,称为"支持向量"。

    数学建模

    求解这个"决策面"的过程,就是最优化。一个最优化问题通常有两个基本的因素:

    1)目标函数,也就是你希望什么东西的什么指标达到最好;

    2)优化对象,你期望通过改变哪些因素来使你的目标函数达到最优。

    在线性SVM算法中,目标函数显然就是那个"分类间隔",而优化对象则是决策面。所以要对SVM问题进行数学建模,首先要对上述两个对象(“分类间隔"和"决策面”)进行数学描述。按照一般的思维习惯,我们先描述决策面。

    数学建模的时候,先在二维空间建模,然后再推广到多维。

    (1)"决策面"方程

    我们都知道二维空间下一条直线的方式如下所示:

    img

    现在我们做个小小的改变,让原来的x轴变成x1,y轴变成x2。

    img

    移项得:

    img

    将公式向量化得:

    img

    进一步向量化,用w列向量和x列向量和标量γ进一步向量化:

    img

    其中,向量w和x分别为:

    img

    这里w1=a,w2=-1。我们都知道,最初的那个直线方程a和b的几何意义,a表示直线的斜率,b表示截距,a决定了直线与x轴正方向的夹角,b决定了直线与y轴交点位置。那么向量化后的直线的w和r的几何意义是什么呢?

    现在假设:

    img

    可得:

    img

    在坐标轴上画出直线和向量w:

    img

    蓝色的线代表向量w,红色的先代表直线y。我们可以看到向量w和直线的关系为垂直关系。这说明了向量w也控制这直线的方向,只不过是与这个直线的方向是垂直的。标量γ的作用也没有变,依然决定了直线的截距。此时,我们称w为直线的法向量。

    二维空间的直线方程已经推导完成,将其推广到n为空间,就变成了超平面方程。(一个超平面,在二维空间的例子就是一个直线)但是它的公式没变,依然是:

    img

    不同之处在于:

    img

    我们已经顺利推导出了"决策面"方程,它就是我们的超平面方程,之后,我们统称其为超平面方程。

    (2)"分类间隔"方程

    现在,我们依然对于一个二维平面的简单例子进行推导。

    img

    我们已经知道间隔的大小实际上就是支持向量对应的样本点到决策面的距离的二倍。那么图中的距离d我们怎么求?我们高中都学过,点到直线的距离距离公式如下:

    img

    公式中的直线方程为Ax0+By0+C=0,点P的坐标为(x0,y0)。

    现在,将直线方程扩展到多维,求得我们现在的超平面方程,对公式进行如下变形:

    img

    这个d就是"分类间隔"。其中||w||表示w的二范数,求所有元素的平方和,然后再开方。比如对于二维平面:

    img

    那么,

    img

    我们目的是为了找出一个分类效果好的超平面作为分类器。分类器的好坏的评定依据是分类间隔W=2d的大小,即分类间隔W越大,我们认为这个超平面的分类效果越好。此时,求解超平面的问题就变成了求解分类间隔W最大化的为题。W的最大化也就是d最大化的。

    (3)约束条件

    看起来,我们已经顺利获得了目标函数的数学形式。但是为了求解w的最大值。我们不得不面对如下问题:

    • 我们如何判断超平面是否将样本点正确分类?
    • 我们知道相求距离d的最大值,我们首先需要找到支持向量上的点,怎么在众多的点中选出支持向量上的点呢?

    上述我们需要面对的问题就是约束条件,也就是说我们优化的变量d的取值范围受到了限制和约束。事实上约束条件一直是最优化问题里最让人头疼的东西。但既然我们已经知道了这些约束条件确实存在,就不得不用数学语言对他们进行描述。但SVM算法通过一些巧妙的小技巧,将这些约束条件融合到一个不等式里面。

    这个二维平面上有两种点,我们分别对它们进行标记:

    • 红颜色的圆点标记为1,我们人为规定其为正样本;
    • 蓝颜色的五角星标记为-1,我们人为规定其为负样本。

    对每个样本点xi加上一个类别标签yi:

    img

    如果我们的超平面方程能够完全正确地对上图的样本点进行分类,就会满足下面的方程:

    img

    如果我们要求再高一点,假设决策面正好处于间隔区域的中轴线上,并且相应的支持向量对应的样本点到决策面的距离为d,那么公式进一步写成:

    img

    上述公式的解释就是,对于所有分类标签为1的样本点,它们到直线的距离都大于等于d(支持向量上的样本点到超平面的距离)。对于所有分类标签为-1的样本点,它们到直线的距离都小于等于d。公式两边都除以d,就可以得到:

    img

    其中,

    img

    因为||w||和d都是标量。所上述公式的两个矢量,依然描述一条直线的法向量和截距。

    img

    上述两个公式,都是描述一条直线,数学模型代表的意义是一样的。

    现在,让我们对wd和γd重新起个名字,就叫它们w和γ。

    因此,我们就可以说:“对于存在分类间隔的两类样本点,我们一定可以找到一些超平面面,使其对于所有的样本点均满足下面的条件:”

    img

    上述方程即给出了SVM最优化问题的约束条件。这时候,可能有人会问了,为什么标记为1和-1呢?因为这样标记方便我们将上述方程变成如下形式:

    img

    正是因为标签为1和-1,才方便我们将约束条件变成一个约束方程,从而方便我们的计算。

    (4)线性SVM优化问题基本描述

    现在整合一下思路,我们已经得到我们的目标函数:

    img

    我们的优化目标是是d最大化。我们已经说过,我们是用支持向量上的样本点(决策面线上的点)求解d的最大化的问题的。那么支持向量上的样本点有什么特点呢?

    img

    你赞同这个观点吗?所有支持向量上的样本点,都满足如上公式。如果不赞同,请重看"分类间隔"方程推导过程。

    现在我们就可以将我们的目标函数进一步化简:

    img

    因为,我们只关心支持向量上的点。随后我们求解d的最大化问题变成了||w||的最小化问题。进而||w||的最小化问题等效于

    img

    为什么要做这样的等效呢?这是为了在进行最优化的过程中对目标函数求导时比较方便,但这绝对不影响最优化问题最后的求解。我们将最终的目标函数和约束条件放在一起进行描述:

    img

    这里n是样本点的总个数,缩写s.t.表示"Subject to",是"服从某某条件"的意思。上述公式描述的是一个典型的不等式约束条件下的二次型函数优化问题,同时也是支持向量机的基本数学模型。

    (5)求解准备

    我们已经得到支持向量机的基本数学模型,接下来的问题就是如何根据数学模型,求得我们想要的最优解。在学习求解方法之前,我们得知道一点,想用我下面讲述的求解方法有一个前提,就是我们的目标函数必须是凸函数。理解凸函数,我们还要先明确另一个概念,凸集。在凸几何中,凸集(convex set)是在)凸组合下闭合的放射空间的子集。看一幅图可能更容易理解:

    img

    左右量图都是一个集合。**如果集合中任意2个元素连线上的点也在集合中,那么这个集合就是凸集。**显然,上图中的左图是一个凸集,上图中的右图是一个非凸集。

    凸函数的定义也是如此,其几何意义表示为函数任意两点连线上的值大于对应自变量处的函数值。若这里凸集C即某个区间L,那么,设函数f为定义在区间L上的函数,若对L上的任意两点x1,x2和任意的实数λ,λ属于(0,1),总有:

    img

    则函数f称为L上的凸函数,当且仅当其上镜图(在函数图像上方的点集)为一个凸集。再看一幅图,也许更容易理解:

    img

    像上图这样的函数,它整体就是一个非凸函数,我们无法获得全局最优解的,只能获得局部最优解。比如红框内的部分,如果单独拿出来,它就是一个凸函数。对于我们的目标函数:

    img

    很显然,它是一个凸函数。所以,可以使用我接下来讲述的方法求取最优解。

    通常我们需要求解的最优化问题有如下几类:

    • 无约束优化问题,可以写为:
    img

    - 有等式约束的优化问题,可以写为:

    img

    - 有不等式约束的优化问题可以写为:

    img

    对于第(a)类的优化问题,尝尝使用的方法就是费马大定理(Fermat),即使用求取函数f(x)的导数,然后令其为零,可以求得候选最优值,再在这些候选值中验证;如果是凸函数,可以保证是最优解。这也就是我们高中经常使用的求函数的极值的方法。

    对于第(b)类的优化问题,常常使用的方法就是拉格朗日乘子法(Lagrange Multiplier) ,即把等式约束h_i(x)用一个系数与f(x)写为一个式子,称为拉格朗日函数,而系数称为拉格朗日乘子。通过拉格朗日函数对各个变量求导,令其为零,可以求得候选值集合,然后验证求得最优值。

    对于第©类的优化问题,常常使用的方法就是KKT条件。同样地,我们把所有的等式、不等式约束与f(x)写为一个式子,也叫拉格朗日函数,系数也称拉格朗日乘子,通过一些条件,可以求出最优值的必要条件,这个条件称为KKT条件。

    必要条件和充要条件如果不理解,可以看下面这句话:

    • A的必要条件就是A可以推出的结论
    • A的充分条件就是可以推出A的前提

    了解到这些,现在让我们再看一下我们的最优化问题:

    img

    现在,我们的这个对优化问题属于哪一类?很显然,它属于第©类问题。因为,在学习求解最优化问题之前,我们还要学习两个东西:拉格朗日函数和KKT条件。

    (6)拉格朗日函数

    首先,我们先要从宏观的视野上了解一下拉格朗日对偶问题出现的原因和背景。

    我们知道我们要求解的是最小化问题,所以一个直观的想法是如果我能够构造一个函数,使得该函数在可行解区域内与原目标函数完全一致,而在可行解区域外的数值非常大,甚至是无穷大,那么这个没有约束条件的新目标函数的优化问题就与原来有约束条件的原始目标函数的优化问题是等价的问题。这就是使用拉格朗日方程的目的,它将约束条件放到目标函数中,从而将有约束优化问题转换为无约束优化问题。

    随后,人们又发现,使用拉格朗日获得的函数,使用求导的方法求解依然困难。进而,需要对问题再进行一次转换,即使用一个数学技巧:拉格朗日对偶。

    所以,显而易见的是,我们在拉格朗日优化我们的问题这个道路上,需要进行下面二个步骤:

    • 将有约束的原始目标函数转换为无约束的新构造的拉格朗日目标函数
    • 使用拉格朗日对偶性,将不易求解的优化问题转化为易求解的优化

    下面,进行第一步:将有约束的原始目标函数转换为无约束的新构造的拉格朗日目标函数

    公式变形如下:

    img

    其中αi是拉格朗日乘子,αi大于等于0,是我们构造新目标函数时引入的系数变量(我们自己设置)。现在我们令:

    img

    当样本点不满足约束条件时,即在可行解区域外

    img

    此时,我们将αi设置为正无穷,此时θ(w)显然也是正无穷。

    当样本点满足约束条件时,即在可行解区域内:

    img

    此时,显然θ(w)为原目标函数本身。我们将上述两种情况结合一下,就得到了新的目标函数:

    img

    此时,再看我们的初衷,就是为了建立一个在可行解区域内与原目标函数相同,在可行解区域外函数值趋近于无穷大的新函数,现在我们做到了。

    现在,我们的问题变成了求新目标函数的最小值,即:

    img

    这里用p*表示这个问题的最优值,且和最初的问题是等价的。

    接下来,我们进行第二步:将不易求解的优化问题转化为易求解的优化

    我们看一下我们的新目标函数,先求最大值,再求最小值。这样的话,我们首先就要面对带有需要求解的参数w和b的方程,而αi又是不等式约束,这个求解过程不好做。所以,我们需要使用拉格朗日函数对偶性,将最小和最大的位置交换一下,这样就变成了:

    img

    交换以后的新问题是原始问题的对偶问题,这个新问题的最优值用d来表示。而且d<=p*。我们关心的是d=p的时候,这才是我们要的解。需要什么条件才能让d=p呢?

    • 首先必须满足这个优化问题是凸优化问题。
    • 其次,需要满足KKT条件。

    凸优化问题的定义是:**求取最小值的目标函数为凸函数的一类优化问题。**目标函数是凸函数我们已经知道,这个优化问题又是求最小值。所以我们的最优化问题就是凸优化问题。

    接下里,就是探讨是否满足KKT条件了。

    (7)KKT条件

    我们已经使用拉格朗日函数对我们的目标函数进行了处理,生成了一个新的目标函数。通过一些条件,可以求出最优值的必要条件,这个条件就是接下来要说的KKT条件。一个最优化模型能够表示成下列标准形式:

    img

    KKT条件的全称是Karush-Kuhn-Tucker条件,KKT条件是说最优值条件必须满足以下条件:

    • 条件一:经过拉格朗日函数处理之后的新目标函数L(w,b,α)对α求导为零:
    • 条件二:h(x) = 0;
    • 条件三:α*g(x) = 0;

    对于我们的优化问题:

    img

    显然,条件二已经满足了。另外两个条件为啥也满足呢?

    这里已经给出了很好的解释。现在,凸优化问题和KKT都满足了,问题转换成了对偶问题。而求解这个对偶学习问题,可以分为三个步骤:首先要让L(w,b,α)关于w和b最小化,然后求对α的极大,最后利用SMO算法求解对偶问题中的拉格朗日乘子。

    (8)对偶问题求解

    第一步:

    根据上述推导已知:

    img

    首先固定α,要让L(w,b,α)关于w和b最小化,我们分别对w和b偏导数,令其等于0,即:

    img

    将上述结果带回L(w,b,α)得到:

    img

    从上面的最后一个式子,我们可以看出,此时的L(w,b,α)函数只含有一个变量,即αi。

    第二步:

    现在内侧的最小值求解完成,我们求解外侧的最大值,从上面的式子得到

    img

    现在我们的优化问题变成了如上的形式。对于这个问题,我们有更高效的优化算法,即序列最小优化(SMO)算法。我们通过这个优化算法能得到α,再根据α,我们就可以求解出w和b,进而求得我们最初的目的:找到超平面,即"决策平面"。

    总结一句话:我们为啥使出吃奶的劲儿进行推导?因为我们要将最初的原始问题,转换到可以使用SMO算法求解的问题,这是一种最流行的求解方法。为啥用这种求解方法?因为它牛逼啊!

    SMO算法

    现在,我们已经得到了可以用SMO算法求解的目标函数,但是对于怎么编程实现SMO算法还是感觉无从下手。那么现在就聊聊如何使用SMO算法进行求解。

    (1)Platt的SMO算法

    1996年,John Platt发布了一个称为SMO的强大算法,用于训练SVM。SMO表示序列最小化(Sequential Minimal Optimizaion)。Platt的SMO算法是将大优化问题分解为多个小优化问题来求解的。这些小优化问题往往很容易求解,并且对它们进行顺序求解的结果与将它们作为整体来求解的结果完全一致的。在结果完全相同的同时,SMO算法的求解时间短很多。

    SMO算法的目标是求出一系列alpha和b,一旦求出了这些alpha,就很容易计算出权重向量w并得到分隔超平面。

    SMO算法的工作原理是:每次循环中选择两个alpha进行优化处理。一旦找到了一对合适的alpha,那么就增大其中一个同时减小另一个。这里所谓的"合适"就是指两个alpha必须符合以下两个条件:

    条件之一就是两个alpha必须要在间隔边界之外,

    而且第二个条件则是这两个alpha还没有进进行过区间化处理或者不在边界上。

    (2)SMO算法的解法

    先来定义特征到结果的输出函数为:

    img

    接着,我们回忆一下原始优化问题,如下:

    img

    求导得:

    img

    将上述公式带入输出函数中:

    img

    与此同时,拉格朗日对偶后得到最终的目标化函数:

    img

    将目标函数变形,在前面增加一个符号,将最大值问题转换成最小值问题:

    img

    实际上,对于上述目标函数,是存在一个假设的,即数据100%线性可分。但是,目前为止,我们知道几乎所有数据都不那么"干净"。这时我们就可以通过引入所谓的松弛变量(slack variable),来允许有些数据点可以处于超平面的错误的一侧。这样我们的优化目标就能保持仍然不变,但是此时我们的约束条件有所改变:

    img

    根据KKT条件可以得出其中αi取值的意义为:

    img
    • 对于第1种情况,表明αi是正常分类,在边界内部;
    • 对于第2种情况,表明αi是支持向量,在边界上;
    • 对于第3种情况,表明αi是在两条边界之间。

    而最优解需要满足KKT条件,即上述3个条件都得满足,以下几种情况出现将会不满足:

    img

    也就是说,如果存在不能满足KKT条件的αi,那么需要更新这些αi,这是第一个约束条件。此外,更新的同时还要受到第二个约束条件的限制,即:

    img

    因为这个条件,我们同时更新两个α值,因为只有成对更新,才能保证更新之后的值仍然满足和为0的约束,假设我们选择的两个乘子为α1和α2:

    img

    其中, ksi为常数。因为两个因子不好同时求解,所以可以先求第二个乘子α2的解(α2 new),得到α2的解(α2 new)之后,再用α2的解(α2 new)表示α1的解(α1 new )。为了求解α2 new ,得先确定α2 new的取值范围。假设它的上下边界分别为H和L,那么有:

    img

    接下来,综合下面两个条件:

    img

    当y1不等于y2时,即一个为正1,一个为负1的时候,可以得到:

    img

    所以有:

    img

    此时,取值范围如下图所示:

    img

    当y1等于y2时,即两个都为正1或者都为负1,可以得到:

    img

    所以有:

    img

    此时,取值范围如下图所示:

    img

    如此,根据y1和y2异号或同号,可以得出α2 new的上下界分别为:

    img

    这个界限就是编程的时候需要用到的。已经确定了边界,接下来,就是推导迭代式,用于更新 α值。

    我们已经知道,更新α的边界,接下来就是讨论如何更新α值。我们依然假设选择的两个乘子为α1和α2。固定这两个乘子,进行推导。于是目标函数变成了:

    img 点击放大图片

    为了描述方便,我们定义如下符号:

    img

    最终目标函数变为:

    img

    我们不关心constant的部分,因为对于α1和α2来说,它们都是常数项,在求导的时候,直接变为0。

    对于这个目标函数,如果对其求导,还有个未知数α1,所以要推导出α1和α2的关系,然后用α2代替α1,这样目标函数就剩一个未知数了,我们就可以求导了,推导出迭代公式。所以现在继续推导α1和α2的关系。注意第一个约束条件:

    img

    我们在求α1和α2的时候,可以将α3,α4,…,αn和y3,y4,…,yn看作常数项。因此有:

    img

    我们不必关心常数B的大小,现在将上述等式两边同时乘以y1,得到(y1y1=1):

    img

    其中γ为常数By1,我们不关心这个值,s=y1y2。接下来,我们将得到的α1带入W(α2)公式得:

    img

    这样目标函数中就只剩下α2了,我们对其求偏导(注意:s=y1y2,所以s的平方为1,y1的平方和y2的平方均为1):

    img

    继续化简,将s=y1y2带入方程。

    img

    我们令:

    img

    Ei为误差项,η为学习速率。

    再根据我们已知的公式:

    img

    将α2 new继续化简得:

    img

    这样,我们就得到了最终需要的迭代公式。这个是没有经过剪辑是的解,需要考虑约束:

    img

    根据之前推导的α取值范围,我们得到最终的解析解为:

    img

    又因为:

    img

    消去γ得:

    img

    这样,我们就知道了怎样计算α1和α2了,也就是如何对选择的α进行更新。

    当我们更新了α1和α2之后,需要重新计算阈值b,因为b关系到了我们f(x)的计算,也就关系到了误差Ei的计算。

    我们要根据α的取值范围,去更正b的值,使间隔最大化。当α1 new在0和C之间的时候,根据KKT条件可知,这个点是支持向量上的点。因此,满足下列公式:

    img

    公式两边同时乘以y1得(y1y1=1):

    img

    因为我们是根据α1和α2的值去更新b,所以单独提出i=1和i=2的时候,整理可得:

    img

    其中前两项为:

    img

    将上述两个公式,整理得:

    img

    同理可得b2 new为:

    img

    当b1和b2都有效的时候,它们是相等的,即:

    img

    当两个乘子都在边界上,则b阈值和KKT条件一致。当不满足的时候,SMO算法选择他们的中点作为新的阈值:

    img

    最后,更新所有的α和b,这样模型就出来了,从而即可求出我们的分类函数。

    现在,让我们梳理下SMO算法的步骤:

    • 步骤1:计算误差:
    img
    • 步骤2:计算上下界L和H:
    img
    • 步骤3:计算η:
    img
    • 步骤4:更新αj:
    img
    • 步骤5:根据取值范围修剪αj:
    img
    • 步骤6:更新αi:

    img

    • 步骤7:更新b1和b2:
    img
    • 步骤8:根据b1和b2更新b:
    img

    SMO算法优化

    在几百个点组成的小规模数据集上,简化版SMO算法的运行是没有什么问题的,但是在更大的数据集上的运行速度就会变慢。简化版SMO算法的第二个α的选择是随机的,针对这一问题,我们可以使用启发式选择第二个α值,来达到优化效果。

    1 启发选择方式

    下面这两个公式想必已经不再陌生:

    img

    在实现SMO算法的时候,先计算η,再更新a_j。为了加快第二个α_j乘子的迭代速度,需要让直线的斜率增大,对于α_j的更新公式,其中η值没有什么文章可做,于是只能令:

    img

    因此,我们可以明确自己的优化方法了:

    • 最外层循环,首先在样本中选择违反KKT条件的一个乘子作为最外层循环,然后用"启发式选择"选择另外一个乘子并进行这两个乘子的优化
    • 在非边界乘子中寻找使得|E_i - E_j|最大的样本
    • 如果没有找到,则从整个样本中随机选择一个样本

    接下来,让我们看看完整版SMO算法如何实现。

    2 完整版SMO算法

    完整版Platt SMO算法是通过一个外循环来选择违反KKT条件的一个乘子,并且其选择过程会在这两种方式之间进行交替:

    • 在所有数据集上进行单遍扫描
    • 在非边界α中实现单遍扫描

    非边界α指的就是那些不等于边界0或C的α值,并且跳过那些已知的不会改变的α值。所以我们要先建立这些α的列表,用于才能出α的更新状态。

    在选择第一个α值后,算法会通过"启发选择方式"选择第二个α值。

    三、非线性SVM

    1 核技巧

    我们已经了解到,SVM如何处理线性可分的情况,而对于非线性的情况,SVM的处理方式就是选择一个核函数。简而言之:在线性不可分的情况下,SVM通过某种事先选择的非线性映射(核函数)将输入变量映到一个高维特征空间,将其变成在高维空间线性可分,在这个高维空间中构造最优分类超平面。

    根据上篇文章,线性可分的情况下,可知最终的超平面方程为:

    img

    将上述公式用内积来表示:

    img

    对于线性不可分,我们使用一个非线性映射,将数据映射到特征空间,在特征空间中使用线性学习器,分类函数变形如下:

    img

    其中ϕ从输入空间(X)到某个特征空间(F)的映射,这意味着建立非线性学习器分为两步:

    • 首先使用一个非线性映射将数据变换到一个特征空间F;
    • 然后在特征空间使用线性学习器分类。

    如果有一种方法可以在特征空间中直接计算内积<ϕ(x_i),ϕ(x)>,就像在原始输入点的函数中一样,就有可能将两个步骤融合到一起建立一个分线性的学习器,这样直接计算的方法称为核函数方法。

    这里直接给出一个定义:核是一个函数k,对所有x,z∈X,满足k(x,z)=<ϕ(x_i),ϕ(x)>,这里ϕ(·)是从原始输入空间X到内积空间F的映射。

    简而言之:如果不是用核技术,就会先计算线性映ϕ(x_1)和ϕ(x_2),然后计算这它们的内积,使用了核技术之后,先把ϕ(x_1)和ϕ(x_2)的一般表达式<ϕ(x_1),ϕ(x_2)>=k(<ϕ(x_1),ϕ(x_2) >)计算出来,这里的<·,·>表示内积,k(·,·)就是对应的核函数,这个表达式往往非常简单,所以计算非常方便。

    这种将内积替换成核函数的方式被称为核技巧(kernel trick)。

    2 非线性数据处理

    已经知道了核技巧是什么,但是为什么要这样做呢?我们先举一个简单的例子,进行说明。假设二维平面x-y上存在若干点,其中点集A服从{x,y|x2+y2=1},点集B服从{x,y|x2+y2=9},那么这些点在二维平面上的分布是这样的:

    img

    蓝色的是点集A,红色的是点集B,他们在xy平面上并不能线性可分,即用一条直线分割( 虽然肉眼是可以识别的) 。采用映射(x,y)->(x,y,x2+y2)后,在三维空间的点的分布为:

    img

    可见红色和蓝色的点被映射到了不同的平面,在更高维空间中是线性可分的(用一个平面去分割)。

    上述例子中的样本点的分布遵循圆的分布。继续推广到椭圆的一般样本形式:

    img

    上图的两类数据分布为两个椭圆的形状,这样的数据本身就是不可分的。不难发现,这两个半径不同的椭圆是加上了少量的噪音生成得到的。所以,一个理想的分界应该也是一个椭圆,而不是一个直线。如果用X1和X2来表示这个二维平面的两个坐标的话,我们知道这个分界椭圆可以写为:

    img

    这个方程就是高中学过的椭圆一般方程。注意上面的形式,如果我们构造另外一个五维的空间,其中五个坐标的值分别为:

    img

    那么,显然我们可以将这个分界的椭圆方程写成如下形式:

    img

    这个关于新的坐标Z1,Z2,Z3,Z4,Z5的方程,就是一个超平面方程,它的维度是5。也就是说,如果我们做一个映射 ϕ : 二维 → 五维,将 X1,X2按照上面的规则映射为 Z1,Z2,··· ,Z5,那么在新的空间中原来的数据将变成线性可分的,从而使用之前我们推导的线性分类算法就可以进行处理了。

    我们举个简单的计算例子,现在假设已知的映射函数为:

    img

    这个是一个从2维映射到5维的例子。如果没有使用核函数,根据上一小节的介绍,我们需要先结算映射后的结果,然后再进行内积运算。那么对于两个向量a1=(x1,x2)和a2=(y1,y2)有:

    img

    另外,如果我们不进行映射计算,直接运算下面的公式:

    img

    你会发现,这两个公式的计算结果是相同的。区别在于什么呢?

    • 一个是根据映射函数,映射到高维空间中,然后再根据内积的公式进行计算,计算量大;
    • 另一个则直接在原来的低维空间中进行计算,而不需要显式地写出映射后的结果,计算量小。

    其实,在这个例子中,核函数就是:

    img

    我们通过k(x1,x2)的低维运算得到了先映射再内积的高维运算的结果,这就是核函数的神奇之处,它有效减少了我们的计算量。在这个例子中,我们对一个2维空间做映射,选择的新的空间是原始空间的所以一阶和二阶的组合,得到了5维的新空间;如果原始空间是3维的,那么我们会得到19维的新空间,这个数目是呈爆炸性增长的。如果我们使用ϕ(·)做映射计算,难度非常大,而且如果遇到无穷维的情况,就根本无从计算了。所以使用核函数进行计算是非常有必要的。

    3 核技巧的实现

    通过核技巧的转变,我们的分类函数变为:

    img

    我们的对偶问题变成了:

    img

    这样,我们就避开了高纬度空间中的计算。当然,我们刚刚的例子是非常简单的,我们可以手动构造出来对应映射的核函数出来,如果对于任意一个映射,要构造出对应的核函数就很困难了。因此,通常,人们会从一些常用的核函数中进行选择,根据问题和数据的不同,选择不同的参数,得到不同的核函数。接下来,要介绍的就是一个非常流行的核函数,那就是径向基核函数。

    径向基核函数是SVM中常用的一个核函数。径向基核函数采用向量作为自变量的函数,能够基于向量举例运算输出一个标量。径向基核函数的高斯版本的公式如下:

    img

    其中,σ是用户自定义的用于确定到达率(reach)或者说函数值跌落到0的速度参数。上述高斯核函数将数据从原始空间映射到无穷维空间。关于无穷维空间,我们不必太担心。高斯核函数只是一个常用的核函数,使用者并不需要确切地理解数据到底是如何表现的,而且使用高斯核函数还会得到一个理想的结果。如果σ选得很大的话,高次特征上的权重实际上衰减得非常快,所以实际上(数值上近似一下)相当于一个低维的子空间;反过来,如果σ选得很小,则可以将任意的数据映射为线性可分——当然,这并不一定是好事,因为随之而来的可能是非常严重的过拟合问题。不过,总的来说,通过调控参数σ,高斯核实际上具有相当高的灵活性,也是使用最广泛的核函数之一。

    六 总结

    1 SVM的优缺点

    优点

    • 可用于线性/非线性分类,也可以用于回归,泛化错误率低,也就是说具有良好的学习能力,且学到的结果具有很好的推广性。
    • 可以解决小样本情况下的机器学习问题,可以解决高维问题,可以避免神经网络结构选择和局部极小点问题。
    • SVM是最好的现成的分类器,现成是指不加修改可直接使用。并且能够得到较低的错误率,SVM可以对训练集之外的数据点做很好的分类决策。

    缺点

    • 对参数调节和和函数的选择敏感。

    参考资料:

    • [1] 五岁小孩也能看懂的SVM:https://www.zhihu.com/question/21094489/answer/8627319
    • [2] 五岁小孩也能看懂的SVM :https://www.reddit.com/r/MachineLearning/comments/15zrpp/please_explain_support_vector_machines_svm_like_i/
    • [3] pluskid大牛博客:http://blog.pluskid.org/?page_id=683
    • [4] 陈东岳老师文章:https://zhuanlan.zhihu.com/p/24638007
    • [5] 深入理解拉格朗日乘子法和KKT条件:http://blog.csdn.net/xianlingmao/article/details/7919597
    • [6] 充分条件和必要条件:https://www.zhihu.com/question/30469121
    • [7] 凸函数:https://zh.wikipedia.org/wiki/%E5%87%B8%E5%87%BD%E6%95%B0
    • [8]《机器学习实战》第6章内容。
    • [9] SVM之SMO算法:http://www.cnblogs.com/zangrunqiang/p/5515872.html
    展开全文
  • 支持向量机:是一种监督学习的算法。 前置芝士: 支持向量:就是距离超平面最近的那些点 :表示一种算法 超平面:就是分割数据的一个(n-1)维的面,就是分类的决策边界 线性可分:数据可以通过画一条直线就可以...

    SVM 概述

    支持向量机:是一种监督学习的算法。

    前置芝士:
    • 支持向量:就是距离超平面最近的那些点
    • 机:表示一种算法
    • 超平面:就是分割数据的一个(n-1)维的面,就是分类的决策边界
    • 线性可分:数据可以通过画一条直线就可以将它们完全分开
    • 线性不可分:上一条相反的意思

    在这里插入图片描述

    场景

    • 给左右两边的点进行分类
    • 直觉就会发现D这种分类方法最好

    摘录自<<机器学习实战>>

    算法流程:

    我们找到函数间隔最小值的向量(也就是找到支持向量),然后让几何间隔最大化。
    函数间隔、几何间隔、为什么这样选择是最优得我下面会说。
    本质求一个函数最小化的最大值得过程

    所以什么是函数间隔几何间隔呢?

    函数间隔:

    就是训练数据集T中得样本点( x i x_i xi, y i y_i yi)距离超平面 w T x + b w^{T}x+b wTx+b 的距离。

    r ^ = l a b l e k ∗ ( w T x k + b ) \widehat{r}=lable_{k}\ast \left( w^{T}x_{k}+b\right) r =lablek(wTxk+b)
    (lable表示分类决策,lable == 1表示在正分类,lable == -1表示在负分类。前面用label乘一下来保证这个间隔是非负的)

    只要等比例改变w和b,超平面没变但是函数间隔变了为什么呢?
    答案: 函数间隔能表示分类的正确性和可信度,但无法表示出间隔的数量大小(定性表示)。我们因此就引入了几何间隔

    几何间隔:

    r ^ = l a b l e k ∗ ( W T x + b ) ∥ W ∥ \widehat{r}=\dfrac{lable_{k}*(W^{T}x+b)}{\left\| W\right\| } r =Wlablek(WTx+b)

    下图形象的解释了函数间隔几何间隔

    在这里插入图片描述

    有了上面的讲解,目标函数就很容易就的出来了。

    a r g : m a x w , b ( m i n [ l a b e l ∗ ( w T x + b ) ] ∗ 1 ∣ ∣ w ∣ ∣ ) arg: max_{w, b} \left( min[label*(w^Tx+b)]*\frac{1}{||w||} \right) arg:maxw,b(min[label(wTx+b)]w1)

    目标函数非常的复杂吗,那么我们怎么优化函数让其便于求解呢?:

    1. l a b e l ∗ ( w T x + b ) > = 1 label*(w^Tx+b)>=1 label(wTx+b)>=1,因为0-1之间,得到的点存在误判的可能性,所以要保证 m i n [ l a b e l ∗ ( w T x + b ) = = 1 min[label*(w^Tx+b)==1 min[label(wTx+b)==1,才能更好的降低噪音数据的影响。

    因为要保证函数间隔最小(找到支持向量),所以将最小的函数距离设为1,也就是说非支持向量的函数距离大于1

    1. 所以目标函数得以简化为:

    a r g : m a x w , b ( 1 ∣ ∣ w ∣ ∣ ) arg: max_{w, b} \left( \frac{1}{||w||} \right) arg:maxw,b(w1)
    前提条件为: l a b e l ∗ ( w T x + b ) = = 1 label*(w^Tx+b)==1 label(wTx+b)==1

    3.进一步化简:

    a r g : m a x w , b ( 1 ∣ ∣ w ∣ ∣ ) = > arg: max_{w, b} \left( \frac{1}{||w||} \right) => arg:maxw,b(w1)=> a r g : m i n w , b ( ∣ ∣ w ∣ ∣ ) arg: min_{w, b}\left( {||w||} \right) arg:minw,b(w)
    (求矩阵偏导很麻烦,如果x求 1 2 x 2 \frac{1}{2x^2} 2x21的偏导数,同样求得是最小值)

    所以目标函数最终变为

    a r g : m i n w , b ( 1 2 ∗ ∣ ∣ w ∣ ∣ 2 ) arg: min_{w, b}\left( \frac{1}{2}*{||w||^2} \right) arg:minw,b(21w2)
    凸二次优化问题

    4.应用拉格朗日乘子法求解凸优化问题:

    L ( w , b , a ) = 1 2 ∥ w ∥ 2 − ∑ i = 1 n a i [ l a b l e ∗ ( w T x i + b ) − 1 ] L\left( w,b,a\right) =\dfrac{1}{2}\left\| w\right\| ^{2}-\sum ^{n}_{i=1}a_{i}\left[ lable\ast \left( w^Tx_{i}+b\right) -1\right] L(w,b,a)=21w2i=1nai[lable(wTxi+b)1]

    令L(w,b,a)对w和b的偏导数为0,有

    w = ∑ i = 1 n l a b l e i ∗ a i x i w=\sum ^{n}_{i=1}lable_{i}*a_{i}x_{i} w=i=1nlableiaixi

    ∑ i = 1 n a i ∗ l a b l e i = 0 \sum ^{n}_{i=1}a_{i}*lable_{i}=0 i=1nailablei=0

    再将上述两个结果带入L(w,b,a)中消去w和b,之后有其对偶化处理得到拉格朗日乘子a的值最终得到结果。

    w = ∑ i = 1 n l a b l e i ∗ a i x i w=\sum ^{n}_{i=1}lable_{i}*a_{i}x_{i} w=i=1nlableiaixi

    b = l a b l e i − w T x i b=lable_{i}-w^Tx_{i} b=lableiwTxi

    所以超平面 w x + b = 0 wx+b=0 wx+b=0
    分类决策函数 f ( x ) = s i g n ( w x + b ) f(x)=sign(wx+b) f(x)=sign(wx+b)

    对待有极端数据点的优化:

    上述所述算法是基于硬间隔,硬间隔对异常数据点太过于敏感,接下来我们介绍一下软间隔
    软间隔SVM模型:允许对少量训练样本出现分类错误。这里我们引入了松弛变量 ξ i \xi _{i} ξi和惩罚因子 C C C,约束条件转化为:
    在这里插入图片描述
    这里的 y i y_i yi代表lable值。

    线性SVM算法流程概览:

    在这里插入图片描述

    非线性SVM

    概述

    对于非线性的情况,支持向量机选择一个核函数k(…,…)将数据映射到高维空间,从而解决原始空间中线性不可分的问题。

    算法流程

    分类函数定义为 f ( x ) = ∑ i = 1 n w i ϕ i ( x ) + b f\left ( x\right) =\sum ^{n}_{i=1}w_{i}\phi _{i}\left( x\right) +b f(x)=i=1nwiϕi(x)+b

    这里的 ϕ i \phi _{i} ϕi是核函数,将低维数据到高维空间的映射关系。

    在这里插入图片描述
    下面是将三维的x矩阵映射为六维的Z矩阵在这里插入图片描述

    接下来严格数学证明还没整理 ~ 考完试再来补充 ~ (一定~)

    SVM优点

    1. 训练好的模型算法的复杂度是由支持向量的个数决定的,而不是由数据维度决定的。所以SVM不太容易产生过拟合
    2. SVM训练出来的模型完全依赖于支持向量,即使训练集里面所有非支持向量点被去除,重复训练过程,结果仍然得到一样的模型。
    3. 如果支持向量个数比较少,SVM训练出的模型容易被泛化。

    SVC算法中不同参数的影响:

    1. C:惩罚系数(对误差的宽容度):

    C越大,越不容忍误差,容易过拟合。C越小,越容忍误差,容易欠拟合。设计算法时我们要选取合适的C,以便在平滑决策边界和分类正确性之间进行平衡。

    2.gamma:指定核函数的系数

    隐含地决定了数据映射到新的特征空间中的分布。gamma值越大,支持向量越少。

    展开全文
  • 文章目录[MATLAB 在科学计算中的应用] 使用MATLAB 进行非线性拟合前言引述MATLAB 曲线拟合函数简述一二维数据非线性拟合一维数据拟合例子二维数据拟合例子高维数据非线性拟合lsqcurvefitnlinfit 函数数据拟合工具箱...
  • 非线性数据拟合

    2021-06-29 10:03:15
    实际的数据拟合问题研究中一般分为线性数据拟合非线性数据拟合。其中,线性数据拟合通常是采用一组简单的、线性无关的基函数来逼近试验数据。而对于非线性数据拟合问题,通常分为两种情形进行处理,一种是利用变量...
  • fminsearch函数用来求解多维无约束的线性优化问题用derivative-free的方法找到多变量无约束函数的最小值语法x =fminsearch(fun,x0)x =fminsearch(fun,x0,options)[x,fval] =fminsearch(...)[x,fval,exitflag] = ...
  • SVM(支持向量机)与LDA(线性判别分析)

    千次阅读 2021-11-10 22:02:21
    目录一、SVM二、LDA三、SVM数据集进行可视化分类1.月亮数据集1....当训练样本线性可分时,通过硬间隔最大化,学习一个线性可分支持向量机; 当训练样本近似线性可分时,通过软间隔最大化,学习一个线性支持
  • MatLab中的多项式拟合(lsqcurvefit函数的非线性曲线拟合) lsqcurvefit函数 函数原型 x=lsqcurvefit(fun, x0, xdata, ydata) == 其中的参数表示为:== xdata ydata为给定数据横纵坐标 按照函数文件fun给定的函数...
  • 我们把使得当时,的样本点,以及使得当时,的样本点称为“支持向量”,两个异类支持向量到超平面的距离之和为 它被称为“间隔”。 欲找到具有“最大间隔”划分的超平面,也就是要找到能满足约束条件的参数和,...
  • 三维曲线(非线性)拟合步骤1 设定目标函数.(M函数书写)% 可以是任意的例如:functionf=mydata(a,data)%y的值目标函数值或者是第三维的,a=[a(1),a(2)]列向量x=data(1,:);�ta 是一2维数组,x=x1y=data(2,:);�ta 是一...
  • 详解支持向量机

    2021-03-17 20:24:41
    作者|Anuj Shrivastav 编译|VK 来源|Medium 介绍监督学习...我们将在此博客中讨论的一种这样的模型是支持向量机,简称为SVM。我的目的是为你提供简单明了的SVM内部工作。假设我们正在处理二分类任务。 可能有无限...
  • MATLAB非线性回归拟合nlintool非线性回归非线性回归可用命令nlinfit,nlintool,nlparci,nlpredci来实现。进行非线性回归时可使用nlinfit指令,其语法如下:beta = nlinfit(X,y,fun,beta0)[beta,r,J] = nlinfit(X,y,...
  • Python实现支持向量机SVM回归模型(SVR算法)项目实战。
  • 关于SVM网上已经有很多很多的前辈有过讲解,这两天自己在网上看了看资料,结合前辈们的文章对SVM进行了一个整理,把看的过程中...支持向量机(Support Vector Machine)是Cortes和Vapnik于1995年首先提出的,它在解决小
  • 对测量数据的拟合在科学研究和工程中具有广泛的应用,下面给出几种常用的拟合方法,及其如何在MATLAB环境中实现。在MATLAB中有用于拟合的命令 polyfit,lsqcurvefit,nlinfit 和曲线拟合工具cftool.解决一般的工程拟合...
  • python 支持向量机(SVM)算法之分类实操 算法简介 SVM 之前我们用了很多线性算法来做预测模型,像是逻辑算法(LogisticRegression),lasso,岭回归。但现实生活中,很多事情不是线性可分的(即画一条直线就能分类的)...
  • 1stopt非线性拟合工具Win10专业版是一个功能模型分析和绘图软件,可以应用于WIN10系统,它具有强大的功能,它是唯一能够以任何初始值获得美利坚合众国国家标准技术研究院非线性回归测试集最优解的软件包, ,可广泛...
  • 函数插值 1.2 抛出问题2:函数拟合 1.3 什么是回归 第2章 函数拟合 2.1 插值有时候插值并不是最好的选择 2.2 什么函数拟合 2.2 函数拟合的基本步骤 第3章 最小二乘法 3.1 什么是最小二乘法 3.2 线性拟合函数的最小...
  • 非线性支持向量机4. 支持向量回归(SVR)5. 代码示例6. 模型评价完整代码地址参考 本博客中使用到的完整代码请移步至: 我的github:https://github.com/qingyujean/Magic-NLPer,求赞求星求鼓励~~~ 1. 线性可分支持...
  • 本文介绍了机器学习算法中经典的有监督算法(线性回归,逻辑回归,支持向量机,集成学习(随机森林&AdsBoot),朴素贝叶斯和KNN),不包括无监督算法和深度学习算法。
  • 支持向量机是处理回归问题的可泛化性能最好的,解决过拟合,机器学习中算法精度也是最高的 相关数学知识 ​ 梯度下降 ​ 梯度下降法(Gradient Descent, GD)常用于求解无约束(不跟其他的位置比最近,而是只自己比...
  • 遗传算法优化BP神经网络在非线性函数拟合中的应用 在工程应用中经常会遇到一些复杂的非线性系统,这些系统状态方程复杂,难以用数学方法精确建模。在这种情况下,可以建立BP神经网络表达这些非线性系统。通常BP神经...
  • 机器学习算法(四): 基于支持向量机的分类预测 1 前言 支持向量机(Support Vector Machine,SVM)是一个非常优雅的算法,具有非常完善的数学理论,常用于数据分类...了解支持向量机非线性核函数分类; 3 代码流程
  • 1.敘述三种分类学习方法:LDA,朴素贝叶斯,支持向量机的原理和算法,三种分类方法各适合什么样的数据集? 先说结论:LDA适合于样本固定,参数未知但不固定,是个随机变量,服从一定的分布的数据集。 朴素贝叶斯的...
  • 支持向量机即SVM(Support Vector Machine),主要用于解决模式识别领域中的数据分类问题,属于有监督学习算法的一种。是一类按监督学习方式对数据进行二元分类的广义线性分类器。 如图所示, 红色和蓝色的点是可以被...
  • 1. 前言 前文: 支持向量机(SVM)详解(一) 支持向量机(SVM)详解(二) 前面用两篇文章
  • SVM 擅长解决复杂的中小规模的非线性问题,甚至在特征多余训练样本时也能有非常好的表现。 但是随着样本量的增加,SVM模型的计算复杂度会呈m^2 或m^3增加。 SVM 算法涉及到非常多的概念:间隔、支持向量、核函数、...
  • 国赛三维曲线(非线性拟合指导

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 46,108
精华内容 18,443
关键字:

支持向量机非线性拟合