机器学习(13)--支持向量机

目录

一、支持向量机概述

二、Sklearn中的SVM概述

三、线性SVM损失函数

四、sklearn中进行可视化

1、导入模块

2、实例化数据集,可视化

3、网格点制作

4、建立模型并绘制决策边

目录

一、支持向量机概述

二、Sklearn中的SVM概述

三、线性SVM损失函数

四、sklearn中进行可视化

1、导入模块

2、实例化数据集,可视化

3、网格点制作

4、建立模型并绘制决策边界和超平面

5、常用接口

6、如果数据是环形呢? 

五、核函数

1、概述

2、在不同类型数据集下使用不同核函数,进行可视化

3、核函数调参

4、惩罚项系数C

六、相关评估指标

1、混淆矩阵

2、精确率

3、准确率和召回率

4、特异性与FPR

5、F1-score和Fβ-score

6、ROC和AUC

7、sklearn中的指标 


一、支持向量机概述

        支持向量机(SVM)是按监督学习方式对数据进行二元分类的广义线性分类器,其决策边界是对学习样本求解的最大边距超平面,可以将问题转换为一个求解凸二次规划的问题。

        在线性可分情况下,要在原空间中寻找两类样本最优分类超平面,选出决策边界。在线性不可分情况下,需要加入松弛变量,通过使用非线性映射规则将空间样本升维到高维度空间,来变为线性可分,这样就可以在特征空间中寻找最优分类超平面。

        SVM在各种实际问题上都表现优秀,在手写体识别和人脸识别应用广泛,在文本和超文本分类上,因为可以大量减少标准归纳和转换设置中对标记训练实例的需求,也是举足轻重的存在。另外,SVM也被用在图像分类,图像分割系统,在生物学和其他科学上SVM也备受青睐。

支持向量机的不同功能

功能
监督学习       

线性二分类与多分类(Linear Support Vector Classfication)

非线性二分类与多分类(Support Vector Classfication,SVC)

普通连续型变量的回归(SVR)

概率型连续变量的回归(Bayesian SVM)

无监督学习

支持向量聚类(Support Vector Clustering)

异常值检测(One-class SVM)

半监督学习转导支持向量机(Transductive Support Vector Machines,TSVM)

支持向量机如何工作?

        支持向量机通过在一组分布中找出一个超平面作为决策边界,使模型在数据上的分类误差尽量小,尤其是在未知的数据集上的分类误差(泛化误差)尽量小。

        决策边界向两个簇平移,直到碰到距离这个决策边界最近的点时停下,形成两个新的超平面,即图中的两条虚线,而虚线间的距离,即蓝色箭头的距离,则为决策边界的边际d。

        边际自然是越大越好,如果说边际小,在训练集上可能score很高,但是在测试集上可能出现个别点分类错误的现象,即过拟合现象。

二、Sklearn中的SVM概述

        在sklearn中的SVM也有类和函数两种表示方法。线性类LinearSVC和LinearSVC只能支持线性,而其他的类都是可以支持线性和非线性的。

含义
svm.LinearSVC线性支持向量分类
svm.LinearSVR线性支持向量回归
svm.SVC非线性支持向量分类
svm.SVR非线性支持向量回归
svm.NuSVCNu支持向量分类
svm.NuSVRNu支持向量回归
svm.OneClassSVM无监督异常值检测
svm.l1_min_c返回参数C的最低边际
函数含义
svm.libsvm.cross_validationSVM专用的交叉验证
svm.libsvm.decision_functionSVM专用的预测边际函数
svm.libsvm.fit使用libsvm训练模型
svm.libsvm.predict给定模型预测X的目标值
svm.libsvm.predict_proba预测概率

三、线性SVM损失函数

         问题的关键:就是扩大边际d。

         w是参数,垂直与决策边界,x是特征向量,与数据集有关,b是截距。

为什么这三条线的右侧是1,0,-1?

        由于w和b都是参数,所以为了使式子更加简洁,两侧同时除以常数,参数只是做了一个变换。新w和新b仍然可以做为变量。

         通过一定的数学推导可以求出来,边际d=\frac{2}{||w||},而边际越大越好,所以有了损失函数f(w)=\frac{||w||^2}{2}越小越好,如果不加平方,取模运算会导致计算量变大,所以增加了平方的运算。

        损失函数计算公式:

        \underset{w,b}{min}\frac{||w||^2}{2}

