机器学习之支持向量机(六)

本文深入介绍了支持向量机(SVM),包括其最大间隔原理、SMO优化算法、核函数的应用以及在手写识别问题中的实践。通过SMO算法求解最佳分隔超平面,利用核函数解决非线性分类问题,展示了SVM在实际问题中的高效性和准确性。
摘要由CSDN通过智能技术生成

主要内容:
● 简单介绍支持向量机
● 利用SMO进行优化
● 利用核函数进行空间转换
● 将SVM和其他分类器进行比对

支持向量机(support vector machines,SVM),SVM有很多实现,我们现在来讲讲最流行的一种实现,即序列最小化(sequential minimal optimization,SMO)算法。


6.1 基于最大间隔分隔数据
● 优点:泛化错误率低,计算开销不大,结果易解释。
● 缺点:对参数调节和核函数的选择敏感,原始分类器不加修改仅适用于处理二类问题。
● 使用数据类型:数值型和标称型数据。

能将下列第一个图中的圆形点和方形点分开,这个分隔开的直线就是分隔超平面。
所给的数据点在二维平面上,分隔超平面就是一条直线。如果数据集是三维的,那么分隔数据的就是一个平面。如果数据集是N维的,那么N-1维的某某对象来对数据进行分隔,该对象被称之为 超平面,也就是分类的决策边界。

我们使用这种方式来构建分类器,如果数据点离决策边界越远,最后的预测结果就越可信。
点到分隔面的距离被称之为间隔。

支持向量(support vector)就是离分隔超平面最近的那些点。寻找最大的支持向量到分隔面的距离,找到这个问题的最优化求解方法。

这里写图片描述

6.2 寻找最大间隔
如何求解数据集的最佳分隔直线呢?
分隔超平面的形式可以写成: W^t *X + b
要计算点A到分隔超平面的距离,就必须给出点到分隔面的发现或垂线的长度,该值为,

| W^t *X + b | / || W ||

常数W和常数b给出了数据的分割线和超平面。

这里写图片描述

6.2.1 分类器求解的优化问题
输入数据个分类器输出一个类别标签,这相当于一个类似于是sigmoid的函数在起作用。
我们将使用类似海维塞德阶跃函数(即单位阶跃函数)的函数对W^t + b 作用得到
f (W^t + b) 。

当u<0 ,f(u) < -1
当u>0 ,f (u) > +1

我们采用 -1 和 1 ,而不是0 ,-1 ,是因为 -1 和 +1 仅仅相差一个符号,方便数学上的处理。

当计算数据点到分隔面的距离并确定分隔面的放置位置的时候,间隔通过 label * (W^t + b ) 来计算。

我们需要找到分类器定义的w和b,我们要找到具有最小间隔的数据点,而这些数据点也就是前面提到的支持向量。找到之后,我们需要对该间隔进行最大化:

这里写图片描述

直接求解上述公式将十分困难。

所以令 label * (W^t + b ) = 1 ,来求 || w || ^-1 的最大值来求解。

然而 label * (W^t + b ) 不全等于1, 存在距离分隔超平面最近的点的值为1 。

给出约束条件: label * (W^t + b ) >= 1

那么由于约束条件都是基于数据点的,

因此将超平面写成数据点的形式。目标函数写成:

这里写图片描述

这里有个假设:数据必须100%线性可分。约束条件为:

这里写图片描述

实际上,数据都几乎有那么多“不干净”,我们引入“松弛变量”,允许有些数据点可以处于分隔面错误的一侧。此时新的约束条件变为:

这里写图片描述

常熟C用于控制 ” 最大化间隔 ” 和 “ 保证大部分点的函数间隔小于1.0 ”这两个目标的权重。

6.2.2 SVM应用的一般框架

SVM的一般流程
1. 收集数据:可以使用任意方法
2. 准备数据:需要数值型数据。
3. 分析数据:有助于可视化的=分隔超平面
4. 训练算法:SVM的大部分时间都源自训练,该过程主要实现两个参数的调优
5. 测试算法:十分简单的计算过程就可以实现
6. 使用算法:几乎所有分类问题都可以使用SVM,值得一提的是,SVM本身是一个二类的分类器,对多类问题应用SVM需要对代码来做一些修改

6.3 SMO高效优化算法
6.3.1 Palatt的SMO算法

根据上面提到的,优化之后一个是最小化的目标函数,一个是优化过程需要遵循的约束条件。

