《机器学习实战》(六)—— SVM(SMO算法)

作者: 033a1d1f0c58 | 来源:发表于2017-08-14 21:14 被阅读185次

    http://blog.csdn.net/u011239443/article/details/77170119
    关于SVM的讲解可以参阅《机器学习技法》的相关笔记:http://blog.csdn.net/u011239443/article/details/76572743

    SMO算法

    实现

    # -*- coding: utf-8 -*-
    from numpy import *
    # 加载数据
    def loadDataSet(fileName):
        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
    
    # 从0到m中产生一个不为i的整数
    def selectJrand(i,m):
        j = i
        while(j == i):
            j = int(random.uniform(0,m))
        return j
    
    # 使得aj 在边界值[L,H]以内
    def clipAlpha(aj,H,L):
        if aj > H:
            aj = H
        if L > aj:
            aj = L
        return aj
    
    
    #SMO 序列最小优化
    def smoSimple(dataMatIn,classLabels,C,toler,maxIter):
        # 这里书上的代码有误,不用mat(classLabels)不用转置
        dataMat = mat(dataMatIn);labelMat = mat(classLabels);
        b = 0;m,n = shape(dataMat)
        alphas = mat(zeros((m,1)))
        iter = 0
        # alphaPairsChanged 用来更新的次数
        # 当遍历  连续无更新 maxIter 轮,则认为收敛,迭代结束 
        while iter < maxIter:
            alphaPairsChanged = 0
            for i in range(m):
                # KKT 条件计算出
                fXi = float(multiply(alphas,labelMat).T * (dataMat*dataMat[i,:].T))+b
                # 误差
                Ei = fXi - float(labelMat[i])
                # toler:容忍错误的程度
                # labelMat[i]*Ei < -toler 则需要alphas[i]增大,但是不能>=C
                # labelMat[i]*Ei > toler 则需要alphas[i]减小,但是不能<=0
                if ((labelMat[i]*Ei < -toler) and (alphas[i] < C)) or ((labelMat[i]*Ei > toler) and (alphas[i] > 0)):
                    # 从0到m中产生一个不为i的整数
                    j = selectJrand(i,m)
                    fXj = float(multiply(alphas,labelMat).T * (dataMat*dataMat[j,:].T)+b)
                    Ej = fXj - float(labelMat[j])
                    alphaIold = alphas[i].copy()
                    alphaJold = alphas[j].copy()
                   # 算法讲解“二变量优化问题”部分
                    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
                    
                   # 见式 7.107
                    eta = -2.0* dataMat[i,:] * dataMat[j,:].T + dataMat[i,:] *\
                                                                dataMat[i,:].T + dataMat[j,:] * dataMat[j,:].T
                    if eta <= 0:print "eta <= 0";continue
                    # 见式 7.106
                    alphas[j] += labelMat[j]*(Ei-Ej)/eta
                    # 见式 7.108 ,讲alphas[j] 约束在 [L,H]
                    alphas[j] = clipAlpha(alphas[j],H,L)
                    if(abs(alphas[j] - alphaJold) < 0.00001):
                        print "j not moving"
                   # 见式 7.109
                    alphas[i] += labelMat[j]*labelMat[i]*(alphaJold-alphas[j])
                   # 见式 7.114
                    b1 = b - Ei -labelMat[i]*(alphas[i]-alphaIold)*dataMat[i,:]*dataMat[i,:].T\
                         - labelMat[j]*(alphas[j]-alphaJold)*dataMat[i,:]*dataMat[j,:].T
                    b2 = b - Ej - labelMat[i] * (alphas[i] - alphaIold) * dataMat[i, :] * dataMat[j, :].T \
                         - labelMat[j] * (alphas[j] - alphaJold) * dataMat[j, :] * dataMat[j, :].T
    
                    if  (0 < alphas[i]) and (C > alphas[i]):
                        b = b1
                    elif (0 < alphas[j]) and (C > alphas[j]):
                        b = b2
                    else:
                        b = (b1+b2)/2.0
    
                    alphaPairsChanged += 算法1
                    print "iter: %d i:%d pairs: %d" %(iter,i,alphaPairsChanged)
    
            if alphaPairsChanged == 0:
                iter += 1
            else:
                iter = 0
            print "iter %d" %iter
    
        return b,alphas
    

    SOM背后的含义

    我们来看下SVM的对偶问题:

    没错,我们在不断的调整alphas,其实就是在不断的调整alpha来优化问题。

    就如我们在《机器学习技法》中说的,无论是SVM 还是 PLA,w都是$y_nz_n$的组合,可以看成是由原始的数据表示出来的:

    而有些数据中的记录没用,我们就将它的alpha调整为0,有用记录 alpha > 0。所谓的有用的,也就是我们边界上边的点,即支持向量。

    b:

    [[-3.83903814]]
    

    alphas[alphas>0],即支持向量所对应的alpha:

    [[ 0.12744319  0.24145985  0.36890304]]
    

    相关文章

      网友评论

        本文标题:《机器学习实战》(六)—— SVM(SMO算法)

        本文链接:https://www.haomeiwen.com/subject/ofkprxtx.html