subject \ to \ y_i(\mathbf{w}\cdot \mathbf{x_i}+b)\geqslant 1,i=1,2,\cdots N.

         约束条件形式:(\alpha_i是拉格朗日乘数)

         拉格朗日乘数的求解需要转化为对偶问题,这一部分过难,先不写了,晕。

        决策函数:

         其中x_{test}作为测试样本,sign函数其实就是sgn函数,括号内大于0时返回1,小于0时返回-1。

四、sklearn中进行可视化

1、导入模块
from sklearn.datasets import make_blobs   #生成聚类数据集
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np
2、实例化数据集,可视化
x,y=make_blobs(n_samples=100,centers=2,random_state=0,cluster_std=0.6)
plt.scatter(x[:,0],x[:,1],c=y,s=50,cmap='rainbow')
plt.show()

3、网格点制作

        制作若干个连续的固定的网格点,为了方便后续决策边界的计算和可视化。

xlim=ax.get_xlim()    #返回上面图的x轴的最小值和最大值
ylim=ax.get_ylim()    #返回上面图的y轴的最小值和最大值

#print(xlim,ylim)    #(-0.7425578984849813, 3.3721920271976598) (-0.41872382476349596, 5.754870487889891)

axisx=np.linspace(xlim[0],xlim[1],30)          #根据xlim和ylim绘制网格点
axisy=np.linspace(ylim[0],ylim[1],30)
print(axisx,axisy)

axisx,axisy=np.meshgrid(axisx,axisy)           #将axisx和axisy分别向y轴和x轴进行扩充(广播)

xy=np.vstack([axisx.ravel(),axisy.ravel()]).T  #扩充为30*30的坐标点,后面基于这900个点绘制决策边界

plt.scatter(xy[:,0],xy[:,1],s=1,cmap="rainbow")
plt.show()

4、建立模型并绘制决策边界和超平面
clf=SVC(kernel='linear').fit(x,y)                #建模
z=clf.decision_function(xy).reshape(axisx.shape) #每个样本所对应的到决策边界的距离


ax=plt.gca()                                     #如果不写将不会生成决策边界
ax.contour(axisx,axisy,z,
           colors='k',
           levels=[-1,0,1],                      #代表两个过支持向量的超平面和决策边界
           alpha=0.5, 
           linestyles=['--','-','--'])           #超平面使用虚线--,决策边界使用实线-

ax.set_xlim(xlim)
ax.set_ylim(ylim)

plt.scatter(x[:,0],x[:,1],c=y,s=50,cmap='rainbow') 
plt.show()

        可以对制作网格点和绘制决策边界和超平面做一个封装函数。

def plot_svc_decision_funtion(model,ax=None):
    if ax is None:
        ax=plt.gca()
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()

    x=np.linspace(xlim[0],xlim[1],30)
    y=np.linspace(ylim[0],ylim[1],30)

    y,x=np.meshgrid(y,x)
    xy=np.vstack([x.ravel(),y.ravel()]).T
    P = model.decision_function(xy).reshape(x.shape)

    ax.contour(x,y,P,colors='k',
               levels=[-1,0,1],
               alpha=0.5,
               linestyles=['--','-','--'])
    ax.set_xlim(xlim)
    ax.set_ylim(ylim)

    plt.show()

        当建模,并绘图时只需要使用如下的代码:

plt.scatter(x[:,0],x[:,1],c=y,s=50,cmap='rainbow')
plot_svc_decision_funtion(clf)

        绘制效果:

5、常用接口
clf.predict(x)               #返回预测的label
clf.score(x,y)               #评分(建模时要分训练集和测试集,要不然分数是1)
clf.support_vectors_         #返回支持向量的坐标(说白了就是在-1和1的超平面线上的点)
clf.n_support_               #返回在两个分类下的支持向量个数
6、如果数据是环形呢? 

        环形数据如果使用线性SVM进行分类,效果非常的差,引出核函数。

x,y=make_circles(n_samples=50,factor=0.1,random_state=0,noise=0.1)
plt.scatter(x[:,0],x[:,1],c=y,s=50,cmap='rainbow')
plt.show()

五、核函数

