该简易算法其实完成的任务很简单,就是违反KKT条件的alpha进行符合KKT条件,然后通过不在边界的点进行迭代,然后使其alpha稳定下来下面的代码基本每一句都进行了详细的解释,具体看代码,但是建议没搞懂参数是如何更新的同学,一旦把上一篇的参数更新方法彻底搞懂,下一篇将编写完整的SMO代码,然后在详细阐释其工作原理的来龙去脉,这个简单的smo算法主要集中在处理更新方面,并没有考虑优化计算速度,因此下一节将详细解释该算法的实现,本代码参考机器学习实战的代码,代码如下:

#!/usr/bin/env/python
# -*- coding: utf-8 -*-
# Author: 赵守风
# File name: SMO_simplify.py
# Time:2018/10/22
# Email:1583769112@qq.com
import numpy as np#  数据处理
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# 选择j不等于i的数据
def selectJrand(i, m):j = i #we want to select any J not equal to iwhile (j==i):j = int(np.random.uniform(0,m))return j# smo的约束条件,前面详解了即    0 ≤alphas≤C,即边界限制
def clipAlpha(aj, H, L):if aj > H:aj = Hif L > aj:aj = Lreturn aj# 简化版SMO算法
def smoSimple(dataMatIn, classLabels, C, toler, maxIter):dataMatrix = np.mat(dataMatIn)  # 把数据转换成numpy的矩阵形式labelMat = np.mat(classLabels).transpose()  # 同样处理,同时进行转置处理,此时的标签就是列向量了b = 0   # 初始化bm,n = np.shape(dataMatrix)  # 获得数据的维度即m行n列,也可以看成是m个样本数据,每个样本有n特征alphas = np.mat(np.zeros((m, 1)))  # 初始化alphas,因为alphas是针对每一个样本数据,因此需要m行1列iter = 0  # 迭代次数,即记录的是alpha没有任何改变的情况下遍历数据的次数while (iter < maxIter):  # 当遍历次数达到最大时退出循环alphaPairsChanged = 0  # 大循环,对整个数据集遍历,该变量记录alpha是否已经被优化,循环结束才能知道for i in range(m):# 下面的式子其实就是f(x) = ∑alpha_i*y_i*<x_i,x> + b,前面理论也详细讲了这一点,就是预测x的类别fXi = float(np.multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[i,:].T)) + b# 下面就是求在真实值和预测值的差即:E_i = f(x_i) - y_i,其中f是预测值,y是真实分类值Ei = fXi - float(labelMat[i]) #if checks if an example violates KKT conditions# 下面就是界定非边界的alpha,正负间隔都会被测试,筛选满足KKT条件的,在边界上的alpha等于0或者C,则不再优化if ((labelMat[i]*Ei < -toler) and (alphas[i] < C)) or ((labelMat[i]*Ei > toler) and (alphas[i] > 0)):j = selectJrand(i,m) # 选择第二个alpha值# 下面是求预测值f(x_j)同上解释fXj = float(np.multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[j,:].T)) + b# 下面是计算误差Ej = fXj - float(labelMat[j])# 存储更新前的alpha值,在更新时或者比较时使用alphaIold = alphas[i].copy()alphaJold = alphas[j].copy()# 判断选择的i,j数据的标签是否异号,开始计算L和Hif (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  # 如果相等,直接跳出本次for循环,直接执行下一次for循环# eta,大家还记得上篇的参数更新里的:K_11 + K_22 - 2K_12吗,其实就是这个eta,有点不同,是因为假设条件不一样,但是原理相同eta = 2.0 * dataMatrix[i,:]*dataMatrix[j,:].T - dataMatrix[i,:]*dataMatrix[i,:].T - dataMatrix[j,:]*dataMatrix[j,:].Tif eta >= 0: print("eta>=0") ; continue # 满足KKT条件,跳出该循序alphas[j] -= labelMat[j]*(Ei - Ej)/eta # 否则更新alphaalphas[j] = clipAlpha(alphas[j],H,L)  # 加入约束条件if (abs(alphas[j] - alphaJold) < 0.00001):# 查看更新后的alpha是否满足条件,即变化大不大,如果不大,说明该alpha已经趋于稳定了,不用继续更新了print("j not moving enough")continue# 同理对i也进行更新,不同的是更新方向不同,这里是加,而j是减,注意细节。忘记的查看一下上篇的alpha1是如何更新的alphas[i] += labelMat[j]*labelMat[i]*(alphaJold - alphas[j])#update i by the same amount as j#the update is in the oppostie direction# 更新b,和上篇的解释是一样的,看不懂的继续看理论b1 = b - Ei- labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[i,:].T - labelMat[j]*(alphas[j]-alphaJold)*dataMatrix[i,:]*dataMatrix[j,:].Tb2 = b - Ej- labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[j,:].T - labelMat[j]*(alphas[j]-alphaJold)*dataMatrix[j,:]*dataMatrix[j,:].Tif (0 < alphas[i]) and (C > alphas[i]): b = b1elif (0 < alphas[j]) and (C > alphas[j]): b = b2else: b = (b1 + b2)/2.0alphaPairsChanged += 1 # 当运行到这里说明alpha已经进行更新了,因此加一print("iter: %d i:%d, pairs changed %d" % (iter,i,alphaPairsChanged))if (alphaPairsChanged == 0): iter += 1else: iter = 0print("iteration number: %d" % iter)return b, alphas