算法SMO来训练SVM算法,SMO表示序列最小优化(sequential minimal optimization)。
SMO算法的目标是求出一系列的alpha 和 b ,从而计算出权重的向量w并得到分隔超平面。

SMO算法工作原理:每次循环中选择两个alpha 进行优化处理。
当(1)两个alpha在间隔的边界之外;(2)两个alpha未经过区间化处理或不在边界上 。此时 就算是找到了一对合适的alpha ,那么久增大其中一个同时减小另一个。

6.3.2 应用简化版SMO算法处理小规模数据集

SMO算法的完整实现需要大量的代码。我们先给出简化处理,以便于去了解算法的基本思路。


# SMO算法中的辅助函数
def loadDataSet(fileName):
    fileName = r"E:\ML\ML_source_code\mlia\Ch06\testSet.txt"
    dataMat = [];labelMat = []
    fr = open(fileName)
    for line in fr.readlines():
        lineArr = line.strip().split('\t')
        dataMat.append([float(lineArr[0]),float(lineArr[1])])
        labelMat.append(float(lineArr[2]))
    return dataMat,labelMat

def selectJrand(i,m):
    """
    i 是第一个alpha下标,m是所有alpha的数目
    """
    j = i
    while (j == i):
        j = int(np.random.uniform(0,m))
    return j

def clipAlpha(aj,H,L):
    if aj > H:
        aj = H
    if L > aj:
        aj = L
    return aj
"""
#SMO函数的伪代码
创建一个alpha向量并将其初始化为0向量
当迭代次数小于最大迭代次数时(外循环):
    对数据集中的每个数据向量(内循环):
        如果该数据向量可以被优化:
            随机选择另外一个数据向量
            同时优化这两个向量
            如果两个向量都不能被优化,退出内循环
    如果所有的向量都没有被优化,增加迭代项目,继续下一次循环
"""

● selectJrand()函数的两个参数,i 是第一个alpha下标,m是所有alpha的数目。只要函数不等
于输入值 i,函数就会进行随机选择。
● clipAlpha()函数用于调整大于H或者小于L的alpha值

测试一下代码,得到的标签是-1和1 ,而不是0和1

In [4]: import svm

In [5]: reload(svm)
Out[5]: <module 'svm' from 'svm.pyc'>

In [7]: fileName = r"E:\ML\ML_source_code\mlia\Ch06\testSet.txt"
   ...:

In [8]: dataArr,labelArr = svm.loadDataSet(fileName)

In [9]: labelArr
Out[9]:
[-1.0,
-1.0,
1.0,
-1.0,
....
-1.0,
-1.0,
-1.0]

6.4 利用完整的platt SMO算法加速优化
之所以要引进完整版的SMO算法,是因为简化版的算法运行速度太慢。

# 简化版SMO算法
def smoSimple(dataMatIn,classLabels,C,toler,maxIter):
    """
    函数(数据集,类别标签,常数C,容错率,退出前最大的循环次数)
    """
    dataMatrix = np.mat(dataMatIn); labelMat = np.mat(classLabels).transpose()
    b = 0; m,n = np.shape(dataMatrix)
    alphas = np.mat(np.zeros((m,1)))
    iter = 0
    while (iter < maxIter):
        aphaPairsChanged = 0
        for i in range(m):
            fXi = float(np.multiply(alphas,labelMat).T * (dataMatrix*dataMatrix[i,:].T)) + b
            Ei = fXi - float(labelMat[i])
            #如果alpha可以更改进入优化过程
            if ((labelMat[i]*Ei<-toler) and (alphas[i]<C)) or ((labelMat[i]*Ei>toler) and (alphas[i]>0)):
                #随机选择第二个alpha
                j = selectJrand(i,m)
                fXj = float(np.multiply(alphas,labelMat).T * (dataMatrix*dataMatrix[j,:].T)) + b
                Ej = fXj - float(labelMat[j])
                alphaIold = alphas[i].copy();
                alphaJold = alphas[i].copy();
                #保证alpha在0与C之间
                if (labelMat[i] != labelMat[j]):
                    L = max(0, alphas[j] - alphas[i])
                    H = min(C, C +  alphas[j] - alphas[i])
                else:
                    L = max(0, alphas[j] + alphas[i] - C)
                    H = min(C ,alphas[j] + alphas[i])
                if L==H:
                    print "L==H";continue
                eta = 2.0*dataMatrix[i,:]*dataMatrix[j,:].T-dataMatrix[i,:]*dataMatrix[i,:].T-dataMatrix[j,:]*dataMatrix[j,:].T
                if eta > 0:
                    print 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值