图解-机器学习算法-支持向量机(04)

 目录
01 支持向量机思想
02 支持向量机背后的最优化问题
2.1 点到直线距离
2.2 限定条件的最优化问题
2.3 目标函数
03 𝑺𝒐𝒇𝒕 𝑴𝒂𝒓𝒈𝒊𝒏 𝑺𝑽𝑴
3.1 𝑆𝑜𝑓𝑡 𝑀𝑎𝑟𝑔𝑖𝑛 𝑆𝑉𝑀 概念
3.1 𝑆𝑜𝑓𝑡 𝑀𝑎𝑟𝑔𝑖𝑛 𝑆𝑉𝑀 推导
04 𝒔𝒌𝒍𝒆𝒂𝒓𝒏 中的支持向量机
4.1 案例分析
05 非线性 𝑺𝑽𝑴 分类
5.2 案例分析
06 多项式核函数
6.1 学习的对偶算法
6.2 核函数
6.3 多项式核函数
6.4 通过核函数方式使 SVM 处理非线性问题
07 高斯核函数
7.1 高斯核函数
7.2 多项式核函数“升维”原理
7.3 高斯核函数“升维”原理
7.4 模拟高斯核函数“升维”原理
7,5 超参数 𝛾
08 𝒔𝒌𝒍𝒆𝒂𝒓𝒏 中的支持向量机(高斯核函数)
8.1 案例分析 8.2 参数调整
09 𝑺𝑽𝑴 思想解决回归问题
9.1 回归事项
9.2 案例分析
9.3 参数调整

04 ScikitLearn中的支持向量机

        前面几节我们介绍了𝑆𝑉𝑀背后的数学原理,这一节来看看如何使用 𝑆𝑐𝑖𝑘𝑖𝑡 𝐿𝑒𝑎𝑟𝑛 中封装
𝑆𝑉𝑀 方法。我们还是使用之前使用过很多次的鸢尾花数据:
        需要说明的是,本节案例只处理二分类的问题,所以只取𝑦 = 0 𝑦 = 1 ,即 𝑦 < 2 ,同
时为了方便可视化,我们只取前两个特征,即特征值前 2 列。
        
import numpy as np
from matplotlib import pyplot as plt

from sklearn import datasets
# 加载鸢尾花数据集
iris = datasets.load_iris()

X = iris.data
y = iris.target
# 我们暂时只处理二分类的问题,所以只取y=0和1,即y<2
# 同时为了方便可视化,我们只取前两个特征,即:2
X = X[y<2,:2]
y= y[y<2]

# 绘制鸢尾花数据集
plt.scatter(X[y==0,0],X[y==0,1],color='r')
plt.scatter(X[y==1,0],X[y==1,1],color='g')
plt.show()

接下来我们使用 𝑆𝑐𝑖𝑘𝑖𝑡 𝐿𝑒𝑎𝑟𝑛 封装的 𝑆𝑉𝑀 方法对样本数据进行分类:
# 使用SVM算法进行分类
# 首先需要进行数据标准
from sklearn.preprocessing import StandardScaler
standardscaler = StandardScaler()
standardscaler.fit(X)
X_standard = standardscaler.transform(X)

# 第1组数据,参数C特别大,1e9
# 调用SVM算法(线性SVM),SVC中的C是classifier的意思
from sklearn.svm import LinearSVC
# 传入参数C,这个C就是正则项前面的系数,取值越大他就越倾向是一样hard margin SVM
svc = LinearSVC(C=1e9)
svc.fit(X_standard,y)

LinearSVC(C=1000000000.0, class_weight=None, dual=True, fit_intercept=True,
     intercept_scaling=1, loss='squared_hinge', max_iter=1000,
     multi_class='ovr', penalty='l2', random_state=None, tol=0.0001,
     verbose=0)
        在使用𝑆𝑉𝑀 之前,我们需要对样本数据进行标准化,这是因为 𝑆𝑉𝑀 对特征的缩放特别敏感,如下图所示,在左图中,垂直刻度比水平刻度大得多,因此此时的支持向量趋向于平行线;而右侧图像经过标准化后,更接近于真实水平。
        

 然后调用SVM方法:

        fromsklearnsvmimportLinearSVC

实例化对象创建SVM分类器:

        svc = LinearSVC(C=1e9)

        在LinearSVC传入参数C=1e9它指的是最小化方程中的C当参数C趋于无穷大时,为了求最小,只能使\xi为0。也就是说由SoftMarginSVM变成HardMarginSVM。换句话说,当C越大时,我们的容错能力越小。

        \text { mi } n \frac{1}{2}\|\omega\|^{2}+C \sum_{i=1}^{m} \xi_{i}

下面我们画出决策边界

# 函数(画决策边界)定义
def plot_decision_boundary(model,axis):
    x0, x1 = np.meshgrid(
        np.linspace(axis[0], axis[1], int((axis[1] - axis[0]) * 100)).reshape(-1, 1),
        np.linspace(axis[2], axis[3], int((axis[3] - axis[2]) * 100)).reshape(-1, 1),
    )
    X_new = np.c_[x0.ravel(), x1.ravel()]

    y_predict = model.predict(X_new)
    zz = y_predict.reshape(x0.shape)
    
    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#EF9A9A', '#FFF59D', '#90CAF9'])

    plt.contourf(x0, x1, zz, linewidth='5',cmap=custom_cmap)

# 绘制决策边界
plot_decision_boundary(svc,axis=[-3,3,-3,3])
plt.scatter(X_standard[y==0,0],X_standard[y==0,1],color='r')
plt.scatter(X_standard[y==1,0],X_standard[y==1,1],color='g')
plt.show()

 

 接下来,我们继续调整参数CC=1e9调整为C=0.01看看决策边界有何变化