1、概述

        核函数可以将m维空间的内积运算转化为低维空间的核函数计算,从而解决了在高维特征空间上计算“维度诅咒”的灾难。

        在Sklearn中就是参数kernel,常用的核函数有Linear线性,poly多项式,rbf径向基核函数,sigmoid核函数等。

常见的核函数计算公式:

线性核函数:k(x,y)=x^Ty+c

多项式核函数:k(x,y)=(ax^Ty+c)^d

径向基核函数:k(x,y)=exp(-\gamma||x-y||^2)=exp(-\frac{||x-y||^2}{2\sigma^2})

Sigmoid核函数:k(x,y)=tanh(ax^T+c)

不同核函数的特点:

线性核函数:简单,求解快,奥卡姆剃刀,可解释性强

多项式核函数:可解决非线性问题,参数较多,对大数量级特征不适用

径向基核函数:可以映射到无限维,决策边界更多样,只有一个参数,更容易选择,特征多时会选用。但可解释性差,容易过拟合,计算速度较慢。

Sigmoid核函数:主要用于神经网络。

如果发现径向基核函数,在多特征下效果不明显,可以descripe数据集,数据集可能有量纲不统一或者偏态问题,可以对数据集进行归一化处理,使数据集保证正态分布。

2、在不同类型数据集下使用不同核函数,进行可视化

2.1建立不同类型数据集

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap       #绘图
from sklearn.svm import SVC
from sklearn.datasets import make_circles ,make_moons,make_blobs,make_classification

n_samples=100
#建立月亮型,环形,聚类,二分类型数据集
datasets=[
    make_moons(n_samples=n_samples,noise=0.2,random_state=0),
    make_circles(n_samples=n_samples,noise=0.2,random_state=1),
    make_blobs(n_samples=n_samples,centers=2,random_state=5),
    make_classification(n_samples=n_samples,n_features=2,n_informative=2,n_redundant=0,random_state=5)
    #n_informative:相关特征 n_redundant:冗余特征
]

2.2建立20个子图

nrows=len(datasets)     #4
ncols=len(Kernel)+1     #5

fig,axes=plt.subplots(nrows,ncols,figsize=(16,12))   #4行5列的20个子图

2.3使用不同核函数建模后可视化

for ds_cnt,(x,y) in enumerate(datasets):
    #第一层循环,绘制数据集的分散情况
    ax=axes[ds_cnt,0]
    if ds_cnt ==0:                   #只在第一列的第一个图上添加标题
        ax.set_title('Input data')
    ax.scatter(x[:,0],x[:,1],c=y,zorder=10,cmap=plt.cm.Paired,edgecolors='k')    #plt.cm.Paired配对颜色映射,对比度极强
    ax.set_xticks(())
    ax.set_yticks(())

    #第二层循环,在不同核函数下进行循环,绘图在第二列到第五列
    for est_idx,kernel in enumerate(Kernel):
        #定义子图位置
        ax=axes[ds_cnt,est_idx+1]

        #建立模型svc,计算评分
        clf=SVC(kernel=kernel,gamma=2).fit(x,y)
        score=clf.score(x,y)

        #绘制数据本身分布散点图
        ax.scatter(x[:,0],x[:,1],c=y,zorder=10,cmap=plt.cm.Paired,edgecolors='k')

        #绘制支持向量
        ax.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,1],s=50,facecolors='none',zorder=10,edgecolors='k')

        #绘制决策边界
        x_min, x_max = x[:, 0].min() - .5, x[:, 0].max() + .5   #决策边界略大于所有的点围成的区域边界
        y_min, y_max = x[:, 1].min() - .5, x[:, 1].max() + .5

        #若干个坐标点,mgrid合并了linspace和meshgrid,表示为[min,max,step]
        xx,yy=np.mgrid[x_min:x_max:200j,y_min:y_max:200j]

        #np.c_类似于np.vstack
        z=clf.decision_function(np.c_[xx.ravel(),yy.ravel()]).reshape(xx.shape)

        #填充等高线不同颜色
        ax.pcolormesh(xx,yy,z>0,cmap=plt.cm.Paired)

        #绘制等高线
        ax.contour(xx,yy,z,colors='k',linestyles=['--','-','--'],levels=[-1,0,1])

        #坐标轴不显示
        ax.set_xticks(())
        ax.set_yticks(())
        
        #在第一行的图上打标签
        if ds_cnt == 0 :
            ax.set_title(kernel)
        
        #在图上加评分
        ax.text(0.95,0.06,('%.2f'%score).lstrip('0'),
                size=15,
                bbox=dict(boxstyle='round',alpha=0.8,facecolor='white'),   #填充白色0.8透明度圆框
                transform=ax.transAxes,                                    #保证坐标轴为原来坐标轴
                horizontalalignment='right')                               #水平靠右
