支持向量机(SVM)简介

来源:互联网 发布:淘宝买的京东e卡假的 编辑:程序博客网 时间:2024/05/18 01:44

本文主要参考于http://www.cnblogs.com/steven-yang/p/5658362.html

基本概念:

支持向量机(Support Vector Machine,SVM)是一种解决二元分类问题的方法。它根据实验数据中的部分数据来确定分类器,这些部分数据叫做支持向量。“机”是指分类器。接下来通过实例更加直观的理解支持向量机。


这里写图片描述
图1、支持向量机实例

图1中的中间黑线将实验数据分为两类,这条黑线表示的超平面就是分类器。图1中的G、R、S点和其他接近于中间黑线的点叫做支持向量,这些点决定了分类器模型的具体参数。

线性分类:

训练数据具有n个属性和一个类别,这些数据可以映射到一个n维空间中,根据一个(n-1)维的超平面能将n维的训练数据分为两类。从图1中可以发现这种超平面有很多,我们从中选择出最优的一个,因此需要增加一个约束条件。距离每个类别中最近点的距离最大的超平面作为最优超平面(图1中距离G、R、S这三个点的间隔之和最大的超平面)。因此在线性分类中的分类器也称为最大间隔分类器。
线性分类函数(超平面函数):


这里写图片描述

其中w和b是需要训练的参数。

具体步骤:

1. 问题描述:

支持向量机的目的是寻找最优超平面这里写图片描述,即求出w和b。w和b通过找到距离超平面最近的点以及点到超平面的最大间隔来确定。训练数据集可分为两类,C1和C2。
超平面函数为:


这里写图片描述

C1类的数据这里写图片描述≥1,其中至少含有一个点这里写图片描述使得这里写图片描述,
C2类的数据这里写图片描述≤-1,其中至少含有一个点这里写图片描述使得这里写图片描述,
这里写图片描述这里写图片描述的真实分类情况(1或-1)
将其合并可得到:


这里写图片描述≥1

2.最大间隔:

接下来计算最近点的最大间隔。任意点到超平面的距离为这里写图片描述,最近点到超平面的距离为这里写图片描述 ,因此求最大间隔变为在这里写图片描述的约束条件下求这里写图片描述的最小值。

3.拉格朗日乘子法和KKT条件:

我们需要使用拉格朗日乘子法和KKT条件来求这里写图片描述的最小值。这种方法用来求解有不等式约束的优化问题。
在该问题中约束条件为:


这里写图片描述

最优化问题为求解这里写图片描述的最小值
拉格朗日函数可写为:


这里写图片描述

令w和b的偏导为0,可得到:


这里写图片描述

使用α来表示w和b并代入拉格朗日函数得到:


这里写图片描述

到目前为止问题变为求解α和b。
拉格朗日乘子法和KKT条件原理请参考:http://blog.csdn.net/xianlingmao/article/details/7919597

4.SMO方法:

使用SMO(Sequential Minimal Optimization)方法来求解α和b。SMO方法的中心思想是每次取一对这里写图片描述,调整这两个值。它的参数包含训练数据,数据标签,常数(C),松弛变量(ξ)和最大迭代数。求出α后即可求得对应的w。
SMO方法原理请参考:http://blog.csdn.net/luoshixian099/article/details/51227754

具体代码如下:

# -*- coding: utf-8 -*-__author__ = 'Wsine'from numpy import *import matplotlib.pyplot as pltimport operatorimport timedef loadDataSet(fileName): #上传实验数据    dataMat = []    labelMat = []    with open(fileName) as fr:        for line in fr.readlines():            lineArr = line.strip().split()            dataMat.append([float(lineArr[0]), float(lineArr[1])])            labelMat.append(float(lineArr[2]))    return dataMat, labelMatdef selectJrand(i, m):#随机选择一个α    j = i    while (j == i):        j = int(random.uniform(0, m))    return jdef clipAlpha(aj, H, L):#调整大于H或小于L的α值    if aj > H:        aj = H    if L > aj:        aj = L    return ajclass optStruct:    def __init__(self, dataMatIn, classLabels, C, toler):        self.X = dataMatIn        self.labelMat = classLabels        self.C = C        self.tol = toler        self.m = shape(dataMatIn)[0]        self.alphas = mat(zeros((self.m, 1)))        self.b = 0        self.eCache = mat(zeros((self.m, 2)))def calcEk(oS, k):#计算误差Ek    fXk = float(multiply(oS.alphas, oS.labelMat).T * (oS.X * oS.X[k, :].T)) + oS.b    Ek = fXk - float(oS.labelMat[k])    return Ekdef selectJ(i, oS, Ei):#选择第二个α    maxK = -1    maxDeltaE = 0    Ej = 0    oS.eCache[i] = [1, Ei]    validEcacheList = nonzero(oS.eCache[:, 0].A)[0]    if (len(validEcacheList)) > 1:        for k in validEcacheList:            if k == i:                continue            Ek = calcEk(oS, k)            deltaE = abs(Ei - Ek)            if (deltaE > maxDeltaE):                maxK = k                maxDeltaE = deltaE                Ej = Ek        return maxK, Ej    else:        j = selectJrand(i, oS.m)        Ej = calcEk(oS, j)    return j, Ejdef updateEk(oS, k):#更新误差Ek    Ek = calcEk(oS, k)    oS.eCache[k] = [1, Ek]def innerL(i, oS):#选择第一个变量α    Ei = calcEk(oS, i)    if ((oS.labelMat[i] * Ei < -oS.tol) and (oS.alphas[i] < oS.C)) or ((oS.labelMat[i] * Ei > oS.tol) and (oS.alphas[i] > 0)):        j, Ej = selectJ(i, oS, Ei)        alphaIold = oS.alphas[i].copy()        alphaJold = oS.alphas[j].copy()        if (oS.labelMat[i] != oS.labelMat[j]):            L = max(0, oS.alphas[j] - oS.alphas[i])            H = min(oS.C, oS.C + oS.alphas[j] - oS.alphas[i])        else:            L = max(0, oS.alphas[j] + oS.alphas[i] - oS.C)            H = min(oS.C, oS.alphas[j] + oS.alphas[i])        if (L == H):            # print("L == H")            return 0        eta = 2.0 * oS.X[i, :] * oS.X[j, :].T - oS.X[i, :] * oS.X[i, :].T - oS.X[j, :] * oS.X[j, :].T        if eta >= 0:            # print("eta >= 0")            return 0        oS.alphas[j] -= oS.labelMat[j] * (Ei - Ej) / eta        oS.alphas[j] = clipAlpha(oS.alphas[j], H, L)        updateEk(oS, j)        if (abs(oS.alphas[j] - alphaJold) < 0.00001):            # print("j not moving enough")            return 0        oS.alphas[i] += oS.labelMat[j] * oS.labelMat[i] * (alphaJold - oS.alphas[j])        updateEk(oS, i)        b1 = oS.b - Ei - oS.labelMat[i] * (oS.alphas[i] - alphaIold) * oS.X[i, :] * oS.X[i, :].T - oS.labelMat[j] * (oS.alphas[j] - alphaJold) * oS.X[i, :] * oS.X[j, :].T        b2 = oS.b - Ei - oS.labelMat[i] * (oS.alphas[i] - alphaIold) * oS.X[i, :] * oS.X[j, :].T - oS.labelMat[j] * (oS.alphas[j] - alphaJold) * oS.X[j, :] * oS.X[j, :].T        if (0 < oS.alphas[i]) and (oS.C > oS.alphas[i]):            oS.b = b1        elif (0 < oS.alphas[j]) and (oS.C > oS.alphas[j]):            oS.b = b2        else:            oS.b = (b1 + b2) / 2.0        return 1    else:        return 0def smoP(dataMatIn, classLabels, C, toler, maxIter, kTup=('lin', 0)):#利用SMO算法求解α和b    """    输入:数据集, 类别标签, 常数C, 容错率, 最大循环次数    输出:目标b, 参数alphas    """    oS = optStruct(mat(dataMatIn), mat(classLabels).transpose(), C, toler)    iterr = 0    entireSet = True    alphaPairsChanged = 0    while (iterr < maxIter) and ((alphaPairsChanged > 0) or (entireSet)):        alphaPairsChanged = 0        if entireSet:            for i in range(oS.m):                alphaPairsChanged += innerL(i, oS)            # print("fullSet, iter: %d i:%d, pairs changed %d" % (iterr, i, alphaPairsChanged))            iterr += 1        else:            nonBoundIs = nonzero((oS.alphas.A > 0) * (oS.alphas.A < C))[0]            for i in nonBoundIs:                alphaPairsChanged += innerL(i, oS)                # print("non-bound, iter: %d i:%d, pairs changed %d" % (iterr, i, alphaPairsChanged))            iterr += 1        if entireSet:            entireSet = False        elif (alphaPairsChanged == 0):            entireSet = True        # print("iteration number: %d" % iterr)    return oS.b, oS.alphasdef calcWs(alphas, dataArr, classLabels):#根据α求解w    """    输入:alphas, 数据集, 类别标签    输出:目标w    """    X = mat(dataArr)    labelMat = mat(classLabels).transpose()    m, n = shape(X)    w = zeros((n, 1))    for i in range(m):        w += multiply(alphas[i] * labelMat[i], X[i, :].T)    return wdef plotFeature(dataMat, labelMat, weights, b):#输出可视图    dataArr = array(dataMat)    n = shape(dataArr)[0]    xcord1 = []; ycord1 = []    xcord2 = []; ycord2 = []    for i in range(n):        if int(labelMat[i]) == 1:            xcord1.append(dataArr[i, 0])            ycord1.append(dataArr[i, 1])        else:            xcord2.append(dataArr[i, 0])            ycord2.append(dataArr[i, 1])    fig = plt.figure()    ax = fig.add_subplot(111)    ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')    ax.scatter(xcord2, ycord2, s=30, c='green')    x = arange(2, 7.0, 0.1)    y = (-b[0, 0] * x) - 10 / linalg.norm(weights)    ax.plot(x, y)    plt.xlabel('X1'); plt.ylabel('X2')    plt.show()def main():    trainDataSet, trainLabel = loadDataSet('E:/testSet.txt')    b, alphas = smoP(trainDataSet, trainLabel, 0.6, 0.0001, 40)    ws = calcWs(alphas, trainDataSet, trainLabel)    print("ws = \n", ws)    print("b = \n", b)    plotFeature(trainDataSet, trainLabel, ws, b)if __name__ == '__main__':    start = time.clock()    main()    end = time.clock()    print('finish all in %s' % str(end - start))

