精华内容
下载资源
问答
  • 基于SVM支持向量机实现人脸识别
    2021-10-28 00:39:57

    基于SVM支持向量机实现人脸识别

    本人本科大三,非985,211出身,这是我写的第一篇博客,其目的是对我这段时间学习SVM支持向量机和PCA降维算法的一次总结。若有错误之处,还请各位路过的大神积极指正。若要转载,请注明出处,谢谢!

    SVM支持向量机的定义

    支持向量机(support vector machines,SVM)是一种十分优秀的二分类算法,它的主要是寻找一个超平面来对样本数据进行分割,原则是间隔(margin)最大化,如果对应的样本特征是二维的,那么这个超平面就是一条直线将样本分隔开。

    在这里插入图片描述

    SVM支持向量机的原理作用

    SVM算法就是在寻找一个最优的决策边界(下图中的两条虚线)来确定分类线b,所提到的支持向量(support vector)就是距离决策边界最近的点(下图中p1、p2、p3点)。假设没有这些支持向量点作为支撑的话,b线的位置就会发生改变。故,SVM就是根据这些支持向量点来进行最大化margin,进而找到了最优的分类器(在这里也就是一条直线)

    在这里插入图片描述

    如何计算SVM支持向量机的权值w和偏置项b

    SVM的目标函数(损失函数):

    m i n 1 2 ∣ ∣ w ∣ ∣ 2 s . t y ⋅ ( w T ⋅ x i + b ) ≥ 1 i = 1 , 2 , 3...... n min\frac{1}{2}||w||^2\quad s.t\quad y\cdot(w^T\cdot x_i+b)\ge1\quad i=1,2,3......n min21w2s.ty(wTxi+b)1i=1,2,3......n
    知道了SVM的损失函数之后,就可以根据拉格朗日乘子法、KKT条件、对偶问题转换和SMO算法计算得到分割线w和b的值,当我们了确定w和b之后,我们就能构造出最大分割超平面,进而实现分类效果。

    代码实现原理步骤

    • 导包
    • 数据加载—>加载机器学习免费开源的SKlearn库的datasets里的人脸数据
    • 数据降维—>使用PCA(主成分分析)降维算法,目的提高模型的运算速度和减少计算机的储存
    • 数据拆分—>使用train_test_split将数据分为训练集和测试集
    • 参数优化—>网格搜索(GridSearchCV),确定最优参数组合,提高模型预测的准确率
    • 数据建模—>建立SVM模型

    代码实例演示:

    导包

    import numpy as np
    from sklearn.model_selection import train_test_split,GridSearchCV
    from sklearn.svm import SVC
    from sklearn import datasets
    from sklearn.decomposition import PCA
    import matplotlib.pyplot as plt
    

    数据加载

    data = datasets.fetch_lfw_people(resize = 1,min_faces_per_person = 70)
    X = data["data"]
    y = data["target"]
    faces = data["images"]
    target_names = data["target_names"]
    

    数据降维

    pca = PCA(n_components = 0.95)
    X_pca = pca.fit_transform(X)
    

    数据拆分

    X_train,X_test,y_train,y_test,faces_train,faces_test = train_test_split(X_pca,y,faces)
    
    

    参数优化

    svc = SVC()
    params = {"C":np.logspace(-3,3,50),"kernel":["rbf","linear","poly"],"tol":[0.0001,0.01,0.1,1]}
    gc = GridSearchCV(estimator = svc,param_grid = params)
    gc.fit(X_pca,y)
    gc.best_params_
    
    Out:{'C': 0.001, 'kernel': 'linear', 'tol': 1}
    

    数据建模,模型评分约为83%

    svc = SVC(C = 0.001,kernel = "linear",tol = 1)
    svc.fit(X_train,y_train)
    y_predict = svc.predict(X_test)
    display(svc.score(X_test,y_test),y_predict)
    
    0.8260869565217391
    array([1, 2, 1, 3, 3, 3, 3, 3, 3, 4, 3, 2, 2, 1, 1, 2, 1, 3, 2, 6, 3,2,
           3, 1, 4, 3, 3, 3, 1, 0, 3, 2, 4, 1, 3, 2, 3, 3, 3, 1, 1, 3, 2,3,
           3, 1, 2, 1, 0, 0, 3, 1, 1, 1, 4, 2, 3, 2, 3, 3, 1, 3, 3, 4, 3,3,
           3, 3, 1, 0, 2, 3, 6, 1, 0, 3, 2, 6, 3, 3, 5, 2, 1, 3, 3, 0, 1,5,
           3, 6, 1, 0, 3, 3, 0, 3, 1, 3, 3, 1, 4, 3, 3, 3, 1, 6, 4, 3, 1,1,
           3, 3, 4, 2, 0, 3, 1, 4, 3, 3, 1, 3, 4, 1, 4, 1, 1, 0, 3, 1, 4,6,
           6, 4, 1, 3, 3, 5, 4, 1, 3, 3, 3, 2, 3, 3, 3, 3, 3, 4, 4, 0, 3,5,
           1, 3, 3, 3, 4, 3, 1, 3, 6, 5, 5, 2, 3, 6, 3, 2, 5, 2, 6, 2, 3,2,
           3, 1, 3, 4, 3, 2, 4, 6, 3, 3, 1, 3, 0, 3, 2, 3, 1, 1, 1, 5, 3,3,
           3, 1, 1, 3, 5, 2, 6, 1, 6, 1, 3, 3, 3, 5, 1, 2, 3, 3, 1, 3, 1,6,
           1, 3, 4, 2, 4, 3, 1, 3, 0, 3, 3, 1, 2, 3, 3, 5, 0, 3, 1, 2, 3,1,
           2, 3, 3, 5, 2, 2, 1, 3, 3, 3, 2, 3, 6, 0, 1, 6, 3, 2, 3, 3, 4,3,
           3, 1, 6, 3, 4, 3, 0, 1, 6, 3, 2, 2, 3, 3, 3, 6, 5, 3, 3, 3, 3,2,
           5, 2, 6, 3, 2, 1, 1, 2, 1, 2, 1, 3, 2, 2, 1, 6, 6, 3, 3, 5, 3,2,
           1, 3, 2, 3, 2, 3, 3, 3, 3, 3, 2, 6, 3, 0], dtype=int64)
    

    模型预测效果可视化

    plt.figure(figsize=(5*2,10*3))
    plt.rcParams["font.family"] = "PingFang SC"
    for i in range(50):
        ax = plt.subplot(10,5,i+1)
        ax.imshow(faces_test[i],cmap = "gray")
        ax.axis("off")
        true_name = target_names[y_test[i]].split(" ")[-1]
        predict_name = target_names[y_predict[i]].split(" ")[-1]
        plt.title("True:%s\nPredict:%s"%(true_name,predict_name))
    

    在这里插入图片描述

    更多相关内容
  • 本文基于SVM支持向量机算法,来实现降水量预测。
  • MATLAB源码集锦-基于SVM支持向量机算法的降水量预测模型代码
  • matlab程序+数据集(预处理完成的)
  • SVM支持向量机分类鸢尾花数据集iris及代码,数据集有Excel、data、txt文件格式,代码有data、txt格式演示
  • 题目是将图片库中的纹理图片裁剪成九份,其中五份做训练集,四份做测试集,先提取图片LBP特征 ,最后用svm支持向量机进行学习,在预测测试集里的图片是哪一类纹理。 正常情况下是需要调参的,即调整SVM的参数,但图...
  • MATLAB实验,实现svm向量机,内含程序代码和数据
  • python实现SVM支持向量机代码CSV文件。elativeLayout xmlns:android= http: //schemas.android.com/apk/res/android android:layout_width= fill_parent android:layout_height= f...
  • 参考学习
  • 使用SVM支持向量机进行鸢尾花分类_Python实现-附件资源
  • SVM支持向量机是建立于统计学习理论上的一种分类算法,适合与处理具备高维特征的数据集。 SVM算法的数学原理相对比较复杂,好在由于SVM算法的研究与应用如此火爆,CSDN博客里也有大量的好文章对此进行分析,下面给出...
  • SVM支持向量机,预测分类 回归,支持向量机(Support Vector Machine,SVM)是Corinna Cortes和Vapnik等于1995年首先提出的,它在解决小样本、非线性及高维模式识别中表现出许多特有的优势,并能够推广应用到函数拟合...
  • 支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大使它有别于感知机;SVM还包括核技巧,这使它成为实质上的非线性分类器。SVM的的学习...
  • SVM支持向量机

    2020-12-24 22:05:31
    目录一、SVM与感知机关系1.1、SVM概念1.2、感知机...1)SVM(Support Vector Mechine)支持向量机,是一个二分类算法,其对感知机进行了扩展,支持线性分类和非线性分类; 2)可以用于回归任务(SVR)中;也可以用于多

    一、SVM与感知机关系

    1.1、SVM概念

    1)SVM(Support Vector Mechine)支持向量机,是一个二分类算法,其对感知机进行了扩展,支持线性分类和非线性分类;
    2)可以用于回归任务(SVR)中;也可以用于多分类中,升维方式(OvR、OvO);

    1.2、感知机

    1)思想:在任意空间中找到一个超平面,将所有二分类别分割开;
    2)前提:数据是线性可分的
    3)模型/判别式:样本代入模型计算结果大于0则为正确分类,反正则为错误分类
    在这里插入图片描述

    4)损失函数:期望使分类错误的所有样本到超平面的距离之和最小;(结果为0时成为完美分类器,意味着每一分错的样本)

    1.3、SVM与感知机比较

    1)相同点:都是寻找一个超平面解决二分类问题的算法,一侧计算结果为正则正例,一侧计算结果为负则负例;
    2)不同点:损失函数不同,感知机是通过判断错的点寻找超平面;SVM是通过支持向量寻找超平面;逻辑回归通过最大似然寻找超平面;
    3)高级点:SVM尝试找到一个决策边界,距离两个类别最近的样本点最远,这样模型的容忍度会更好;

    二、几何距离与函数距离

    2.1、概念

    感知机使用几何距离计算中的损失函数大小;SVM使用函数距离;
    在这里插入图片描述
    上面为某点到平面的几何距离
    在这里插入图片描述

    2.2、关键词说明

    1)三种支持向量机:线性可分支持向量机(硬间隔最大化)、线性支持向量机(软间隔最大化)、非线性支持向量机(升维【核函数】)
    2)线性可分(Linearly Separable):即指在数据集中,可以找到一个超平面将两组数据分开
    3)线性不可分(Linearly Inseparable):即指在数据集中,无法可以找到一个超平面将两组数据分开
    4)间隔(Margin):数据点到分割超平面的距离
    5)分割超平面(Separating Hyperplane):将数据集分割开的直线或平面
    6)支持向量(Support Vector):离分割超平面最近的点

    三、损失函数推导

    通过线性可分支持向量机进行说明
    1)实现硬间隔最大化,需要满足两个条件:能够完美分类正负例、距离最近的点越远越好
    2)怎么确定超平面
    在这里插入图片描述
    3)目标:能够正确分类的平面中,距离越近的越远越好;(即找到一组最好的w和b固定一个超平面,可以完美分类正负例,且距离最近的点间隔最大)
    4)转为为有约束的函数最优化问题
    在这里插入图片描述
    5)目标简化:一个超平面对应无数组w和b,只要找到其中任意一组即可,所以令函数距离等于1,则最优化问题可以简化为如下
    在这里插入图片描述
    6)将求解最大问题转为最小问题,得到等价的、带约束的损失函数(s.t即约束条件,1/2后面跟的就是L2正则项)
    在这里插入图片描述
    两种最优化问题求解方案:上面的损失函数+SMO、hinge Loss+GD

    四、最优化问题

    拉格朗日函数,将带有约束问题,对原始问题求最小,转为无约束条件,先对原始问题求最大,再求最小;
    好处:去掉约束条件;
    代价:一次优化变成了二次优化、每个阿尔法需要大于等于0

    4.1、硬间隔SVM

    4.1.1、求解流程

    1)原始目标:求得一组w和b使得间隔margin最大
    2)转换目标:通过拉格朗日函数,构造出目标函数,问题由求得n个w和1个b转换为求得m个α
    在这里插入图片描述
    3)利用smo算法求得m个α
    4)利用求得的m个α*,求得w**和b*
    在这里插入图片描述

    4.1.2、思路推导流程

    4.1.2.1、函数最优化问题(无约束条件)

    给定一个函数f(x)=x²+2x+3,找到一个x使得f(x)最小,对x的取值范围不做限制
    在这里插入图片描述

    4.1.2.2、函数最优化问题(有约束条件)

    给定一个函数f(x)=x²+2x+3,找到一个x使得f(x)最小,但有约束条件x>=0

    4.1.2.3、原始最优化问题

    对应带约束带条件的最优化问题,其泛化表示形式为如下,s.t表示约束条件,即k个不等式约束条件和l个等式约束条件(SVM没有hj函数部分)
    在这里插入图片描述

    4.1.2.4、拉格朗日函数

    使用拉格朗日函数的目的,是将有约束的最优化问题转换我无约束条件最优化问题,下面的式子与原始最优化问题式子等价;
    定义一个原始最优化问题的拉格朗日函数,ci表示第i个不等式约束函数,βi表示第j个等式约束函数,αi和βi即为拉格朗日乘子。
    在这里插入图片描述
    拉格朗日函数特性:令
    在这里插入图片描述
    如果x满足上述s.t约束条件,则
    在这里插入图片描述
    如果x不满足s.t约束条件,则
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    所以,对原始约束条件求最小,可以转换为先对拉格朗日函数函数求最大再求最小,即二次优化问题。也就是说,我们目标是求解x,但是会先在求最大值时解出α和β值,然后再将二者带入公式求最小值时解出x。

    4.1.2.5、对偶问题

    定义
    在这里插入图片描述
    此时求解θD极大值,则称为拉格朗日极大极小问题,也叫原始问题的对偶问题
    在这里插入图片描述
    其最优解形式为
    在这里插入图片描述
    所以,当f(x)的ci函数为凸函数,hj函数为仿射函数(高维空间中的一条线),那么极小极大问题可以转换为极大极小问题(minmax=maxmin)
    在这里插入图片描述

    4.1.2.6、KKT条件求解

    在这里插入图片描述

    4.1.2.7、求解SVM最优化问题
    4.1.2.7.1、整体流程

    在这里插入图片描述
    说明:之前的x表示w0-wn,而这里w表示w1-wn,b表示w0截距项,因为SVM不涉及β,所以函数式子中没有β

    4.1.2.7.2、先求极小值(KKT条件)

    在这里插入图片描述

    4.1.2.7.3、再求极大值(将极小结果反代回公式)

    在这里插入图片描述
    在这里插入图片描述

    4.1.2.7.4、整理对偶函数

    在这里插入图片描述

    4.1.2.7.5、求得最终超平面

    在这里插入图片描述

    4.2、软间隔SVM

    4.2.1、硬间隔SVM面临的问题

    硬间隔SVM要求完美的分割正负例样本,如果数据集线性不可分,包含噪声样本点,则意味着无法找到一个合格的超平面,也就是无法得出w和b的最优解
    在这里插入图片描述

    4.2.2、如何解决上述问题

    引入松弛变量,将约束条件变为,ξ代表异常点嵌入间隔面的深度,我们要在能选出符合约束条件的最好的 w 和 b 的同时,让嵌入间隔面的总深度越少越好
    在这里插入图片描述

    4.2.3、目标函数优化

    在这里插入图片描述

    4.2.4、软间隔支持向量分析

    在这里插入图片描述

    4.2.5、软间隔最大化算法

    1)设定惩罚系数C,构造优化问题
    在这里插入图片描述

    4.2.6、判别函数的另一种表达形式

    在这里插入图片描述

    4.3、非线性SVM与核函数

    4.3.1、如何处理线性不可分问题

    4.3.1.1、升维

    在这里插入图片描述
    在这里插入图片描述

    4.3.1.2、核函数

    在这里插入图片描述
    在这里插入图片描述

    4.3.2、svm算法求解流程

    1)选择某个核函数及对应超参数
    2)选择惩罚系数C
    3)构造最优化问题
    在这里插入图片描述

    展开全文
  • 【SVM预测】灰狼算法优化svm支持向量机预测matlab源码.md
  • 基于MATLAB的SVM支持向量机手写识别算法.pdf
  • 使用python手动实现了SVM支持向量机,包括其中二次规划的求解(调用cvxopt包),实现了软间隔及核技术,以及对数据集及分类效果的可视化!建议配合我的SVM PPT一起学习SVM 不是直接调用sklearn的SVM!!
  • SVM支持向量机详解

    万次阅读 多人点赞 2020-12-21 10:13:36
    支持向量机(support vector machines, SVM)是二分类算法,所谓二分类即把具有多个特性(属性)的数据分为两类,目前主流机器学习算法中,神经网络等其他机器学习模型已经能很好完成二分类、多分类,学习和研究SVM...

    支持向量机(support vector machines, SVM)是二分类算法,所谓二分类即把具有多个特性(属性)的数据分为两类,目前主流机器学习算法中,神经网络等其他机器学习模型已经能很好完成二分类、多分类,学习和研究SVM,理解SVM背后丰富算法知识,对以后研究其他算法大有裨益;在实现SVM过程中,会综合利用之前介绍的一维搜索、KKT条件、惩罚函数等相关知识。本篇首先通过详解SVM原理,后介绍如何利用python从零实现SVM算法。

        为便于理解,假设样本有两个属性,可以把属性值分别对应到二维空间轴的x,y轴上,如下图所示:

    二维坐标.png

    实例中样本明显的分为两类,黑色实心点不妨为类别一,空心圆点可命名为类别二,在实际应用中会把类别数值化,比如类别一用1表示,类别二用-1表示,称数值化后的类别为标签。每个类别分别对应于标签1、还是-1表示没有硬性规定,可以根据自己喜好即可,需要注意的是,由于SVM算法标签也会参与数学运算,这里不能把类别标签设为0。

        还是对应于上图,如果能需要找到一条直线,将上述的实心点与空心点分为两个部分,当下次还有其他样本点时,将其属性值作为坐标绘制到坐标轴上后,根据新样本点与直线位置关系,就可以判断出其类别。满足这样直线有无数条,SVM是要找到最合适一条:观察上图,绿线肯定不行,该条分类直线在没有验证集前提下已经错了;而蓝色线和红色都可以实现分类,蓝色线与实心黑点靠的太近,相比而言,红色线更‘公允’些。红色线就是SVM需要找出的分类直线,数学语言描述红线的‘公允’特性可表述为:将黑点和空心点视为两个集合,如果找到一个直线,使得黑点集合中的一些点离直线最近,这些点到该直线距离为d;空心点集合中也能找到一系列的点,离直线最近,距离同样也是d,则该直线就是我们要找到线性分类器,同时称两个集合中离直线最近的点为支持向量,SVM支持向量机就是由此得名的。

        一些算法书籍中这样描述SVM算法,找出一个直线,使得直线与两边集合最近的点的间隔空间最大,从上图也可以看出来,黑色点离蓝线最近的点,其距离小于到红线距离(直角的斜边)。能找到支持向量就一定找到分类直线,反之亦然,以上是针对两个属性值,通过观察二维平面即可以引出SVM的算法的特点,如果样本属性非常多呢,如何归纳算法的规律性?首先说下凸集可分离定理,该定理不仅是SVM的核心理论支持,更是机器学习算法的基石。

    一、凸集可分离定理

        还是以二维空间为例,中学时代我们就学过直线方程,比如有直线方程y=2x-1,如下图所示:

    超平面.png

    把直线方程y=2x-1写成内积形式:

    内积一.gif

    向量(-2,1)对应上图中OA向量,把OA向量变为单位向量,即方向与OA相同,模为1向量OS,S的坐标为 坐标1.gif,将直线方程两边同除以52.gif,可得:

    内积而.gif

    (x,y)代表直线y=2x-1上任意一点,上式说明y=2x-1上任意一点与单位向量S:坐标1.gif的内积是标准内积1.gif,图中向量OP的长度为标准内积3.gif,取负号是因为OP向量方向与OS方向相反;上图中向量v1、v2在OS向量上投影都是OP,这个例子说明:通过引入一个向量OS,直线y=2x-1上无数的点在向量OS上都可以用标准内积1.gif来表示,或者说,直线y=2x-1在向量OS上都可以用坐标(0,标准内积1.gif)表示。通过内积投影的方式,可以把高维数据变为向量上一个实数,这是一个线性泛函的过程,数学领域中常用内积来降低数据维度,把多维数据处理成一个实数便于后期分析、处理。

        引申到任意维度时,上面方程可用集合公式表达:S:{x | pTx=α}  x∈Rn。对应于上图:p向量对应向量OS,x为直线上任意一点,在SVM算法中,称x点构成的集合S为超平面。有时高维数据集合投影到向量p的内积值是一个范围:比如{x | pTx>=α}或{y | pTy<=-α},高维数据被投影到向量p的两个区间上:

    凸集.png

    接下来介绍凸集分离定理:

    上图中X,Y在高维空间中都是凸集,且X∩Y=Φ;将X、Y投影到向量p上后,可以得到两个凸集X',Y',在向量p上X'、Y'一定处在向量p的两端,即X',Y'两个凸集是可分离的。

        注意定理中有两个条件,一是X,Y是凸集,二是X,Y交集为空集。X',Y'可分离意味着在向量p上可以将两者区分开,而X与X'、Y与Y'都是一一映射,X',Y'可区分开就间接地意味着X,Y也可区分开,这里所谓的'可区分开'也就是SVM所要实现的二分法。凸集可分离定理说明两个没有交集的凸集是线性可分的,同时,如果两个数据集不能线性分开时,可以通过核函数将数据变为两个凸集,所以凸集可分离定理对核函数生成也有着指导意义。

    二、 SVM算法

    2.1 超平面与最大间隔

        前面介绍过,能把数据实现二分类的线性分类器称为超平面,SVM算法需要求出最大间隔的超平面,可设超平面为S:{x|pTx=α},由于pTx=α等式两边可除以一个正数就可以把p归一化为单位向量,不妨设p是一个已经处理后的单位向量,此设定不影响SVM算法。一般文献中,超平面通常写成隐函数形式:

    S:{x|pTx-α=0}   x∈Rn,p∈Rn,||p||=1

    由几何知识可知,空间任意一点x到超平面S的距离公式为:

    距离公式.gif

    属于两个分类的支持向量到该超平面的距离都为d , d>0,由于支持向量是各自分类数据中,距离超平面最近的点,针对所有数据有以下不等式:

    条件.gif         ⑴

    公式(1)两边同除以d,可得:处理1.gif,使用换元法,令:

    设定2.gif                               ⑵

    这样就得到约束条件常见形式:

    条件3.gif                             ⑶

    接下来要把公式(3)脱掉绝对值符号,SVM是一个二分类问题:可设定ωTx+b>=1时分类标签y=1;ωTx+b<=-1时分类标签y=-1,这样一来,所有的数据都有不等式:

    y(ωTx+b)>=1                  ④

    再回过头来看换元设定,ω=pT/d,等式两边取范数运算有:||ω||=||pT||/d=1/d,可得d=1/||ω||,SVM算法需要在满足公式4约束的基础上,使得间隔距离d最大。假设待分类数据共有m个,实现SVM算法等同于求解一个带有不等式约束的非线性规划问题:

    svm线性规划.png

    上面的问题也可以表述为求最小值的问题:

    svm线性规划22.png ⑤

    超平面实现分类效果、以及各个参数之间关系可参考下图:

    1608295305531001632.png

    2.2 最大软间隔

        实践中由于异常数据的存在,导致超平面不能完全将数据分为两部分,如下图:

    软间隔1.png

    两个分类中混杂了少量的异常数据,除去极少数的异常点,上图中超平面能分离大多数样本。⑤式引入松弛变量后可以兼容上图的情形:

    松弛变量.png(5.1)

    软间隔.jpg

    xi.gif正常情况下等于0,表示样本点分列在支持向量的两侧;xi.gif>0时代表的是异常数据当0<xi.gif<1时,代表数据在超平面与支持向量之间,如上图中的点2和点4;而xi.gif>1时代表数据到了对方空间中,如上图的点1和点3。满足(5.1)式的间隔称为软间隔,软间隔优化结果不仅需要支持向量的间隔最大,还要使得各个xi.gif尽量的小换句话说超平面确定后,被定义为异常数据的样本个数要尽量的少。

    三、求解带约束的非线性规划问题

        SVM算法最后归结为求解式(5),这是一个有约束的非线性规划问题,接下来通过两种方法求解,一种方案是利用之前介绍惩罚函数,优点是简单直接容易理解,不受约束条件数量的限制;另一种方案是数学解析法,其原理是拉格朗日对偶原理的应用,计算中涉及到对偶问题、鞍点、SMO算法等,解析法是一种理论性较强方法。

     

    3.1 拉格朗日对偶 

    3.1.1 对偶问题

        为后期求导方便,将公式(5)的目标函数f(ω)改为:

    fw2.gif

    乘以一个正数后与之前优化问题是等效的,新的目标函数与约束条件合成一个函数L(ω,b,α):

    拉格朗日2.png

    L(ω,b,α)称为拉格朗日函数,由于yi(ωTxi+b)-1>=0,αi≥0,在可行区内恒有L(ω,b,α)<=f(ω),如有常数ω*,b*,α*满足下面关系:

    L(ω*,b*,α)<=L(ω*,b*,α*)<=L(ω,b,α*)  ⑥

    称ω*,b*,α*是L(ω,b,α)函数的鞍点,此时ω*,b*是原问题的最优解。观察⑥式,L(ω*,b*,α)是仅含有参数α的函数,产生这个函数的过程是:ω,b分别取不同的值,代入L(ω,b,α)后得到一系列参数为α的函数簇Φ,当ω=ω*,b=b*时,函数L(ω*,b*,α)是函数簇Φ中下界函数,图像上看,L(ω*,b*,α)在函数簇Φ所有函数的下方,L(ω*,b*,α)函数可用θ(α)=inf{L(ω,b,α)}表示,inf意为取得函数簇Φ的下界,当α=α*时,函数θ(α)有最大值,即L(ω*,b*,α)<=L(ω*,b*,α*);而α取不同值代入L(ω,b)后得到一系列参数为ω,b的函数簇Ψ,L(ω,b,α*)代表函数簇Ψ的上界函数,公式表示:φ(ω,b)=L(ω,b,α*)=sup{L(α)},当ω=ω*,b=b*时φ(ω,b)有最小值L(ω*,b*,α*)。

        ⑥式不等式形式称为弱对偶条件,当取等号时,L(ω*,b*,α*)是θ(α)函数最大值,同时也是φ(ω,b)函数最小值,此时为强对偶条件。SVM默认是满足强对偶条件的,满足强对偶条件时,max{θ(α)}=L(ω*,b*,α*)=min{f(ω)} ,也称下面的⑦与⑤是拉格朗日对偶问题:

    max : θ(α)=inf{L(ω,b,α)}        

    s.t. α>=0     ⑦

    上面过程没有给出鞍点就是K-T点证明、强对偶成立的条件,可参考相关资料详细研究,拉格朗日函数鞍点示意图如下:

    鞍点.png

    上图中红色虚线代表ω,b分别取不同的值,代入L(ω,b,α)后得到一系列参数为α的函数簇Φ,绿色点代表函数簇Φ中每个函数最大值;绿色虚线为α取不同值代入L(ω,b,α)后得到一系列参数为ω,b的函数簇Ψ,红色点代表函数簇Ψ中每个函数最小值。显然函数簇Φ中下界函数θ(α)的最大值、函数簇Ψ上界函数φ(ω,b)的最小值,两点重合,该点为拉格朗日鞍点。

        求⑦最大值时首选要知道函数θ(α)的具体形式,已经知道,θ(α)是函数簇Φ的下界函数,函数簇Φ是把L(ω,b,α)中α视为符号常量、ω,b视为变量,那么求L(ω,b)最小值时,求导等于0时,ω,b都将是α函数,将ω,b代入L(ω,b,α)中即可得到θ(α)。

    求导1.png

    我.png                                 (7.1)

    求导二.png                    (7.2)

    (7.1)代入拉格朗日函数L(ω,b,α)可得:

    代入.png

    由于等于0.gif,所以上式可化为:

    θ(α)=theta.png ⑧

    求 max:θ(α)即可得到SVM的最优解,⑧是一个二次凸优化问题,求解⑧通用办法是利用SMO算法。

    3.1.2 SMO算法

        介绍SMO算法之前,先结合软间隔定义(5.1)式看看参数αi除了满足(7.1)、(7.2)还有其他哪些特性。软间隔要求间隔最大基础上,松弛变量xi.gif总体要小,即得到超平面之后,被定义为异常数据样本数量要尽量的少。按照这个定义生成新的拉格朗日函数:

    拉格朗日2.png(8.1)

    求解上式最小值的过程中,逐渐增大C将使xi.gif值变小,C是惩罚系数。按照对偶函数思想,为得到下界函数θ(α),先对其他参数求偏导得到以下等式组:

    约束条件1.png

    条件前两个结果之前已经推导过,最后一个条件说明0≤αi≤C。

       SMO算法用坐标上升法来实现参数优化,该方法在之前文章中介绍过,详细可参考链接:梯度下降法。简略回顾下,坐标上升法选择一个参数vi同时固定并初始化其他变量,目标函数此时变为vi的函数,求导并置零后,vi变为其他固定变量的函数,代入初始值后,得到vi优化值,再切换到下一个变量,重复以上操作直至函数值收敛,得到最优解。

        由于有条件条件2.gif存在,若选择αi以外的变量固定,αi一定是个常量,所以SMO算法通常一次取两个变量后固定其余的变量。不妨设先取α1 、α2(注意,下标1和2不代表第一个样本和第二个样本),此时其他变量被初始化而固定,得到以下等式:

    a12.gif   

    上式中ζ是一个常数,上式代入到⑧式中,目标函数θ(α)变为只含有α2的函数:

    1610453905611058385.png

    K(xi,xj)代表利用核函数求两个样本向量的泛函,本篇中K是个内积函数,求θ(α2)的梯度:

    求导1.png

    在α2初始值基础上,沿着梯度方向前进是最大值方向,这样就得到α2新的值:

    new.gif           

    得到α2新的值后接下来求α新的值:

    等式2.png (10.1)

    通过公式⑩得到α2新的值,实质是沿着梯度方向前进,且步长为1,如果读者了解一维搜索算法,能看出这里步长应该是计算出来的,不能盲目直接设置为1。步长系数的确定,在SMO算法中体现为对α1、α2新值的进一步裁剪。再回过头来看公式⑨,根据y1,y2是否同号,α1、α2会有以下两种线性关系:

    y1≠y2时:α1-α2=k

    y1=y2时:α1+α2=k

    根据k为正负情况,以上两种线性关系可用下图表示:

    边界.png

    通过上图可以得到α1、α2上下界,显然当y1≠y2时:

    下界:L1.gif

    上界:h1.gif

    而当y1=y2时:

    下界:L2.gif

    上界:h2.gif

    有了上下界后,即可对新值做剪裁,具体规则为:

    剪裁.png

    剪裁本质就是修改步长系数的过程,将剪裁后的α2新值代入公式(10.1)后获得α1新值。得到α1、α2后按照坐标上升法依次得到其他参数值,然后迭代多轮重复计算,可得到全体α值,同时根据公式(7.1),可得参数ω值。

        最后看下如何更新参数b的值,根据条件C-αi-μi=0,αi的新值经剪裁后恒有约束0≤αi≤C,接下来根据αi值的范围分别讨论。优化问题(8.1)有最优解时应满足KKT条件,即有下面等式存在:

    KKT.gif   

    KKT2.gif               (11)

    情形一、当αi=0时,可得μi>0,ξi=0,此时有情形一.gif,代表超平面可正确分类样本点xi,样本点xi在支持向量的两侧,大多数样本都是这种情形。

    情形二、当0<αi<C时,可得μi>0,ξi=0,根据公式(11)判断出情形二.gif,样本点xi此时是支持向量。

    情形三、当αi=C时,此时μi=0,ξi≥0并且有情形三.gif,此时样本点xi大概率是一个异常点数据(是否是异常点还要看ξi值)。

    对于情形二,由于αi对应的xi是支持向量,不失一般性,可设有0<α1<C:

    推导b.png

    对于情形一、情形二时,即α1、α2在边界时,这时两个变量的组合有三种:(0,0),(C,C),(0,C),通过观察α1、α2的线性关系图可以发现,在边界时,其实只有(0,C)这种情况。不妨设α1=0,α2=C,设b的目标值为bgoal,α1=0对应着x1是被正确分类的点,这时有:

    b-1.gif

    而x1强行设为支持向量时,可利用公式(11.1)计算出b-1_new.gif,此时有

    b-1_21_bew.gif

    对比上式,显然有

    bbig.gif

    同样对于α2=C对应的样本点有:

    b2121221.gif

    x2强行设为支持向量时,可利用公式(11.2)计算出b-2_new.gif,此时有:

    b6662121221.gif

     可以导出:

    b_2_goal.gif

    综上所述,对应情形一、情形二时,bgoal一定是b-2_new.gifb-1_new.gif之间的某个值,或者说b-2_new.gifb-1_new.gif之间值都满足KKT条件,在这种场景下通常取b得值为两者平均数:

    bgoal.gif

    至此,就分析完SMO算法主要过程,下面代码利用SMO实现SVM分类功能:

    余下文章请点击链接    SVM详解

    展开全文
  • 使用SVM对数据进行分类
  • SVM支持向量机笔记

    2019-02-20 15:49:19
    李航老师的统计学习方法的个人笔记,此文档为阅读支持向量机部分的笔记
  • from sklearn.svm import SVC import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from sklearn.linear_model import LogisticRegression import numpy as np #创建样本点 ''' n_samples:...
  • 支持向量机,能在N维平面中,找到最明显得对数据进行分类的一个超平面!看下面这幅图: 如上图中,在二维平面中,有红和蓝两类点。要对这两类点进行分类,可以有很多种分类方法,就如同图中多条绿线,都
  • 运用libSVM支持向量机算法对数据进行简单的处理,
  • 基于一个公开数据集和一个BCI竞赛数据集,提供一个SVM-CSP运动想象二分类demo,详见https://www.xxy.ink/learn/bci/2.html。包含脑电CSP特征提取,运动想象支持向量机分类,bbci和biosig工具箱等。
  • 主要介绍了Python SVM(支持向量机)实现方法,结合完整实例形式分析了基于Python实现向量机SVM算法的具体步骤与相关操作注意事项,需要的朋友可以参考下
  • 机器学习05:SVM支持向量机的学习和应用SVM解决猫狗图像分类问题 文章目录机器学习05:SVM支持向量机的学习和应用SVM解决猫狗图像分类问题前言1.从二维线性模型说起2. 如何求解SVM的相关变量3.数据集介绍4. 数据集...

    机器学习05:SVM支持向量机的学习和应用SVM解决猫狗图像分类问题

    前言

    svm作为深度学习提出前曾经风靡一段时间的机器学习方法,广泛被应用在数据分类,数据处理上。它以巧妙的算法(巧妙到对我来说真的有点复杂了😫😫😫。。。),速度快,分类正确率高而著称。我们本篇博客则重点介绍svm支持向量机的具体原理,以及他具体如何来处理分类问题。

    1.从二维线性模型说起

    让我们先来看这个问题,假设我们有给出一系列数据:
    ( x 1 , y 1 ) , ( x 2 , y 2 ) , ( x 3 , y 3 ) . . . ( x n , y n ) {(x_1,y_1),(x_2,y_2),(x_3,y_3)...(x_n,y_n)} (x1,y1),(x2,y2),(x3,y3)...(xn,yn)
    假设我们已经知道了他们中存在两个聚类,那么现在我们想要利用这一系列训练样本,训练出一个能够划分的这两个聚类的方法。使得接下来我们随机输入的点都能被正确的划分聚类。可视化问题就是下面这一张图:

    在这里插入图片描述

    我们对此的目标就是寻找到出一个分割直线 wx + b =0,能够正确划分这两个聚类(之后我们使用正样本和负样本来代称)。使用数学问题来表述就是寻找到出一系列点使得对于所有正样本代入式子wx+b得到值为正,所有负样本代入式子wx+b值为负。

    当然这里又出现问题了,就是其实根据训练数据样本的不同我们可以找到这样的分割向量其实理论上来说是可以无限种的(限制一段空间,我们依然能绘画出无数条直线)。那么选择哪一条最好呢?

    在这里插入图片描述

    当然这里学者们依然给出了一个选择分隔直线的方法,我们选择能够能够使分隔间距最大的直线也就是图中红色这一条。为什么呢?因为我们生成出来的模型其实非常严重依赖当前训练集的数据。如果我们不选择间隔最大化的这条直线可能出现因为分隔平面与正样本区域距离的不够远导致一些原本属于负样本的点却被分类到负样本去了。

    那么通过这上面的叙述,我们的问题就转化到下面这个问题上来了:

    在这里插入图片描述

    这些被圆圈圈住的点,我们就称之为支持向量(support vector)根据我们的假设这些支持向量代入直线计算只有可能为1或-1这两种值(至于如果你想了解为什么是1和-1而不是其他的数,这里推荐大家去看这位大佬的博客【机器学习算法】支持向量机入门教程及相关数学推导_SESESssss的博客-CSDN博客 ,这里我就不详细叙述了)。那么我们现在就是要寻找出一个最大间隔,这里我们使用数学表示就是:
    对 于 正 样 本 , 负 样 本 中 最 靠 近 分 隔 直 线 的 向 量 存 在 以 下 参 数 w , b 使 得 w ⊤ x + b = 1 w ⊤ x + b = − 1 我 们 计 算 这 两 条 直 线 到 直 线 w ⊤ x + b = 0 的 距 离 计 算 可 得 : γ = 2 ∥ w ∥ 对于正样本,负样本中最靠近分隔直线的向量存在以下参数w,b使得\\ \boldsymbol{w}^{\top} \boldsymbol{x}+b=1 \\ \boldsymbol{w}^{\top} \boldsymbol{x}+b=-1\\ 我们计算这两条直线到直线\boldsymbol{w}^{\top} \boldsymbol{x}+b=0 的距离计算可得:\\ \gamma=\frac{2}{\|\boldsymbol{w}\|} 线w,b使wx+b=1wx+b=1线线wx+b=0γ=w2
    这里在计算的时候使用了点到直线距离的计算公式有疑问的同学可以百度一下补充知识偶😘😘。到这里我们支持向量的最终目标就很明显了寻找到一个使得分隔最大的直线(对于高维的点是寻找分隔平面)来划分正样本和负样本。而为了寻找到这样的直线,我们其实并不需要利用所有样本,只需要这些距离分隔平面最近的向量来计算即可。所以这也是SVM(support vector machine)支持向量机名字的由来。他并不跟一般机器学习方法依赖数据集中的所有点来决定,他实际上只依赖于部分支持向量从而构建分类器。

    那么又到了扯公式的时候了,如何寻找到这样的w,b呢?来让我们继续往下计算取:
    arg ⁡ max ⁡ w , b 2 ∥ w ∥  s.t.  y i ( w ⊤ x i + b ) ≥ 1 , i = 1 , 2 , … , m . \begin{aligned} \underset{\boldsymbol{w}, b}{\arg \max } & \frac{2}{\|\boldsymbol{w}\|} \\ \text { s.t. } & y_{i}\left(\boldsymbol{w}^{\top} \boldsymbol{x}_{i}+b\right) \geq 1, i=1,2, \ldots, m . \end{aligned} w,bargmax s.t. w2yi(wxi+b)1,i=1,2,,m.
    这个式子不够方便计算,为了计算方便我们进行转换,求原始值倒数的最小值等同于求原始值的最大值,所以我们做如下转换:
    arg ⁡ min ⁡ w , b 1 2 ∥ w ∥ 2  s.t.  y i ( w ⊤ x i + b ) ≥ 1 , i = 1 , 2 , … , m \begin{aligned} \underset{w, b}{\arg \min } & \frac{1}{2}\|\boldsymbol{w}\|^{2} \\ \text { s.t. } & y_{i}\left(\boldsymbol{w}^{\top} \boldsymbol{x}_{i}+b\right) \geq 1, i=1,2, \ldots, m \end{aligned} w,bargmin s.t. 21w2yi(wxi+b)1,i=1,2,,m
    式子展开到现在其实已经知道怎么解决很明显了。相信如果是对学习过高等数学非常深刻的同学一定记得:举个例子:

    给定一个约束条件F(x,y,z) = 0需要求解f(x,y,z)的最大值的方法。使用拉格朗日乘子方法可以轻松解决这个问题:
    设 方 程 为 f ( x , y , z ) + α F ( x , y , z ) = 0 然 后 分 别 对 x , y , z , α 求 导 即 可 以 确 定 当 取 得 极 值 时 x , y , z 的 值 设方程为 f(x,y,z) + α F(x,y,z)=0\\ 然后分别对x,y,z,α求导即可以确定当取得极值时x,y,z的值 f(x,y,z)+αF(x,y,z)=0x,y,z,αx,y,z
    但是这里可能有同学又要问了?但是你这里约束条件是不等式啊?不是等式这也能直接使用拉格朗日乘子方法来求解吗?那么接下来我们就来详细探究在不等式情况下我们需要如何求解呢?(接下来涉及很多数学公式的推导,限于博主的知识水平不足,可能推导过程中存在一些错误,希望大家能够在评论区指正😥😥😥

    2. 如何求解SVM的相关变量

    这里我们先来说明拉格朗日函数是否能解决不等式约束问题。其实拉格朗日函数原本的公式是:对于带约束条件的优化问题,如果满足以下形式,我们就可以使用拉格朗日函数进行转化:
    min ⁡ x ∈ R n f ( x )  s.t.  c i ( x ) ⩽ 0 , i = 1 , 2 , ⋯   , k h j ( x ) = 0 , j = 1 , 2 , ⋯   , l \begin{aligned} &\min _{x \in \mathbb{R}^{n}} f(x) \\ &\text { s.t. } \\ &\begin{array}{l} c_{i}(x) \leqslant 0, \quad i=1,2, \cdots, k \\ h_{j}(x)=0, \quad j=1,2, \cdots, l \end{array} \end{aligned} xRnminf(x) s.t. ci(x)0,i=1,2,,khj(x)=0,j=1,2,,l
    对于上面这个式子,我们就可以转化为一个拉格朗日函数:
    L ( x , α , β ) = f ( x ) + ∑ i = 1 k α i c i ( x ) + ∑ j = 1 l β j h j ( x ) L(x, \alpha, \beta)=f(x)+\sum_{i=1}^{k} \alpha_{i} c_{i}(x)+\sum_{j=1}^{l} \beta_{j} h_{j}(x) L(x,α,β)=f(x)+i=1kαici(x)+j=1lβjhj(x)
    从而再进行求偏导联立方程等一系列操作来进行x变量的求解,而我们的svm其实是没有等式条件,所以我们可以把等式条件视为0=0,那么我们依然可以使用拉格朗日函数解决在不等式约束下的优化问题。

    说明了能够使用拉格朗日函数方法求解在不等式约束下的极值优化问题那么我们现在就来从头到尾重新说明一下我们的求解变量步骤:

    首先我们定义我们的问题如下
    arg ⁡ min ⁡ w , b 1 2 ∥ w ∥ 2  s.t.  y i ( w ⊤ x i + b ) ≥ 1 , i = 1 , 2 , … , m . \begin{aligned} \underset{\boldsymbol{w}, b}{\arg \min } & \frac{1}{2}\|\boldsymbol{w}\|^{2} \\ \text { s.t. } & y_{i}\left(\boldsymbol{w}^{\top} \boldsymbol{x}_{i}+b\right) \geq 1, i=1,2, \ldots, m . \end{aligned} w,bargmin s.t. 21w2yi(wxi+b)1,i=1,2,,m.
    对此我们引入拉格朗日乘子使得式子如下:
    L ( w , b , α ) = 1 2 ∥ w ∥ 2 − ∑ i = 1 m α i ( y i ( w ⊤ x i + b ) − 1 ) ( α 大 于 等 于 0 ) L(\boldsymbol{w}, b, \boldsymbol{\alpha})=\frac{1}{2}\|\boldsymbol{w}\|^{2}-\sum_{i=1}^{m} \alpha_{i}\left(y_{i}\left(\boldsymbol{w}^{\top} \boldsymbol{x}_{i}+b\right)-1\right) ({\alpha}大于等于0) L(w,b,α)=21w2i=1mαi(yi(wxi+b)1)α0
    然后我们令函数L(w,b,α)对w和b的偏导为0,即可计算出最终的结果。但是这样的计算仍然是十分复杂的。所以我们这里使用一点小技巧将我们要计算出的最小结果(证明过程可以查看:不简单的SVM - 知乎 (zhihu.com))转化为:
    min ⁡ w , b 1 2 w T w = min ⁡ w , b max ⁡ α L ( w , b , α ) = max ⁡ α min ⁡ w , b L ( w , b , α ) \min _{w, b} \frac{1}{2} w^{T} w=\min _{w, b} \max _{\alpha} L(w, b, \alpha)=\max _{\alpha} \min _{w, b} L(w, b, \alpha) w,bmin21wTw=w,bminαmaxL(w,b,α)=αmaxw,bminL(w,b,α)
    也就是说我们最终求解w,b需要拉格朗日函数L的参与。那么我们接下来就直接在这个前提下进行推导。对于函数L我们令他对w,b的偏导都能为0得:
    w = ∑ i = 1 m α i y i x i , ∑ i = 1 m α i y i = 0 \boldsymbol{w}=\sum_{i=1}^{m} \alpha_{i} y_{i} \boldsymbol{x}_{i}, \quad \sum_{i=1}^{m} \alpha_{i} y_{i}=0 w=i=1mαiyixi,i=1mαiyi=0
    将这样求解出来的公式代入原式可得:
    min ⁡ α 1 2 ∑ i = 1 m ∑ j = 1 m α i α j y i y j x i ⊤ x j − ∑ i = 1 m α i  s.t.  ∑ i = 1 m α i y i = 0 , α i ≥ 0 , i = 1 , 2 , … , m . \begin{array}{ll} \min _{\alpha} & \frac{1}{2} \sum_{i=1}^{m} \sum_{j=1}^{m} \alpha_{i} \alpha_{j} y_{i} y_{j} \boldsymbol{x}_{i}^{\top} \boldsymbol{x}_{j}-\sum_{i=1}^{m} \alpha_{i} \\ \text { s.t. } & \sum_{i=1}^{m} \alpha_{i} y_{i}=0, \alpha_{i} \geq 0, i=1,2, \ldots, m . \end{array} minα s.t. 21i=1mj=1mαiαjyiyjxixji=1mαii=1mαiyi=0,αi0,i=1,2,,m.
    而这个就是我们支持向量机的基本形式,我们利用这个来求的使当前函数取得最小值时的α值。然后再利用上面求导朱来的公式求得我们的w值。

    那么介绍完了这么多公式相信大家也昏昏欲睡了吧😂😂。那么我们接下来实战一下,在图像分类数据集上来尝试我们利用支持向量机svm的分类效果。

    3.数据集介绍

    SVM对于二分类问题有着非常好的效果。所以我们这里也使用一个非常著名的二分类数据集猫狗分类数据集,该数据集含有上万张的猫狗图像。他被经常使用于图像分类模型的测试和各式各样分类方法的测试。(依稀记得两年前被学长用猫狗分类数据集考核人工智能协会期末考试的噩梦时光)关于他的详细介绍和如何转化为向量,我在我之前的博客中有详细的介绍过(机器学习03:使用logistic回归方法解决猫狗分类问题_theworld666的博客-CSDN博客)。这里就不再详细介绍了。

    在这里插入图片描述

    在这里插入图片描述

    4. 数据集处理

    对于该数据集处理,为了加快速度我们这里会统一的将图像缩小为(64,64)的大小。同时也是为了方便处理,我们统一将猫狗标签使用-1,1进行划分:

    import numpy as np
    import random
    import cv2
    import glob
    
    def path_to_data(all_img_path): #循环读取所有图片的路径
        train_set = []
        for path in all_img_path:
            img = cv2.imread(path) #读取图片
            mat = np.array(cv2.resize(img,(64,64))) #将图片大小调整为64*64
            mat = mat/255 #图像像素值为0-255使用这样的方法归一化数据使得计算速度更快
            train_set.append(mat.flatten())#使用ndarray自带的flatten方法进行压平
        return train_set #返回存储所有像素数据的矩阵
    
    if '__name__' == '__main__':
        train_image_path = glob.glob("test/*.jpg")
        # 使用列表推导式获得满足条件的图片
        train_cat_path = [s for s in train_image_path if s.split('\\')[-1].split('.')[0] == "cat"]
        train_dog_path = [s for s in train_image_path if s.split('\\')[-1].split('.')[0] == "dog"]
        # 准备测试集数据,为了分类均匀猫和狗的图像选取一样多的数据量
        test_dog_path = train_cat_path[500:650]
        test_cat_path = train_cat_path[500:650]
        test_cat_path.extend(test_dog_path)
        test_label = [s.split('\\')[-1].split('.')[0] for s in test_cat_path]
        test_data = path_to_data(test_cat_path)
        label_to_index = {'dog': -1, 'cat': 1}  # 标签替换字典
        test_labels_nums = [label_to_index.get(l) for l in test_label]  # 将猫和狗标签使用数字表示
        #####准备训练集数据
        train_cat_path = train_cat_path[:500]
        train_dog_path = train_dog_path[:500]
        train_cat_path.extend(train_dog_path)
        train_image_path = train_cat_path
        random.shuffle(train_image_path)  ##训练集打乱数据加强训练模型泛化能力
        train_label = [s.split('\\')[-1].split('.')[0] for s in train_image_path]
        train_labels_nums = [label_to_index.get(l) for l in train_label]
        dataArr = path_to_data(train_image_path)
    

    在我们对测试集和训练集选择中,训练集抽取1000张图,测试集300张图片。其中训练集和测试集图片中的猫狗图片数量是一样多的。那么数据准备好了接下来我们就直接上硬菜:使用SVM代码解决图像分类问题并统计平均错误率。

    5.使用SVM解决图像分类问题并统计平均错误率

    def testRbf(dataArr,  labelArr, testDataArr,testLabelArr,k1=1.3):
        # 加载训练集
        # dataArr, testDataArr, labelArr, testLabelArr = loadCSVfile2()
        # 根据训练集计算b, alphas
        print(np.shape(dataArr))
        print(np.shape(labelArr))
        b, alphas = smoP(dataArr, labelArr, 200, 0.0001, 100, ('rbf', k1))
        datMat = np.mat(dataArr)
        labelMat = np.mat(labelArr).transpose()
        # 获得支持向量
        svInd = np.nonzero(alphas.A > 0)[0]
        sVs = datMat[svInd]
        labelSV = labelMat[svInd]
        print("支持向量个数:%d" % np.shape(sVs)[0])
        m, n = np.shape(datMat)
        errorCount = 0
        for i in range(m):
            # 计算各个点的核
            kernelEval = kernelTrans(sVs, datMat[i, :], ('rbf', k1))
            # 根据支持向量的点计算超平面,返回预测结果
            predict = kernelEval.T * np.multiply(labelSV, alphas[svInd]) + b
            # 返回数组中各元素的正负号,用1和-1表示,并统计错误个数
            if np.sign(predict) != np.sign(labelArr[i]):
                errorCount += 1
        # 打印错误率
        print('训练集错误率:%.2f%%' % ((float(errorCount) / m) * 100))
        # showDataSet(dataArr, labelMat)
        # 加载测试集
        dataArr = testDataArr
        labelArr = testLabelArr
        errorCount = 0
        datMat = np.mat(dataArr)
        labelMat = np.mat(labelArr).transpose()
        m, n = np.shape(datMat)
        for i in range(m):
            # 计算各个点的核
            kernelEval = kernelTrans(sVs, datMat[i, :], ('rbf', k1))
            # 根据支持向量的点计算超平面,返回预测结果
            predict = kernelEval.T * np.multiply(labelSV, alphas[svInd]) + b
            # 返回数组中各元素的正负号,用1和-1表示,并统计错误个数
            if np.sign(predict) != np.sign(labelArr[i]):
                errorCount += 1
        # 打印错误率
        print('测试集错误率:%.2f%%' % ((float(errorCount) / m) * 100))
        return (float(errorCount) / m) #返回错误率吧
    
    if __name__ == '__main__':
        train_image_path = glob.glob("dc/train/*.jpg")
        print(train_image_path[:10])
        # 使用列表推导式获得满足条件的图片
        train_cat_path = [s for s in train_image_path if s.split('\\')[-1].split('.')[0] == "cat"]
        train_dog_path = [s for s in train_image_path if s.split('\\')[-1].split('.')[0] == "dog"]
        # 准备测试集数据,为了分类均匀猫和狗的图像选取一样多的数据量
        test_dog_path = train_cat_path[500:650]
        test_cat_path = train_cat_path[500:650]
        test_cat_path.extend(test_dog_path)
        test_label = [s.split('\\')[-1].split('.')[0] for s in test_cat_path]
        test_data = path_to_data(test_cat_path)
        label_to_index = {'dog': -1, 'cat': 1}  # 标签替换字典
        test_labels_nums = [label_to_index.get(l) for l in test_label]  # 将猫和狗标签使用数字表示
        #####准备训练集数据
        train_cat_path = train_cat_path[:500]
        train_dog_path = train_dog_path[:500]
        train_cat_path.extend(train_dog_path)
        train_image_path = train_cat_path
        random.shuffle(train_image_path)  ##训练集打乱数据加强训练模型泛化能力
        train_label = [s.split('\\')[-1].split('.')[0] for s in train_image_path]
        train_labels_nums = [label_to_index.get(l) for l in train_label]
        dataArr = path_to_data(train_image_path)
        errornum=0
        for i in range(10):
            errornum+= testRbf(dataArr,np.mat(train_labels_nums),test_data,np.mat(test_labels_nums))
        print("平均错误率是%.2f"%(errornum/10))
        
       
    

    这里由于参考机器学习实战编写的SVM代码实在篇幅太长,所以就不放在博客里了。大家如果需要的话可以上Github下载即可😋😋😋😋。liujiawen-jpg/SVM: 使用支持向量机来解决猫狗分类问题 (github.com)

    最终我们运行平均错误率吧达到了百分之二十五:

    在这里插入图片描述

    甚至达到了百分之1可以发现我们的效果还是非常不错的(这里博主多次运行发现实际上svm对于该数据集的随机性很强)所以建议大家每次训练完成后都使用numpy保存变量值,最后取最好的变量值即可。

    结语

    在本篇博客中,我们完成了对于SVM算法原理的简要阐释,以及如何使用SVM来解决一般图像二分类问题。当然由于本人水平有限对于SVM原理的阐述没有十分完全。有差错大家可以在评论区指正。

    展开全文
  • svm支持向量机对手写字符进行分类
  • SVM支持向量机分类

    2018-05-31 17:18:45
    用matlab编程实现支持向量机分类,核函数选取,超平面建立等

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 55,571
精华内容 22,228
关键字:

svm支持向量机