【Python机器学习】支持向量机——SMO高效优化算法

news2024/11/15 23:29:48

最小化的目标函数、优化过程中必须要遵循的额约束条件。不久之前,人们使用二次规划求解工具来解决上述最优化问题,这种工具是一种用于在线性约束下优化具有多个变量的二次目标函数的软件,而这些二次规划求解工具需要强大的计算能力支撑,另外在实现上也十分复杂。所有需要做的围绕优化的事情就是训练分类器,一旦得到alpha的最优值,我们就得到了分隔超平面并能够将之用于数据分类。

platt的SMO算法

SMO表示序列最小优化。platt的SMO算法时将大优化问题分解为多个小优化问题来求解的。这些小优化问题往往很容易求解,并且对它们进行顺序求解的结果与将它们作为整体来求解的结果是完全一致的。在结果完全相同的同时,SMO算法的求解时间短很多。

SMO算法的目标是求出一系列的alpha和b,一旦求出了这些alpha,就很容易计算出权重向量w并得到分隔超平面。

SMO算法的工作原理是:每次循环中选择两个alpha进行优化处理。一旦找到一对合适的alpha,那么就增大其中一个同时减少另一个。这里所谓的合适是指两个alpha必须要符合一定的条件,条件之一就是这两个alpha必须要在间隔边界之外,第二个条件则是这两个alpha还没有进行过区间化处理或者不在边界上。

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

首先在数据集上遍历每一个alpha,然后在剩下的alpha集合中随机选择另一个alpha,从而构建alpha对。这里有一点非常重要,就是我们要同时改变两个alpha,之所以这样做是因为我们有一个约束条件:

\sum _{i}\cdot label^{(i)}=0

由于改变一个alpha可能会导致改约束条件失效,因此我们总是同时改变两个alpha。

构建一个辅助函数,用于在某个区间范围内随机选择一个整数,同时,我们还需要另一个辅助函数,用于在数值太大时对其进行调整:

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
def selectJrand(i,m):
    j=i
    while(j==i):
        j=int(random.uniform(0,m))
    return j
def clipAlpha(aj,H,L):
    #用于调整大于H或小于L的alpha值
    if aj>H:
        aj=H
    if L>aj:
        aj=L
    return aj

运行验证:

dataArr,labelArr=loadDataSet('testSet.txt')
print(labelArr)

这类可以看出来,类别标签都是-1和1,而不是0和1.

下面是SMO第一个版本的伪代码:

创建一个alpha向量并将其初始化为0向量

当迭代次数小于最大迭代次数时(外循环):

    对数据集中的每个数据向量(内循环):

        如果该数据向量可以被优化:

            随机选择另外一个数据向量

            同时优化这两个向量

            如果两个向量都不能被优化,退出内循环

    如果所有向量都没被优化,增加迭代数目,继续下一次循环

下面是实现过程:

def smoSimple(dataMatIn,classLabels,C,toler,maxIter):
    #输入参数分别为:数据集、类别标签、常数C、容错率、退出前最大的循环次数
    #转换为mat矩阵,得到列向量
    dataMatrix=mat(dataMatIn)
    labelMat=mat(classLabels).transpose()
    b=0
    m,n=shape(dataMatrix)
    #alpha列矩阵,初始化为0
    alphas=mat(zeros((m,1)))
    #遍历数据集的次数,当iter=maxIter时,函数结束运行并退出
    iter=0
    while (iter<maxIter):
        #用来记录alpha是否已经进行优化。
        alphaPairsChanges=0
        for i in range(m):
            fXi=float(multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[i,:].T))+b
            #误差
            Ei=fXi-float(labelMat[i])
            #如果误差很大,可以对该数据实例对应的alpha值进行优化
            #另外,如果alpha小于0或者大于C将被调整为0或C,一旦他们等于这两个值,就不值得强化了
            if ((labelMat[i]*Ei<-toler) and (alphas[i]<C)) or ((labelMat[i]*Ei>toler) and (alphas[i]>0)):
                #如果alpha可以更改,进入优化过程
                j=selectJrand(i,m)
                #随机选择第二个alpha
                fXj=float(multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[j,:].T))+b
                # 继续计算误差值
                Ej=fXj-float(labelMat[j])
                #通过copy()实现
                alphaIold=alphas[i].copy()
                alphaJold=alphas[j].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为最优修改量,如果eta=0,需要退出循环的当前迭代过程。
                eta=2.0*dataMatrix[i,:]*dataMatrix[j,:].T-dataMatrix[i,:]*dataMatrix[i,:].T-dataMatrix[j,:]*dataMatrix[j,:].T
                if eta>=0:
                    print('eta>=0')
                    continue
                alphas[j]=alphas[j]-labelMat[j]*(Ei-Ej)/eta
                alphas[j]=clipAlpha(alphas[j],H,L)
                if (abs(alphas[j]-alphaJold)<=0.00001):
                    print('J没有足够移动')
                    continue
                #对i进行修改,修改量与j相同,但方向相反
                alphas[i]=alphas[i]+labelMat[j]*labelMat[i]*(alphaJold-alphas[j])
                #设置常数项
                b1=b-Ei-labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[i,:].T-labelMat[j]*(alphas[j]-alphaJold)*dataMatrix[i,:]*dataMatrix[j,:].T
                b2=b-Ej-labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[j,:].T-labelMat[j]*(alphas[j]-alphaJold)*dataMatrix[j,:]*dataMatrix[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
                alphaPairsChanges=alphaPairsChanges+1
        if alphaPairsChanges==0:
            iter=iter+1
        else:
            iter=0
    return b,alphas

实际运行:

dataArr,labelArr=loadDataSet('testSet.txt')
# print(labelArr)
b,alphas=smoSimple(dataArr,labelArr,0.6,0.001,40)
print(b)
print(alphas[alphas>0])

alphas[alphas>0]命令是数组过滤的一个实例,而且它只对NumPy类型有用,却并不适用于Python中的正则表,如果输入alpha>0,那么就会得到一个布尔数组,并且在不等式成立的情况下,其对应值是正确的。于是,在将该布尔数组应用到原始的矩阵当中时,就会得到一个NumPy矩阵,并且其中矩阵仅仅包含大于0的值。

为了得到支持向量的个数,输入:

print(shape(alphas[alphas>0]))
for i in range(100):
    if alphas[i]>0.0:
        print(dataArr[i],labelArr[i])

在原始数据集上对这些支持向量画圈后的结果如图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1975700.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文搞懂后端面试之数据库MySQL的各种锁以及锁优化【中间件 | 数据库 | MySQL | 锁机制】

锁与索引 在MySQL的InnoDB引擎里&#xff0c;锁是借助索引来实现的&#xff0c;加锁锁住的其实是索引项&#xff0c;更加具体的说&#xff0c;是锁住了叶子节点。 引出的问题&#xff1a; 一个表有很多索引&#xff0c;锁的是哪个索引呢&#xff1f; 答案是 查询最终使用的索…

AI2-CUDA、CuDNN、TensorRT的详细安装教程

一、查看本机的显卡 首先你要看你的电脑是否有NVIDIA的独立显卡&#xff0c;你可以在设备管理器-显示适配器中查看 点击“开始”--找到“NVIDA Control Panel” 点击帮助--系统信息--组件&#xff0c;查看NVCUDA.DLL对应的产品名称&#xff0c;就可以看住CUDA的版本号 这里的版…

P31结构体初阶 (1)

结构体的声明 结构体的基础知识 结构是一些值的集合&#xff0c;这些值成为成员变量。结构的每个成员可以是不同类型的变量。 结构体的声明 结构成员的类型 结构的成员可以是标量、数组、指针&#xff0c;甚至是其他结构体 结构体变量的定义和初始化 结构体成员的访问 结构…

AVL树图解(插入与删除)

文章目录 AVL树概念平衡因子 旋转左单旋更新父节点与孩子节点的连接 右单旋左右双旋 (先左单旋再右单旋)右左双旋 (先右单旋再左单旋)验证是否为AVL树ALV树的删除操作一. 高度不变删除叶子节点和单孩子节点1.1高度不变删除叶子节点1.2删除单孩子节点 二. 高度变化 - 旋转2.1 左…

基于JAVA的企业财务管理系统设计与实现

点击下载源码 基于JAVA的企业财务管理系统设计与实现 摘要 对于企业集来说,财务管理的地位很重要。随着计算机和网络在企业中的广泛应用&#xff0c;企业发展速度在不断加快&#xff0c;在这种市场竞争冲击下企业财务管理系统必须优先发展&#xff0c;这样才能保证在竞争中处…

第30届哈尔滨种博会提质升级,10月28-30日移师长春全新亮相!

紧扣农业新质生产力发展需要&#xff0c;持续推动区域种业发展和农业振兴&#xff0c;第30届哈尔滨种业博览会暨第19届哈尔滨农资博览会/北方现代农业设施设备展将于10月28-30日在长春东北亚国际博览中心举办。展会扎根东北&#xff0c;全面辐射北方地区&#xff0c;被东北地区…

50 IRF检测MAD-BFD

IRF 检测MAD-BFD IRF配置思路 网络括谱图 主 Ten-GigabitEthernet 1/0/49 Ten-GigabitEthernet 1/0/50 Ten-GigabitEthernet 1/0/51 备 Ten-GigabitEthernet 2/0/49 Ten-GigabitEthernet 2/0/50 Ten-GigabitEthernet 2/0/51 1 利用console线进入设备的命令行页…

C语言初阶(11)

1.结构体定义 结构体就是一群数据类型的集合体。这些数据类型被称为成员变量。结构的成员可以是标量、数组、指针&#xff0c;甚至是其他结构体。 2.结构体的声明和结构体变量命名与初始化 结构体声明由以下结构组成 struct stu {char name[12];int age; }; 结构体命名有两…

计算机毕业设计选题推荐-生活垃圾治理系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

解决卸载360安全卫士,报错“需要来自administrators权限才能对此文件夹进行更改”

卸载360卫士报错&#xff0c;见图&#xff1a; 解决过程&#xff1a; cmd 输入msconfig引导&#xff0c;勾上安全引导后确定立即重启进入安全模式然后进去360位置&#xff0c;进入文件夹后把所有都删除了 可能遇到的问题&#xff1a; 有个.dll的文件显示被其他进程访问删不掉…

Win11不在C盘安装WSL2(Linux环境),安装Nvidia驱动和默认使用Win11的网络代理服务

众所周知&#xff0c;WSL 2 为 Windows 用户提供了一个强大、高效且灵活的 Linux 环境&#xff0c;特别适合开发者使用。它结合了 Windows 和 Linux 的优点&#xff0c;为用户提供了更加全面和高效的工作环境。但缺点也很明显&#xff0c;那就是默认安装在本来空间就不富裕的C盘…

[一本通提高数位动态规划]恨7不成妻--题解--胎教级教学

[一本通提高数位动态规划]恨7不成妻--题解--胎教级教学 1前言2问题3化繁为简--对于方案数的求解&#xff08;1&#xff09;子问题的分解&#xff08;2&#xff09;数位dp-part1状态设置--利用约束条件推状态&#xff08;3&#xff09;数位dp-part2状态转移&#xff08;4&#x…

【leetcode详解】正方形中的最多点数【中等】(C++思路精析)

思路精析&#xff1a; 自定义结构体解读&#xff1a; 一个点是否在题给正方形中&#xff0c;只取决于其横纵坐标的最大值&#xff0c;记为dis 沟通二位数组points和字符串s的桥梁&#xff0c;就是这个点的序号&#xff0c;记为idx 由此自定义结构体&#xff0c;储存dis 和i…

JAVA中List不能创建实例。结合ArrayList的理解。

今天在使用List的时候&#xff0c;我以为List是一个父类&#xff0c;ArrayList继承自List&#xff0c;所以我想着干脆直接就创建一个List实例。结果发现程序报错了。 后来我查看了List源码&#xff0c;和ArrayList源码&#xff0c;我发现。List是一个接口&#xff0c;而ArrayL…

mac中dyld[99014]: Library not loaded: @rpath/libmysqlclient.24.dylib解决方法

将需要的库做个软链即可 sudo ln -s -f /usr/local/mysql-9.0.1-macos14-arm64/lib/libmysqlclient.24.dylib /usr/local/mysql/lib/libmysqlclient.24.dylib 再执行就不会报这个错误了&#xff0c;报的下一个需要的库

去噪扩散恢复模型

去噪扩散恢复模型 Bahjat Kawar 计算机科学系 以色列海法理工学院 bahjat.kawarcs.technion.ac.il Michael Elad 计算机科学系 以色列海法理工学院 eladcs.technion.ac.il Stefano Ermon 计算机科学系 美国加利福尼亚州斯坦福大学 ermoncs.stanford.edu …

ROS2 Linux Mint 22 安装教程

前言&#xff1a; 本教程在Linux系统上使用。 一、linux安装 移动硬盘安装linux&#xff1a;[LinuxToGo教程]把ubuntu装进移动固态&#xff0c;随时随用以下是我建议安装linux mint版本的清单&#xff1a; 图吧工具箱&#xff1a;https://www.tbtool.cn/linux mint: https://…

YAML基础语言深度解析

引言 YAML&#xff08;YAML Aint Markup Language&#xff0c;即YAML不是一种标记语言&#xff09;是一种直观、易于阅读的数据序列化格式&#xff0c;常用于配置文件、数据交换和程序间的通信。其设计目标是易于人类阅读和编写&#xff0c;同时也便于机器解析和生成。在本文中…

英伟达A100 GPU的核心数,Tesla系列

目录 GeForce RTX 什么意思 英伟达A100 GPU的核心数 A100概述 NVIDIA GPU GeForce系列(消费级) Quadro系列(专业级) Tesla系列(数据中心和AI) AMD GPU Radeon系列(消费级) 注意 GeForce RTX 什么意思 GeForce RTX是英伟达(NVIDIA)公司旗下的一个高端显卡系…

VS2019 新建项目里没有CUDA选项

问题 在Visual Studio 2019安装之前&#xff0c;先安装了CUDA Toolkit。在使用Visual Studio 2019创建新项目的时候&#xff0c;发现新建项目里没有CUDA的选项。 这时候有两种办法&#xff0c;一种是把CUDA Toolkit卸载重装&#xff0c;重装的时候&#xff0c;CUDA会自己在Visu…