支持向量机(SVM)笔记

SVM

1.概述

SVM全称Support_Vector_Machine,即支持向量机,是机器学习中的一种监督学习分类算法,一般用于二分类问题。对于线性可分的二分类问题,SVM可以直接求解,对于非线性可分问题,其也可以通过核函数将低维映射到高维空间从而转变为线性可分。对于多分类问题,SVM经过适当的转换,也能加以解决。相对于传统的分类算法如logistic回归,k近邻法,决策树,感知机,高斯判别分析法(GDA)等,SVM尤其独到的优势。相对于神经网络复杂的训练计算量,SVM在训练方面较少计算量的同时也能得到很好的训练效果。

2.问题的提出

  • 考虑一个线性可分的二分类问题

    • m个训练样本x是特征向量,y是目标变量

      {x(i),y(i)},x(i)∈Rn,y(i)∈{1,−1},i=1,2,⋯,m
      决策函数:hw,b(x)=g(wTx+b),g(z)={1,ifx>00,ifx<0

      直线代表 wTx+b=0

    • 首先定义一些符号
      • functional margin(函数边界)

        r^=min{r^(i)},i=1,2,⋯,m;r^(i)=y(i)∗(wTx(i)+b)

      • geometrical margin(几何边界)

        r=min{r(i)},i=1,2,⋯,m;r(i)=y(i)∗(wTx(i)+b)∥w∥

      • 符号解释:
        • 函数边界:由于y(i)只能取1,−1,所以当wT∗x(i)+b>>0时,y=1和y=−1分别表示点分布在距离超平面wTx+b=0两边很远的地方,注意如果加倍w与x,函数边界是会加倍的
    • 目标:几何边界最大,即

      max{r}

3.问题的转化

  • 依次转化:

    • max{r}
    • max{min{r(i)=y(i)∗(wTx(i)+b)∥w∥};i=1,2,⋯,m}
    • ⎧⎩⎨max{r}s.t.y(i)∗(wTx(i)+b)∥w∥≥r
    • {max{r^∥w∥}s.t.y(i)∗(wTx(i)+b)≥r^
    • 注意函数边界的改变不影响优化问题的求解结果

    letr^=1
    问题转化为:
    {max{1∥w∥}s.t.y(i)∗(wTx(i)+b)≥1
    最终转化为optimization problem,而且目标函数是convex的,即凸函数
    {min{12w2}s.t.y(i)∗(wTx(i)+b)≥1最终得到优化问题(1)

4.问题求解

(1)可以用通常的QP(二次规划)方法求解,matlab或lingo都有相应工具箱。
(2)既然本文叫SVM,当然会用到不同的解法,而且SVM的解法在训练集很大的时候,比一般的QP解法效率高。

  • 广义拉格朗日数乘法

    对于3中得到的优化问题(1)有:
    {L(w,b,α)=12w2−∑mi=1α(i)[y(i)∗(wTx(i)+b)−1]α(i)≥0

    • 满足约束条件y(i)∗(wTx(i)+b)≥1下有:
      max{L(w,b,α)}=1w2=f(w)
  • 优化问题变为:

    ⎧⎩⎨⎪⎪minw,b{maxα{L(w,b,α)}}s.t.y(i)∗(wTx(i)+b)≥1α(i)≥0

  • 在满足KKT条件下有(对偶优化问题)
    • minw,b{maxα{L(w,b,α)}}=maxα{minw,b{L(w,b,α)}}
      通常对偶问题(dual problem)max{min{f(w,α)}}比原始问题(primal problem)min{max{f(w,α)}}更容易求解,尤其是在训练样本数量很大的情况下,KKT条件又称为互补松弛条件

    • ∇w,bL(w¯,b¯,α¯)=0;

      w¯,b¯是primaloptimal;α¯是dualoptimal

    • α¯(i)gi(w¯,b¯)=0,

      y(i)∗(wTx(i)+b)=1时,通常有α≠0,这些点称为Support Vector,即支持向量 y(i)∗(wTx(i)+b)>1时,有α=0,通常大多数α为0,减少了计算量

  • 解决minw,b{L(w,b,α)}

    求偏导令为0可得{w=∑mi=1α(i)y(i)x(i)∑mi=1α(i)y(i)=0

  • 带入原式:

    ⎧⎩⎨⎪⎪maxα{∑mi=1α(i)−12∑mi,j=1y(i)y(j)α(i)α(j)<x(i),x(j)>}α(i)≥0∑mi=1α(i)y(i)=0

    • 求得α则可得到w,b
    • 目标表示为 wTx+b=∑mi=1α(i)y(i)<x(i),x>+b
    • kernel(x,y)=<xT,y>称为核函数,能较少高维空间计算量,通常知道了核函数,计算量相对于找对应的x,y向量小得多,而且若x,y是无限维向量,也可通过核函数映射。常用的核函数有:
      • 高斯核K(x,z)=exp(−∥z−x∥2σ2)
      • 多项式核K(x,z)=(x−z)a

5.问题的优化

  • 4中推导出了求α使得最大化的问题。但其存在一定问题。

    当训练集如右图分布在超平面两侧时,结果并不好,因此我们可以给r^=1添加松弛条件,允许少数点小于1,甚至分类到错误的一面

  • 我们修改限制条件,并修改目标函数

    ⎧⎩⎨⎪⎪min{12w2+csummi=1ξi}y(i)∗(wTx(i)+b)≥1−ξiξi≥0

  • 通过类似的对偶问题的求解,我们得到

    ⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪W=maxα{∑mi=1α(i)−12∑mi,j=1y(i)y(j)α(i)α(j)<x(i),x(j)>}0≤α≤c∑mi=1α(i)y(i)=0

6.优化后问题的求解

  • 坐标上升法求解最大值
 #伪代码
        loop {
          for i in range(m):
              alpha(i):=alpha(i) which let {w} maximum
      }
  • 坐标上升与梯度上升的对比图
  • SMO
 #伪代码
      L<=alpha<=H
      loop {
          for i,j in range(m):
              alpha(i):=min{ (alpha(i) or L or H ) which let {w} maximum }
              alpha(j):=min{ (alpha(j) or L or H ) which let {w} maximum }
      }

7.实战

  • trainsets 总共90组
    -0.017612 14.0530640
    -1.395634 4.6625411
    -0.752157 6.5386200
    -1.322371 7.1528530
    …………………………
    -1.076637 -3.1818881
    1.821096 10.2839900
    3.010150 8.4017661
    -1.099458 1.6882741
    -0.834872 -1.7338691
    -0.846637 3.8490751
    1.400102 12.6287810
    1.752842 5.4681661
    0.078557 0.0597361

  • testsets 总共10组

    0.089392 -0.7153001
    1.825662 12.6938080
    0.197445 9.7446380
    0.126117 0.9223111
    -0.679797 1.2205301
    0.677983 2.5566661
    0.761349 10.6938620
    -2.168791 0.1436321
    1.388610 9.3419970
    0.317029 14.7390250

  • logistic回归效果
    • 权值weight=[[11.93391219][1.12324688][−1.60965531]]
    • 原始测试文件真值y=[1.0,0.0,0.0,1.0,1.0,1.0,0.0,1.0,0.0,0.0]
    • logistic回归预测值:y1=[1.0,0.0,0.0,1.0,1.0,1.0,0.0,1.0,0.0,0.0]
    • 正确率还是蛮高的
    • 附上代码:
#!/usr/bin/env
#coding:utf-8
import numpy
import sys
from matplotlib import pyplot
import random

def makedata(filename):
    try:
        f = open(filename,"r")
        lines = f.readlines()
        datalist = []
        datalist = [i.split() for i in lines ]
        datalist = [ [ float(i) for i in line] for line in datalist ]
        for i in range(len(datalist)):
            datalist[i].insert(0,1.0)
    except:
        return
    finally:
        return datalist
        f.close()

def makedat(filename):
    try:
        f = open(filename,"r")
        lines = f.readlines()
        datalist = []
        datalist = [i.split() for i in lines ]
        datalist = [ [ float(i) for i in line] for line in datalist ]
        x = [ line[0:len(line)-1] for line in datalist ]
        y = [ line[-1] for line in datalist ]
    except:
        return
    finally:
        return x,y
        f.close()

def sigma(z):
    return 1.0/(1+numpy.exp(-z))

#batch regression
def logisticFunc(dataset,itertimes,alpha):
    weight = numpy.ones((len(dataset[0])-1,1))
    value = [ int(i[-1]) for i in dataset ]
    value = numpy.mat(value).transpose()
    params = [ i[0:-1] for i in dataset ]
    params = numpy.mat(params)
    for i in range(int(itertimes)):
        error = value-sigma(params*weight)
        weight = weight+alpha*params.transpose()*error
    return weight

#random grad ascend regression
def randLogisticFunc(dataset,itertimes,alpha):
    weight = numpy.ones((len(dataset[0])-1,1))
    value = [ int(i[-1]) for i in dataset ]
    value = numpy.mat(value).transpose()
    params = [ i[0:-1] for i in dataset ]
    params = numpy.mat(params)
    for i in range(int(itertimes)):
        randid = random.randint(0,len(dataset)-1)
        error = value[randid]-sigma(params[randid]*weight)
        weight = weight+alpha*params[randid].transpose()*error
    return weight

def plot(data,weight):
    x1 = []
    x2 = []
    y1 = []
    y2 = []
    for i in data:
        if i[-1] == 1:
            x1.append(i[1])
            y1.append(i[2])
        else:
            x2.append(i[1])
            y2.append(i[2])
    x = numpy.linspace(-3,3,1000)
    weight = numpy.array(weight)
    y = (-weight[0][0]-weight[1][0]*x)/weight[2][0]
    fg = pyplot.figure()
    sp = fg.add_subplot(111)
    sp.scatter(x1,y1,s=30,c="red")
    sp.scatter(x2,y2,s=30,c="blue")
    sp.plot(x,y)
    pyplot.show()

def predict(weight,x1):
    yi = []
    for i in x1:
        if weight[0][0]+i[0]*weight[1][0]+i[1]*weight[2][0]>=0:
            yi.append(1)
        else:
            yi.append(0)
    print yi

def main():
    trainfile = sys.argv[1]
    itertimes = int(sys.argv[2])
    alpha = float(sys.argv[3])
    testfile = sys.argv[4]
    data = makedata(trainfile)
    testx,testy = makedat(testfile)
    weight = logisticFunc(data,itertimes,alpha)
    print weight
    predict(weight,testx)
    print testy
    #weight = randLogisticFunc(data,itertimes,alpha)
    #print weight
    plot(data,weight)
if __name__=='__main__':
    main()
  • SVM效果(采用高斯核,使用sklearn库)
    • 原始测试文件真值y=[1.0,0.0,0.0,1.0,1.0,1.0,0.0,1.0,0.0,0.0]
    • svm预测值:y1=array([1.,0.,0.,1.,1.,1.,0.,1.,0.,0.])
    • 正确率也挺高的
    • 附上代码:
#!/usr/bin/env python
#coding:utf-8
from sklearn import svm
import sys
def makedata(filename):
    try:
        f = open(filename,"r")
        lines = f.readlines()
        datalist = []
        datalist = [i.split() for i in lines ]
        datalist = [ [ float(i) for i in line] for line in datalist ]
        x = [ line[0:len(line)-1] for line in datalist ]
        y = [ line[-1] for line in datalist ]
    except:
        return
    finally:
        return x,y
        f.close()
def learn(x,y):
    clf = svm.SVC()
    clf.fit(x,y)
    return clf
def predict(x1,y1,clf):
    print "svm fit results",clf.predict(x1)
    print "original test file results",y1
if __name__=="__main__":
    inputfile = sys.argv[1]
    testfile = sys.argv[2]
    x,y = makedata(inputfile)
    x1,y1 = makedata(testfile)
    clf = learn(x,y)
    predict(x1, y1, clf)
时间: 2024-11-01 06:42:47

支持向量机(SVM)笔记的相关文章

机器学习——支持向量机SVM在R中的实现

支持向量机是一个相对较新和较先进的机器学习技术,最初提出是为了解决二类分类问题,现在被广泛用于解决多类非线性分类问题和回归问题.继续阅读本文,你将学习到支持向量机如何工作,以及如何利用R语言实现支持向量机. 支持向量机如何工作? 简单介绍下支持向量机是做什么的: 假设你的数据点分为两类,支持向量机试图寻找最优的一条线(超平面),使得离这条线最近的点与其他类中的点的距离最大.有些时候,一个类的边界上的点可能越过超平面落在了错误的一边,或者和超平面重合,这种情况下,需要将这些点的权重降低,以减小它们

机器学习——svm支持向量机的原理

前言     动笔写这个支持向量机(support vector machine)是费了不少劲和困难的,原因很简单,一者这个东西本身就并不好懂,要深入学习和研究下去需花费不少时间和精力,二者这个东西也不好讲清楚,尽管网上已经有朋友写得不错了(见文末参考链接),但在描述数学公式的时候还是显得不够.得益于同学白石的数学证明,我还是想尝试写一下,希望本文在兼顾通俗易懂的基础上,真真正正能足以成为一篇完整概括和介绍支持向量机的导论性的文章.     本文在写的过程中,参考了不少资料,包括<支持向量机导论

支持向量机通俗导论(理解SVM的三层境界)

PS: 膜拜+跪拜 支持向量机通俗导论(理解SVM的三层境界) 作者:July :致谢:pluskid.白石.JerryLead.画儿.出处:结构之法算法之道blog. 前言     动笔写这个支持向量机(support vector machine)是费了不少劲和困难的,原因很简单,一者这个东西本身就并不好懂,要深入学习和研究下去需花费不少时间和精力,二者这个东西也不好讲清楚,尽管网上已经有朋友写得不错了(见文末参考链接),但在描述数学公式的时候还是显得不够.得益于同学白石的数学证明,我还是想

机器学习算法的python实现之svm支持向量机(1) 理论知识

1.背景 强烈推荐阅读(http://www.cnblogs.com/jerrylead/archive/2011/03/13/1982639.html) 支持向量机SVM(support vector machines).SVM是一种二值分类器,是近些年比较流行的一种分类算法. 本文,首先要介绍一些基本的知识概念,在下一章将对SVM进行简单地代码实现. 2.基本概念 (1)线性可分 首先介绍一下什么叫线性可分,引用一张上一节的图.线性可分实际上就是可以用一条直线将两种不同的点区分开来.由此我们

【机器学习算法-python实现】svm支持向量机(1)—理论知识介绍

(转载请注明出处:http://blog.csdn.net/buptgshengod) 1.背景      强烈推荐阅读(http://www.cnblogs.com/jerrylead/archive/2011/03/13/1982639.html)          支持向量机SVM(support vector machines).SVM是一种二值分类器,是近些年比较流行的一种分类算法. 本文,首先要介绍一些基本的知识概念,在下一章将对SVM进行简单地代码实现. 2.基本概念 (1)线性可

人工神经网络(Artificial Neural Netwroks)笔记-离散单输出感知器算法

最近在重新学习人工神经网络(Artificial Neural Netwroks),做做笔记,整理思路 离散单输出感知器算法,传说中的MP 二值网络:自变量及其函数的值.向量分量的值只取0和1函数.向量 权向量:W=(w1,w2,w3.....wn) 输入向量:X=(x1,x2,x3.....xn) 训练样本集 {(X,Y)|Y为输入向量X的输出} 训练过程比较简单 如下: 1,初始化权向量W 2,重复下列过程,直到训练完成: 2.1对每个样本(X,Y),重复如下过程: 2.1.1输入X 2.1

基于Spark如何实现SVM算法?这里有一份详尽的开发教程(含代码)

支持向量机SVM(Support Vector Machine)是一种有监督的学习模型,它的核心有两个:一.核函数(kernel trick):二.序列最小优化算法SMO(Sequential minimal optimization)是John Platt在1996年发布的用于训练SVM的有效算法.本文不打算细化SVM支持向量机的详细推倒算法,只涉及以上两点的内容做一个说明,最后给出算法实现和一个实验对比图.   核函数 核函数在处理复杂数据时效果显著,它的做法是将某一个维度的线性不可分数据采

SVM在车牌字符识别中的应用

1 引言 车牌识别是http://www.aliyun.com/zixun/aggregation/13918.html">智能交通系统的一个重要研究课题,存在巨大的市场需求.车牌识别系统分车辆图像的获取.车牌的定位与字符分割.车牌字符识别3大部分.对于车牌字符识别,目前最常用的方法是基于模板匹配的方法和基于神经网络的方法两大类.前者多利用了字符的轮廓.网格.投影等统计特征,相似字符区分能力差,且因特征数据维数过大会导致识别速度慢:而后者则存在网络输入数据的选择和网络结构设计等问题. 目前

《Mastering Opencv ...读书笔记系列》车牌识别(I)

一.ANPR简介:   Automatic Number Plate Recognition (ANPR),,是一种使用Optical Character Recognition (OCR)和其他分割.检测方法来读取汽车注册牌照的算法.最好的ANPR算法结果是由红外线照相机拍摄图片得到的.因为车牌的特殊材质,夜间会有逆反射效果,看不清车牌.但是现在我们不使用IR图片,我们使用常规图片,这样就增加了我们检测错误和识别错误的等级,以显示我们的算法有多牛逼[老外的意思,有逆反射的图片我没试过].下面给