实验数据如下:

3.542485    1.977398    -13.018896    2.556416    -17.551510    -1.580030   12.114999    -0.004466   -18.127113    1.274372    17.108772    -0.986906   18.610639    2.046708    12.326297    0.265213    -13.634009    1.730537    -10.341367    -0.894998   -13.125951    0.293251    -12.123252    -0.783563   -10.887835    -2.797792   -17.139979    -2.329896   11.696414    -1.212496   -18.117032    0.623493    18.497162    -0.266649   14.658191    3.507396    -18.197181    1.545132    11.208047    0.213100    -11.928486    -0.321870   -12.175808    -0.014527   -17.886608    0.461755    13.223038    -0.552392   -13.628502    2.190585    -17.407860    -0.121961   17.286357    0.251077    12.301095    -0.533988   -1-0.232542   -0.547690   -13.457096    -0.082216   -13.023938    -0.057392   -18.015003    0.885325    18.991748    0.923154    17.916831    -1.781735   17.616862    -0.217958   12.450939    0.744967    -17.270337    -2.507834   11.749721    -0.961902   -11.803111    -0.176349   -18.804461    3.044301    11.231257    -0.568573   -12.074915    1.410550    -1-0.743036   -1.736103   -13.536555    3.964960    -18.410143    0.025606    17.382988    -0.478764   16.960661    -0.245353   18.234460    0.701868    18.168618    -0.903835   11.534187    -0.622492   -19.229518    2.066088    17.886242    0.191813    12.893743    -1.643468   -11.870457    -1.040420   -15.286862    -2.358286   16.080573    0.418886    12.544314    1.714165    -16.016004    -3.753712   10.926310    -0.564359   -10.870296    -0.109952   -12.369345    1.375695    -11.363782    -0.254082   -17.279460    -0.189572   11.896005    0.515080    -18.102154    -0.603875   12.529893    0.662657    -11.963874    -0.365233   -18.132048    0.785914    18.245938    0.372366    16.543888    0.433164    1-0.236713   -5.766721   -18.112593    0.295839    19.803425    1.495167    11.497407    -0.552916   -11.336267    -1.632889   -19.205805    -0.586480   11.966279    -1.840439   -18.398012    1.584918    17.239953    -1.764292   17.556201    0.241185    19.015509    0.345019    18.266085    -0.230977   18.545620    2.788799    19.295969    1.346332    12.404234    0.570278    -12.037772    0.021919    -11.727631    -0.453143   -11.979395    -0.050773   -18.092288    -1.372433   11.667645    0.239204    -19.854303    1.365116    17.921057    -1.327587   18.500757    1.492372    11.339746    -0.291183   -13.107511    0.758367    -12.609525    0.902979    -13.263585    1.367898    -12.912122    -0.202359   -11.731786    0.589096    -12.387003    1.573131    -1

在E盘新建一个testSet.txt文件,将实验数据拷贝进去即可。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 笔记本外壳a面裂了怎么办 苹果手机外壳摔坏了怎么办 挂衣服肩膀出包怎么办 摩拜单车手机号注销了怎么办 摩拜单车手机号码换了怎么办 摩拜单车换手机号码打不开怎么办 摩拜单车丢了怎么办 摩拜单车忘锁了怎么办 透明手机壳粘指纹怎么办 tpu手机壳变黄了怎么办 0pp0手机声音小怎么办 橡胶皮套晒坏了怎么办 宝宝晚上吹空调发烧怎么办 玩手机手指尖疼怎么办 手机型号不支持微信运动怎么办 手腕向下压会疼怎么办 手腕韧带拉伤怎么办恢复快 华为手机用车载充电慢怎么办 华为麦芒6充电慢怎么办 oppo手机压弯了怎么办 麦芒5电池不耐用怎么办 华为7x照相模糊怎么办 华为麦芒6照相虚怎么办 荣耀8gps信号弱怎么办 华为麦芒4手机卡顿怎么办 华为麦芒4玩游戏卡怎么办 sim卡换卡通讯录丢了怎么办 换sim卡通讯录怎么办 麦芒4开不了机怎么办 麦芒5开不了机怎么办 麦芒6针丢了怎么办 麦芒6扬声器坏了怎么办 华为手机2s太卡怎么办 华为麦芒6网速慢怎么办 华为麦芒5太卡怎么办 小米note3拍照反应慢怎么办 华为刷机后还要账号密码怎么办 刷机后忘记华为账号和密码怎么办 荣耀7x耗电快怎么办 小米2s死机后怎么办? 电信合约卡不想用了怎么办