# 第2组数据,参数C特别小,0.01
# 调用SVM算法(线性SVM),SVC中的C是classifier的意思
from sklearn.svm import LinearSVC
# 传入参数C,这个C就是正则项前面的系数,取值越大他就越倾向是一样hard margin SVM
svc2 = LinearSVC(C=0.01)
svc2.fit(X_standard,y)

LinearSVC(C=0.01, class_weight=None, dual=True, fit_intercept=True,
     intercept_scaling=1, loss='squared_hinge', max_iter=1000,
     multi_class='ovr', penalty='l2', random_state=None, tol=0.0001,
     verbose=0)

# 绘制决策边界
plot_decision_boundary(svc2,axis=[-3,3,-3,3])
plt.scatter(X_standard[y==0,0],X_standard[y==0,1],color='r')
plt.scatter(X_standard[y==1,0],X_standard[y==1,1],color='g')
plt.show()

 

 

        由上图可以看到,有一个红色的点被划到蓝色点的范围内,那么我们知道这都是因为SoftMarginSVM中加了宽松量的缘故。这就说明当参数C越小,我们的容错能力越大。换句话说,通过牺牲容错能力得到更好的泛化能力。

        下面我们绘制出支持向量直线,在上一节,我们知道决策边界以及上下支撑向量构成的直线的公式分别是:

决策边界w^{T}x + b = 0

上支持向量直线w^{T}x + b = 1

下支持向量直线w^{T}x+b=-1

        那么在鸢尾花的示例中,如何来求这三条直线呢?以决策边界直线为例,w^{T}b其实就是特征系数和截距:

# 观察两个决策边界图,当C=0.01时,有一个红色点被错误分类到绿色中
# 这说明C越小,我们的容错能力越大

# 查看系数
svc.coef_

array([[ 4.0324376 , -2.49295326]])

# 查看截距
svc.intercept_

array([0.95364924])

        下面绘制支持向量直线,由于在鸢尾花的示例中,特征向量只有两个,以上支持向量直线w_{1}x_{1}+w_{2}x_{2}+b=1为例,从而可知:

x_{2}=\frac{1-b-w_{1}x_{1}}{w_{2}}

同理可知下支持向量直线:

 x_{2}=\frac{-1-b-w_{1}x_{1}}{w_{2}}

# 下面我们绘制出margin那个图像,修改我们的绘图函数
def plot_svc_decision_boundary(model,axis):
    x0, x1 = np.meshgrid(
        np.linspace(axis[0], axis[1], int((axis[1] - axis[0]) * 100)).reshape(-1, 1),
        np.linspace(axis[2], axis[3], int((axis[3] - axis[2]) * 100)).reshape(-1, 1),
    )
    X_new = np.c_[x0.ravel(), x1.ravel()]

    y_predict = model.predict(X_new)
    zz = y_predict.reshape(x0.shape)
    
    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#EF9A9A', '#FFF59D', '#90CAF9'])

    plt.contourf(x0, x1, zz, linewidth='5',cmap=custom_cmap)
    
    w = model.coef_[0]
    b = model.intercept_[0]
    
    # 我们决策边界的那条线就是w0*x0+w1*x1+b=0
    # 我们将函数变化一下:x1 = -w0/x1 * x0 - b/w1,每给出一个x0就能求出x1
    # 但是对于上下两个边界,w0*x0+w1*x1+b分别等于1和-1,所以同理变化
    plot_x = np.linspace(axis[0],axis[1],200)
    up_y = -w[0]/w[1] * plot_x -b/w[1] +1/w[1]
    down_y = -w[0]/w[1] * plot_x -b/w[1] -1/w[1]
    # 但up_y和down_y有可能超过plot_svc_decision_boundary函数中的axis,所以做一个限定
    up_index = (up_y>=axis[2])&(up_y<=axis[3])
    down_index = (down_y>=axis[2])&(down_y<=axis[3])
    # 绘制图像
    plt.plot(plot_x[up_index],up_y[up_index],color='black')
    plt.plot(plot_x[down_index],down_y[down_index],color='black')

下面绘制决策边界、上、下支持向量直线。

# 绘制边界和上下边界图像
plot_svc_decision_boundary(svc,axis=[-3,3,-3,3])
plt.scatter(X_standard[y==0,0],X_standard[y==0,1],color='r')
plt.scatter(X_standard[y==1,0],X_standard[y==1,1],color='g')
plt.show()

         

        在图像中,这两个黑线部分就是margin区域,上边界有3个数据点落在上面,下边界有2个点落在上面,这个就是我们的支持向量。

        由于我们使用的是SVC,即当C=1e9HardMarginSVM方法,因此在margin区域内没有任何其他数据点。下面传入SVC2,即当C=0.01SoftMarginSVM方法,看看支持向量直线如何变化。

# 这两个黑线部分就是margin区域
# 上边界有3个数据点落在上面,下边界有2个点落在上面,这个就是我们的支撑向量
# 由于上传的svc,即hard margin SVM,所以在margin区域内没有任何其他数据点
# 下面传入svc2时的图像

# 绘制边界和上下边界图像
plot_svc_decision_boundary(svc2,axis=[-3,3,-3,3])
plt.scatter(X_standard[y==0,0],X_standard[y==0,1],color='r')
plt.scatter(X_standard[y==1,0],X_standard[y==1,1],color='g')
plt.show()

         从上图中可以看出,margin区域内有很多点,这说明相比之前的HardMarginSVMSoftMarginSVM增加了不少宽松量。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值