11、支持向量机

本文通过Python的scikit-learn库探讨了支持向量机(SVM)在分类任务中的应用。首先展示了如何加载数据并绘制数据集的散点图,接着讨论了线性核函数和高斯核函数在SVM中的作用。对于线性核函数,通过调整权重C观察了决策边界的改变。而对于非线性分类,使用高斯核函数(RBF)并以不同gamma值进行实验,通过交叉验证选择了最佳的超参数。最终,展示了最佳参数下的决策边界。
摘要由CSDN通过智能技术生成
"""
SVM支持向量机
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sb
from scipy.io import loadmat
from sklearn import svm

mat = loadmat('data/ex6data1.mat')
# print(mat.keys())  # 打印关键字
'''打印结果: dict_keys(['__header__', '__version__', '__globals__', 'X', 'y'])'''
X = mat['X']
y = mat['y']
'''大多数SVM的库会自动帮你添加额外的特征x0,所以无需手动添加。'''

#print(X, '\n', y)  # X,y都是二维数组


# 画数据集的散点图
def plotData(X, y):
    plt.figure(figsize=(8, 5))
    plt.scatter(X[:, 0], X[:, 1], c=y.flatten(), cmap='rainbow')
    # c:色彩或颜色序列   camp:colormap(颜色表)
    plt.xlabel('X1')
    plt.ylabel('X2')


plotData(X, y)
#plt.show()

数据散点图:
在这里插入图片描述

# 画数据集的散点图
def plotData(X, y):
    plt.figure(figsize=(8, 5))
    plt.scatter(X[:, 0], X[:, 1], c=y.flatten(), cmap='rainbow')
    # c:色彩或颜色序列   camp:colormap(颜色表)
    plt.xlabel('X1')
    plt.ylabel('X2')


# plotData(X, y)
# plt.show()

# 画决策边界
def plotBoundary(clf, X):
    x_min, x_max = X[:, 0].min() * 1.2, X[:, 0].max() * 1.1  # 横坐标轴范围
    y_min, y_max = X[:, 1].min() * 1.1, X[:, 1].max() * 1.1  # 纵坐标轴范围
    xx, yy = np.meshgrid(np.linspace(x_min, x_max, 500),
                         np.linspace(y_min, y_max, 500))  # 生成网格点坐标矩阵
    # np.linspace(x_min, x_max, 500).shape---->(500, )  500是样本数
    # xx.shape, yy.shape ---->(500, 500) (500, 500)
    '''
    >>> X, Y = np.meshgrid([1,2,3], [4,5,6,7])
    >>> X
    array([[1, 2, 3],
           [1, 2, 3],
           [1, 2, 3],
           [1, 2, 3]])
    >>> Y
    array([[4, 4, 4],
           [5, 5, 5],
           [6, 6, 6],
           [7, 7, 7]])
    '''
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])  # model.predict:模型预测 (250000, )
    # ravel()将多维数组转换为一维数组 xx.ravel().shape ----> (250000,1)
    # np.c 中的c是column(列)的缩写,就是按列叠加两个矩阵,就是把两个矩阵左右组合,要求行数相等。
    # np.c_[xx.ravel(), yy.ravel()].shape ----> (250000,2) 就是说建立了250000个样本
    """
    ==> np.c_[X.ravel(),Y.ravel()]
    ==> [[1,4],
         [2,4],
         [3,4],
         [1,5],
         [2,5],
         ...
         [3,7]]
    """
    Z = Z.reshape(xx.shape)  # 重塑预测结果矩阵 (500,500)
    #print(Z)
    '''
    运行结果:
    [[0 0 0 ... 0 0 0]
     [0 0 0 ... 0 0 0]
     [0 0 0 ... 0 0 0]
     ...
     [1 1 1 ... 1 1 1]
     [1 1 1 ... 1 1 1]
     [1 1 1 ... 1 1 1]]
    '''
    plt.contour(xx, yy, Z)  # 绘制等高线


models = [svm.SVC(C, kernel='linear') for C in [1, 100]]
# 支持向量机模型 (kernel:核函数选项,这里是线性核函数 , C:权重,这里取1和100)
# 线性核函数画的决策边界就是直线
clfs = [model.fit(X, y.ravel()) for model in models]  # model.fit:拟合出模型
title = ['SVM Decision Boundary with C = {} (Example Dataset 1)'.format(C) for C in [1, 100]]  # 图像标题
for model, title in zip(clfs, title):
    # zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
    plt.figure(figsize=(8, 5))
    plotData(X, y)  # 数据散点图
    plotBoundary(model, X)  # 用拟合好的模型(预测那些250000个样本),绘制决策边界
    plt.title(title)

# plt.show()
"""
当C比较小时:模型对误分类的惩罚增大,间隔比较宽。
当C比较大时:模型对误分类的惩罚减小,间隔比较窄。
"""

在这里插入图片描述
在这里插入图片描述
高斯核函数公式:
在这里插入图片描述

# 高斯核函数,用于非线性分类
def gaussKernel(x1, x2, sigma):
    return np.exp(-((x1 - x2) ** 2).sum() / (2 * sigma ** 2))


print(gaussKernel(np.array([1, 2, 1]), np.array([0, 4, -1]), 2.))
# 运行结果:0.32465246735834974
# 引入第二个数据集
mat = loadmat('data/ex6data2.mat')
X2 = mat['X']
y2 = mat['y']
plotData(X2, y2)
#plt.show()

在这里插入图片描述

# 画决策边界
sigma = 0.1
gamma = np.power(sigma, -2.) / 2
'''
高斯核函数中的gamma越大,相对高斯函数中的σ越小,此时的分布曲线也就会越高越瘦。
高斯核函数中的gamma越小,相对高斯函数中的σ越大,此时的分布曲线也就越矮越胖。
'''
clf = svm.SVC(C=1, kernel='rbf', gamma=gamma)  # kernel='rbf'表示支持向量机使用高斯核函数
model = clf.fit(X2, y2.flatten())  # 拟合出模型
plotData(X2, y2)
plotBoundary(model, X2)  # 模型(预测),画决策边界
#plt.show()

在这里插入图片描述
引入第三组数据:

# 引入第三个数据集
mat3 = loadmat('data/ex6data3.mat')
X3, y3 = mat3['X'], mat3['y']  # 训练集
Xval, yval = mat3['Xval'], mat3['yval']  # 交叉验证集
plotData(X3, y3)  # 画训练集散点图
#plt.show()

在这里插入图片描述

Cvalues = (0.01, 0.03, 0.1, 0.3, 1., 3., 10., 30.)  # 权重C的候选值
sigmavalues = Cvalues  # 核函数参数的候选值
best_pair, best_score = (0, 0), 0  # 最佳的(C,sigma)权值 ,决定系数(R2)
# 寻求最佳权值(C,sigma)
for C in Cvalues:
    for sigma in sigmavalues:
        gamma = np.power(sigma, -2.) / 2
        model = svm.SVC(C=C, kernel='rbf', gamma=gamma)  # 使用核函数的支持向量机
        model.fit(X3, y3.flatten())  # 拟合出模型
        this_score = model.score(Xval, yval)  # 利用交叉验证集来选择最合适的权重
        '''
        model.score函数的返回值是决定系数,也称R2。
        可以测度回归直线对样本数据的拟合程度,决定系数的取值在0到1之间,
        决定系数越高,模型的拟合效果越好,即模型解释因变量的能力越强。
        '''
        # 选择拟合得最好的权重值
        if this_score > best_score:
            best_score = this_score
            best_pair = (C, sigma)
print('最优(C,sigma)权值:', best_pair, '决定系数为:', best_score)
# 最优(C,sigma)权值: (1.0, 0.1) 决定系数为: 0.965
model = svm.SVC(C=1., kernel='rbf', gamma=np.power(.1, -2.) / 2)  # 用确定好的权重再重新声明一次支持向量机
model.fit(X3, y3.flatten())  # 模型拟合
plotData(X3, y3)
plotBoundary(model, X3)  # 画模型的决策边界
#plt.show()

model.score ( ) 函数的返回值是决定系数,也称R2,其计算公式如下:
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值