plt.tight_layout()    #紧密排布子图
plt.show()

3、核函数调参

        核函数调参一般有gamma,degree,coef0三个参数,对于不同核函数在三个参数上也有不同的影响。

input表达式gammadegreecoef0
'linear'k(x,y)=x^TyNoNoNo
'poly'k(x,y)=(\gamma x^Ty+r)^dYesYesYes
'sigmoid'k(x,y)=tanh(\gamma x^T+r)YesNoYes
'rbf'k(x,y)=e^{(-\gamma||x-y||^2)}YesNoNo

        其中除了线性核函数以外,其他核函数还要受到gamma(\gamma),degree(d),coef0(常数r)的影响。

参数含义
degree整数,可不填,默认为3
gamma

浮点数,可不填,默认为'auto'

输入‘auto’,使用1/n_features

输入‘scale’,使用1/(n_features*x.std())

输入‘auto_deprecated’,表明没有传递明确gamma值

coef0

浮点数,可不填,默认为0.0

4、惩罚项系数C

        惩罚项系数C也作为SVM调参的重点,用于权衡‘训练样本正确分类’和‘决策函数的边际最大化’,C越高越会扩大化边界,决策功能更简单。浮点数,默认状况下为1,必须大于等于0,可以使用网格搜索或学习曲线来调整C的值。

六、相关评估指标

1、混淆矩阵

        在机器学习中,混淆矩阵(confusion matrix)主要用于比较分类结果和实际预测值,可以把分类的结果的精度显示在一个混淆矩阵中。

        TP(True Positive)真正类,样本真实类别为正,预测为正。

        FP(False Positive)假正类,样本真实类别为负,预测为正。

        TN(True Negative)真负类,样本真实类别为正,预测为负。

        FN(False Negative)假负类,样本真实类别为负,预测为负。

真实值
10
预测值1TPFP
0FNTN

2、精确率

        精确率是最常用的分类性能指标,可以用来表示模型的精度,模型的精度越高,说明模型的效果越好。

        Accuracy=(TP+TN)/(TP+FN+TN+FP)

3、准确率和召回率

        准确率(Precision):表示样本预测为正类中,样本真实类别为正类的比例。准确率越高,模型效果越好。

        Precision=TP/(TP+FP)

        召回率(Recall):表示真实类别为正类中,样本预测为正类的比例。召回率越高,模型效果越好。

        Recall=TP/(TP+FN)

4、特异性与FPR

        特异性(Specificity):表示样本预测为负类中,样本真实为负类的比例。

        FPR:模型识别为正类的负类样本中占所有负类样本的比例,FPR越低越好。

        FPR=FP/(TN+FP)=1-Specificity

5、F1-score和Fβ-score

        Fβ-score:对于准确率和召回率的加权平均,召回率是准确率的β倍

        F\beta-Score=(1+\beta^2)\frac{Precision\cdot Recall}{(\beta^2\cdot Precision)+Recall}

        常用的F1-score,是将参数β=1时的取值,是统计学中用来衡量二分类模型精确度的一种指标,被定义为正确率和召回率的调和平均数,取值范围是0-1,越接近1,模型效果越好。

        F1-Score=\frac{2 \cdot Precision \cdot Recall}{Precision+Recall}

6、ROC和AUC

        ROC曲线(接收者操作特征Receiver operating charcteristic),横坐标为负正类率(FPR),纵坐标为真正类率(TPR),可以根据测试样本上表现的TPR和FPR对调整分类时所指定的阈值。

        AUC(Area under roc curve)代表ROC曲线与横纵坐标轴所围成的面积,面积一般介于0.5-1.0之间(优于随机猜测),AUC的面积越大,ROC曲线越靠近(0,1)点,更加弯曲,远离角分线,则模型的效果越好。AUC==0.5时为随机猜测时的面积,即y=x曲线。

        

参考视频:c7 2.3.2 重要参数C & 总结_哔哩哔哩_bilibili​​​​​​

参考书籍:《机器学习》周志华

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值