下面给出测试代码和测试结果:

#!/usr/bin/env/python
# -*- coding: utf-8 -*-
# Author: 赵守风
# File name: test.py
# Time:2018/10/23
# Email:1583769112@qq.com
import SMO_simplifydataarr, labelarr = SMO_simplify.loadDataSet('testSet.txt')
print(labelarr)b, alphas = SMO_simplify.smoSimple(dataarr, labelarr, 0.6, 0.0001, 40)
print('b 的值为:', b)
print('alphas[alphas>0]: ', alphas[alphas > 0])for i in range(100):if alphas[i] > 0.0:print('dataarr[i],labelarr[i]为:', dataarr[i], labelarr[i])

测试结果:

......
........
........
iteration number: 38
j not moving enough
j not moving enough
iteration number: 39
j not moving enough
j not moving enough
iteration number: 40
b 的值为: [[-3.87921175]]
alphas[alphas>0]:  [[0.08331274 0.27824106 0.04908614 0.31246766]]
dataarr[i],labelarr[i]为: [4.658191, 3.507396] -1.0
dataarr[i],labelarr[i]为: [3.457096, -0.082216] -1.0
dataarr[i],labelarr[i]为: [5.286862, -2.358286] 1.0
dataarr[i],labelarr[i]为: [6.080573, 0.418886] 1.0

