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

来源:互联网 发布:解手机密码软件 编辑:程序博客网 时间:2024/06/05 14:11

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都是ynzn的组合,可以看成是由原始的数据表示出来的:

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

b:

[[-3.83903814]]

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

[[ 0.12744319  0.24145985  0.36890304]]

这里写图片描述

阅读全文
0 0
原创粉丝点击