支持向量机SVM

news2024/12/26 21:32:44

文章目录

  • SVM简单理解
  • SVM代码实现
    • 导入数据集
    • SVM实现
    • 画出支持向量
  • 总结

SVM简单理解

在下二维平面存在以下数据点,不同颜色代表不同类别,现在需要画一条直线,想将两个类别分别开来,当有新数据加入时,根据这条直线,也能将新数据正确分类,那么怎么才能画出这条线呢?对于下面这几种不同的画法,你会怎么选择。那么在三维空间、四维空间、高维空间,你又该怎样确定超平面划分两类数据呢?
在这里插入图片描述
上面的这些问题都可以理解为,在N维数据的样本数,M维数据的维度数,设计一个维度为M-1的超平面 W 1 X 1 + W 2 X 2 + … … + W m X m + B = 0 W_{1}X_{1}+ W_{2}X_{2}+ ……+ W_{m}X_{m}+B = 0 W1X1+W2X2++WmXm+B=0将两类数据区别开来,W可以理解为X对应的权重
在这里插入图片描述
下面以二维空间为例,找到那条分类线W_{1}X_{1}+ W_{2}X_{2}+B = 0 作为决策边界。下面看一下几种不同的画法,看看那一条边界能够很好分类数据。
第一种画法中,两类数据都有数据点离边界非常接近,这种画法效果是非常差的,当有一个点同样接近分类线时,分类错误的概率是非常大的。
第二种画法中,两类数据中所有点,都与决策边界线保持一定的距离,这个距离起到缓冲区的作用,当这个缓冲区足够大时,分类结果的可信度就更高了,我们把这个缓冲区称为间隔。间隔能够把两类数据所处的空间分割开来,间隔距离可以体现分类数据差异的大小,越大的间隔,意味着两类数据差异越大,我们区分起来就越容易。因此,寻找最佳决策边界线的问题,可以转化为 求解两类数据的最大间隔问题。间隔的中间,就是我们的决策边界。
在这里插入图片描述
当有新数据需要判断时,根据它处于决策边界的相对位置,就可以进行分类了。假设决策边界的超平面方程式为W_{1}X_{1}+ W_{2}X_{2}+B = 0 它分别上下移动c,来到间隔上下边界W_{1}X_{1}+ W_{2}X_{2}+B = c W_{1}X_{1}+ W_{2}X_{2}+B = -c ,上下边界一定会经过一些样本边界的点,这些点距离决策边界最近,他们决定了间隔边界距离,我们称他们为支持向量(support vector),我们的支持向量机就是support vector machine,简称SVM。
在这里插入图片描述
我们把等式两边分别除以c,得到
W 1 X 1 + W 2 X 2 + B = 0 − > W 1 c X 1 + W 2 c X 2 + b c = 0 W_{1}X_{1}+ W_{2}X_{2}+B = 0 ->\frac{W1}{c} _{}X_{1}+ \frac{W2}{c} X_{2}+\frac{b}{c} = 0 W1X1+W2X2+B=0>cW1X1+cW2X2+cb=0
W 1 X 1 + W 2 X 2 + B = 0 − > W 1 c X 1 + W 2 c X 2 + b c = 1 W_{1}X_{1}+ W_{2}X_{2}+B = 0 ->\frac{W1}{c} _{}X_{1}+ \frac{W2}{c} X_{2}+\frac{b}{c} = 1 W1X1+W2X2+B=0>cW1X1+cW2X2+cb=1
W 1 X 1 + W 2 X 2 + B = 0 − > W 1 c X 1 + W 2 c X 2 + b c = 1 W_{1}X_{1}+ W_{2}X_{2}+B = 0 ->\frac{W1}{c} _{}X_{1}+ \frac{W2}{c} X_{2}+\frac{b}{c} = 1 W1X1+W2X2+B=0>cW1X1+cW2X2+cb=1
W 1 ′ = W 1 c , W 2 ′ = W 2 c , b ′ = b c W_{1}^{'}=\frac{W_{1}}{c} , W_{2}^{'}=\frac{W_{2}}{c},b_{}^{'}=\frac{b_{}}{c} W1=cW1W2=cW2b=cb
使用 W 1 ′ W_{1}^{'} W1, W 2 ′ W_{2}^{'} W2, b ′ b_{}^{'} b分别替代原方程的变量,得到新方程:
w 1 ′ x 1 + w 2 ′ x 2 + b ′ = 0 w_{1}{'}x_{1}+ w_{2}{'}x_{2}+b_{}{'} = 0 w1x1+w2x2+b=0
w 1 ′ x 1 + w 2 ′ x 2 + b ′ = 1 w_{1}{'}x_{1}+ w_{2}{'}x_{2}+b_{}{'} = 1 w1x1+w2x2+b=1
w 1 ′ x 1 + w 2 ′ x 2 + b ′ = − 1 w_{1}{'}x_{1}+ w_{2}{'}x_{2}+b_{}{'} = -1 w1x1+w2x2+b=1
方程右边被转化为正负一,这样我们就可以将上述两个方程式定义为正负超平面,只需要求解 W ′ W_{}{'} W, b ′ b_{}{'} b,得到对应的三个超平面方程式。正超平面及其上面的点成为正类,负超平面以及下面的点成为负类。当有新数据加入,需要判断时,只需要判断他与决策超平面的绝对位置进行分类。
在这里插入图片描述

SVM代码实现

导入数据集

对文件进行逐行解析,从而得到第行的类标签labelMat和整个特征矩阵dataMat。
下一个函数selectJrand ()有两个参数值,其中i是第一个alpha的下标,m是所有alpha的数目。只要函数值不等于输入值i,函数就会进行随机选择。clipAlpha ()它是用于调整大于H或小于L的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):
    if aj > H:
        aj = H
    if L > aj:
        aj = L
    return aj

SVM实现

Args:
    dataMatIn    数据集
    classLabels  类别标签
    C   松弛变量(常量值),允许有些数据点可以处于分隔面的错误一侧。
        控制最大化间隔和保证大部分的函数间隔小于1.0这两个目标的权重。
        可以通过调节该参数达到不同的结果。
    toler   容错率(是指在某个体系中能减小一些因素或选择对某个系统产生不稳定的概率。)
    maxIter 退出前最大的循环次数
def smoSimple(dataMatIn, classLabels, C, toler, maxIter):
    dataMatrix = mat(dataMatIn)
    # 矩阵转置 和 .T 一样的功能
    labelMat = mat(classLabels).transpose()
    m, n = shape(dataMatrix)

    # 初始化 b和alphas(alpha有点类似权重值。)
    b = 0
    alphas = mat(zeros((m, 1)))

    # 没有任何alpha改变的情况下遍历数据的次数
    iter = 0
    while (iter < maxIter):
        # w = calcWs(alphas, dataMatIn, classLabels)
        # print("w:", w)

        # 记录alpha是否已经进行优化,每次循环时设为0,然后再对整个集合顺序遍历
        alphaPairsChanged = 0
        for i in range(m):
            # print('alphas=', alphas)
            # print('labelMat=', labelMat)
            # print('multiply(alphas, labelMat)=', multiply(alphas, labelMat))
            # 我们预测的类别 y = w^Tx[i]+b; 其中因为 w = Σ(1~n) a[n]*lable[n]*x[n]
            fXi = float(multiply(alphas, labelMat).T*(dataMatrix*dataMatrix[i, :].T)) + b
            # 预测结果与真实结果比对,计算误差Ei
            Ei = fXi - float(labelMat[i])

            # 约束条件 (KKT条件是解决最优化问题的时用到的一种方法。我们这里提到的最优化问题通常是指对于给定的某一函数,求其在指定作用域上的全局最小值)
            # 0<=alphas[i]<=C,但由于0和C是边界值,我们无法进行优化,因为需要增加一个alphas和降低一个alphas。
            # 表示发生错误的概率: labelMat[i]*Ei 如果超出了 toler, 才需要优化。至于正负号,我们考虑绝对值就对了。
            '''
            # 检验训练样本(xi, yi)是否满足KKT条件
            yi*f(i) >= 1 and alpha = 0 (outside the boundary)
            yi*f(i) == 1 and 0<alpha< C (on the boundary)
            yi*f(i) <= 1 and alpha = C (between the boundary)
            '''
            if ((labelMat[i]*Ei < -toler) and (alphas[i] < C)) or ((labelMat[i]*Ei > toler) and (alphas[i] > 0)):

                # 如果满足优化的条件,我们就随机选取非i的一个点,进行优化比较
                j = selectJrand(i, m)
                # 预测j的结果
                fXj = float(multiply(alphas, labelMat).T*(dataMatrix*dataMatrix[j, :].T)) + b
                Ej = fXj - float(labelMat[j])
                alphaIold = alphas[i].copy()
                alphaJold = alphas[j].copy()

                # L和H用于将alphas[j]调整到0-C之间。如果L==H,就不做任何改变,直接执行continue语句
                # labelMat[i] != labelMat[j] 表示异侧,就相减,否则是同侧,就相加。
                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 = 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
                # 并使用辅助函数,以及L和H对其进行调整
                alphas[j] = clipAlpha(alphas[j], H, L)
                # 检查alpha[j]是否只是轻微的改变,如果是的话,就退出for循环。
                if (abs(alphas[j] - alphaJold) < 0.00001):
                    print("j not moving enough")
                    continue
                # 然后alphas[i]和alphas[j]同样进行改变,虽然改变的大小一样,但是改变的方向正好相反
                alphas[i] += labelMat[j]*labelMat[i]*(alphaJold - alphas[j])
                # 在对alpha[i], alpha[j] 进行优化之后,给这两个alpha值设置一个常数b。
                # w= Σ[1~n] ai*yi*xi => b = yj- Σ[1~n] ai*yi(xi*xj)
                # 所以:   b1 - b = (y1-y) - Σ[1~n] yi*(a1-a)*(xi*x1)
                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
                alphaPairsChanged += 1
                print("iter: %d i:%d, pairs changed %d" % (iter, i, alphaPairsChanged))
        # 在for循环外,检查alpha值是否做了更新,如果在更新则将iter设为0后继续运行程序
        # 知道更新完毕后,iter次循环无变化,才推出循环。
        if (alphaPairsChanged == 0):
            iter += 1
        else:
            iter = 0
        print("iteration number: %d" % iter)
    return b, alphas

画出支持向量

在这里插入图片描述

def plotfig_SVM(xMat, yMat, ws, b, alphas):

    xMat = mat(xMat)
    yMat = mat(yMat)

    # b原来是矩阵,先转为数组类型后其数组大小为(1,1),所以后面加[0],变为(1,)
    b = array(b)[0]
    fig = plt.figure()
    ax = fig.add_subplot(111)

    # 注意flatten的用法
    ax.scatter(xMat[:, 0].flatten().A[0], xMat[:, 1].flatten().A[0])

    # x最大值,最小值根据原数据集dataArr[:, 0]的大小而定
    x = arange(-1.0, 10.0, 0.1)

    # 根据x.w + b = 0 得到,其式子展开为w0.x1 + w1.x2 + b = 0, x2就是y值
    y = (-b-ws[0, 0]*x)/ws[1, 0]
    ax.plot(x, y)

    for i in range(shape(yMat[0, :])[1]):
        if yMat[0, i] > 0:
            ax.plot(xMat[i, 0], xMat[i, 1], 'cx')
        else:
            ax.plot(xMat[i, 0], xMat[i, 1], 'kp')

    # 找到支持向量,并在图中标红
    for i in range(100):
        if alphas[i] > 0.0:
            ax.plot(xMat[i, 0], xMat[i, 1], 'ro')
    plt.show()

总结

优点:
1.支持向量机算法可以解决小样本情况下的机器学习问题,简化了通常的分类和回归等问题。
2.支持向量机算法利用松弛变量可以允许一些点到分类平面的距离不满足原先要求,从而避免这些
点对模型学习的影响。
——————————————————————————————————————————————————————————————————————————————————
缺点:
1.支持向量机算法对大规模训练样本难以实施。这是因为支持向量机算法借助二次规划求解支持
向量,这其中会涉及m阶矩阵的计算,所以矩阵阶数很大时将耗费大量的机器内存和运算时间。
2.经典的支持向量机算法只给出了二分类的算法一般要解决多分类问题,但支持向量机对于多分
类问题解决效果并不理想。

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

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

相关文章

springboot+jsp母婴用品商城网站系统

开发语言&#xff1a;Java 后端框架&#xff1a;springboot(SpringSpringMVCMyBatis) 前端框架&#xff1a;jsp 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 母婴用品网站&#xff0…

客快物流大数据项目(九十六):ClickHouse的VersionedCollapsingMergeTree深入了解

文章目录 ClickHouse的VersionedCollapsingMergeTree深入了解 一、创建VersionedCollapsingMergeTree引擎表的语法 二、折叠数据

人工智能轨道交通行业周刊-第26期(2022.12.5-12.11)

本期关键词&#xff1a;智慧检修、障碍物检测、监管数据平台、ChatGPT、脑机接口、图像增强 1 整理涉及公众号名单 1.1 行业类 RT轨道交通中关村轨道交通产业服务平台人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁…

Canvas 性能优化:脏矩形渲染

大家好&#xff0c;我是前端西瓜哥。 使用 Canvas 做图形编辑器时&#xff0c;我们需要自己维护自己的图形树&#xff0c;来保存图形的信息&#xff0c;并定义元素之间的关系。 我们改变画布中的某个图形&#xff0c;去更新画布&#xff0c;最简单的是清空画布&#xff0c;然…

Java项目:SSM个人博客管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 管理员角色包含以下功能&#xff1a; 发博客,审核评论,博客增删改查,博客类别增删改查,修改导航,评论增删改查,个人信息修改,登陆页面等功能。 …

TOOD: Task-aligned One-stage Object Detection 原理与代码解析

paper&#xff1a;TOOD: Task-aligned One-stage Object Detection code&#xff1a;https://github.com/fcjian/TOOD 存在的问题 目标检测包括分类和定位两个子任务&#xff0c;分类任务学习的特征主要关注物体的关键或显著区域&#xff0c;而定位任务是为了精确定位整个…

SpringBoot yaml语法详解

SpringBoot yaml语法详解1.yaml基本语法2.yaml给属性赋值3.JSR303校验4.SpringBoot的多环境配置1.yaml基本语法 通常情况下&#xff0c;Spring Boot 在启动时会将 resources 目录下的 application.properties 或 apllication.yaml 作为其默认配置文件&#xff0c;我们可以在该…

【云原生 | Kubernetes 实战】11、K8s 控制器 Deployment 入门到企业实战应用(下)

目录 四、通过 k8s 实现滚动更新 4.3 自定义滚动更新策略 取值范围 建议配置 总结 测试&#xff1a;自定义策略 重建式更新&#xff1a;Recreate 五、生产环境如何实现蓝绿部署&#xff1f; 5.1 什么是蓝绿部署&#xff1f; 5.2 蓝绿部署的优势和缺点 优点&#x…

图数据库 Neo4j 学习之JAVA-API操作

Neo4j 系列 1、图数据库 Neo4j 学习随笔之基础认识 2、图数据库 Neo4j 学习随笔之核心内容 3、图数据库 Neo4j 学习随笔之基础操作 4、图数据库 Neo4j 学习随笔之高级操作 5、图数据库 Neo4j 学习之JAVA-API操作 6、图数据库 Neo4j 学习之SpringBoot整合 文章目录Neo4j 系列前…

mac pro M1(ARM)安装vmware虚拟机及centos8详细教程

前言 mac发布了m1芯片&#xff0c;其强悍的性能收到很多开发者的追捧&#xff0c;但是也因为其架构的更换&#xff0c;导致很多软件或环境的安装成了问题&#xff0c;这次我们接着来看如何在mac m1环境下安装centos8 Centos8安装安装vmware虚拟机Centos8 镜像支持M1芯片安装Cen…

DDPM原理与代码剖析

前言 鸽了好久没更了&#xff0c;主要是刚入学学业压力还蛮大&#xff0c;挺忙的&#xff0c;没时间总结啥东西。 接下来就要好好搞科研啦。先来学习一篇diffusion的经典之作Denoising Diffusion Probabilistic Models(DDPM)。 先不断前向加高斯噪声&#xff0c;这一步骤称为…

论文笔记(二十三):Predictive Sampling: Real-time Behaviour Synthesis with MuJoCo

Predictive Sampling: Real-time Behaviour Synthesis with MuJoCo文章概括摘要1. 介绍2. 背景3. MuJoCo MPC (MJPC)3.1. 物理模拟3.2. 目标3.3. 样条3.4. 规划师4. 结论4.1. 图形用户界面4.2. 例子5. 讨论5.1. 预测抽样5.2. 用例5.3. 局限和未来的工作文章概括 作者&#xff…

25-Vue之ECharts-基本使用

ECharts-基本使用前言ECharts介绍ECharts快速上手ECharts配置说明前言 本篇开始来学习下开源可视化库ECharts ECharts介绍 ECharts是百度公司开源的一个使用 JavaScript 实现的开源可视化库&#xff0c;兼容性强&#xff0c;底层依赖矢量图形 库 ZRender &#xff0c;提供直…

Oracle High Water Mark问题

公司写SQL时遇到一个奇怪的问题&#xff0c;往表中频繁插入和删除大量数据&#xff0c;几次操作后&#xff0c;使用Select查询(表中没数据)特别慢&#xff0c;后得知是高水位线的问题。 该问题已通过: truncate table tableName语句解决。 本想写篇文章详细记录一下的&#xff…

操作系统,计算机网络,数据库刷题笔记9

操作系统&#xff0c;计算机网络&#xff0c;数据库刷题笔记9 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff…

聊聊远程项目交付的敏捷管理

这是鼎叔的第四十三篇原创文章。行业大牛和刚毕业的小白&#xff0c;都可以进来聊聊。 欢迎关注本人专栏和微信公众号《敏捷测试转型》&#xff0c;大量原创思考文章陆续推出。 对于日益重要的国际化市场&#xff0c;越来越多的离岸项目&#xff08;内包或外包&#xff09;在…

这十套练习,教你如何用Pandas做数据分析(09)

练习9-时间序列 探索Apple公司股价数据 步骤1 导入必要的库 运行以下代码 import pandas as pd import numpy as np visualization import matplotlib.pyplot as plt %matplotlib inline 步骤2 数据集地址 运行以下代码 path9 ‘…/input/pandas_exercise/pandas_exer…

CVE-2019-11043(PHP远程代码执行漏洞)复现

今天继续给大家介绍渗透测试相关知识&#xff0c;本文主要内容是CVE-2019-11043&#xff08;PHP远程代码执行漏洞&#xff09;复现。 免责声明&#xff1a; 本文所介绍的内容仅做学习交流使用&#xff0c;严禁利用文中技术进行非法行为&#xff0c;否则造成一切严重后果自负&am…

【hexo系列】02.hexo和obsidian实现笔记丝滑

文章目录hexo主题hexo进阶hexo插件&#xff1a;自动生成目录hexo插件&#xff1a;自动生成目录序号&#xff08;自行选用&#xff09;obsidian插件&#xff1a;templater安装插件配置插件定制模板新建笔记参考资料hexo主题 hexo主题大全 cd blog git clone https://github.co…

这十套练习,教你如何用Pandas做数据分析(08)

练习8-创建数据框 探索Pokemon数据 步骤1 导入必要的库 运行以下代码 import pandas as pd 步骤2 创建一个数据字典 运行以下代码 raw_data {“name”: [‘Bulbasaur’, ‘Charmander’,‘Squirtle’,‘Caterpie’], “evolution”: [‘Ivysaur’,‘Charmeleon’,‘Warto…