机器学习--支持向量机实战(二)简易SMO算法实现相关推荐

  1. 机器学习--支持向量机(四)SMO算法详解

    上篇我们讲到,线性和非线性都转化为求解的问题即: 求解的方法就是SMO算法,下面详细介绍SMO算法: 在讲解SMO算法之前先说明一下讲解思路,首先先帮助大家理解这个式子,说明推倒的过程细节,然后和原论 ...

  2. c语言期中项目实战二—简易扫雷,思路分析加代码详细注释

    c语言期中项目实战二-简易扫雷,思路分析+代码详细注释 游戏介绍 项目步骤 模块化编程 设置菜单 设置棋盘 打印棋盘 布置雷 排查雷 总结及总代码和详细注释 游戏介绍 扫雷这个经典游戏,直到现在仍有很 ...

  3. 机器学习--支持向量机实战(三)完整版SMO算法实现

    完整版和简化版的smo不通之处在于alpha的选择方式上,alpha的更改和代数运算和简化版本,完整版的alpha的选择方式采用了启发式进行选择,前面文章已经详解了,这里再简单的叙述一下: Platt ...

  4. 支持向量机smo matlab,理解支持向量机(三)SMO算法

    在支持向量机模型的求解中,我们用到了SMO算法来求解向量α. 那么什么是SMO算法?在讲SMO算法之前.我们须要先了解下面坐标上升法. 1.坐标上升法 如果有优化问题: W是α向量的函数.利用坐标上升 ...

  5. 机器学习笔记(十)——这样推导SMO算法才易理解

    线性支持向量机 上一篇文章对支持向量机的间隔.对偶和KKT条件做了详细推导,但前文的基础是原始问题为线性可分问题,所以对线性不可分训练数据是不适用的,这时需要引入一个新定义:软间隔. 假如训练数据中有 ...

  6. 机器学习:SVM训练,SMO算法描述,启发式选择样本或变量

    文章目录 优化目标: 优化步骤: 对偶问题本质: 选择第一个样本点标准: 选择第一个样本点标准为:最不满足KKT条件的样本 如何判断样本点是否满足KKT条件? 满足和不满足KKT的情况: 量化不满足K ...

  7. 机器学习--支持向量机实战(四)核函数实现

    这节和上一节很像,不同的是,上一篇的是通过支持向量和待分类数据內积进行分类的,只是这里不同的是,在计算內积时使用核函数进行代替,这里参考的是机器学习实战中的核函数,如果前面理解的比较深入,读代码还是很 ...

  8. 机器学习--支持向量机(二)拉格朗日乘子法详解

    上节我们从线性回归模型出发详细阐述了支持向量的来源,以及为什么需要寻找支持向量,如何找到这决策函数等问题,最后问题转化为下面的求最大值问题: 先说明一下分类就是如果:          则被分为    ...

  9. 【数据科学系统学习】机器学习算法 # 西瓜书学习记录 [8] 支持向量机(二)...

    这两篇内容为西瓜书第 6 章支持向量机 6.1,6.2,6.4,6.3 的内容: 6.1 间隔与支持向量 6.2 对偶问题 6.4 软间隔与正则化 6.3 核函数 由于本章内容较多,分为两篇来叙述.本 ...

最新文章

  1. Duktape 集成
  2. ngx_http_redis_module配置使用
  3. hdu--Number Sequence
  4. python3.9.0_Python 3.9.0 alpha 1 发布了,3.9 系列首个迭代版本
  5. x86虚拟机NXVM_Centos6.5 x86_64系统安装kvm虚拟机—基础篇
  6. linux 取消证书登录密码,SUSELinux 中为 SSH 访问设置不输入密码的证书认证登录方式...
  7. mysql5.6.24怎么打开_mysql 5.6.24 安装配置方法图文教程
  8. asp服务器_Asp.Net Core2.2从环境配置到应用建立
  9. 【线性代数本质】4:矩阵乘法本质
  10. codeforces 361 D. Levko and Array(dp+二分)
  11. PDA应用的一些想法
  12. 在线JSON在线对比差异工具
  13. Java - 生成健康证图片,各种模板图片
  14. 通讯录管理系统(C语言版)
  15. signature=506ccff074d130c2e8d4e3268d3b44f1,Secure proxy signature schemes from the Weil pairing
  16. 新版标准日本语中级_第十八课
  17. 微信小程序-视频弹幕的项目
  18. 正高职称 程序员_研究员级高级工程师和高级工程师有什么区别,副研究员与高级工程师有什么差别...
  19. html整体垂直居中,让html img图片垂直居中的三种方法
  20. Maxwell电机电磁仿真笔记

热门文章

  1. [C++] Vector对象的合法定义
  2. Q91:真实地模拟透明材质(Realistic Transparency)
  3. 大数据可视化该如何实现
  4. Master公式求递归复杂度
  5. 年龄是计数还是计量_MSA你只知道计量型和计数型?有哪些类型?分别是什么方法?...
  6. l298n电机驱动模块使用方法_家用柴油发电机使用方法
  7. linux的poll_wait函数,select() 与 poll()两个函数接口的作用
  8. 李煜东算法进阶指南打卡题解
  9. c++优先队列小节(常常弄混)
  10. Shell脚本编程之(二)简单的Shell脚本练习