吴恩达机器学习作业八:SVM支持向量机

数据集在作业一

支持向量机

支持向量机(Support Vector Machine,SVM) 是一种经典的监督学习算法,主要用于分类任务(也可扩展到回归任务),其核心思想是:在特征空间中找到一个最优超平面,将不同类别的样本分割开,且使该超平面与两侧最近样本点的距离(即 “间隔”)最大。

由“使该超平面与两侧最近样本点的距离(即 “间隔”)最大”可知,该超平面的方向和位置是确定的。

算法流程

1.调用sklearn中的svm构建所需要的模型

2.进行模型训练、

3.进行模型测试

代码

线性分类

读取数据及可视化

import numpy as np
import matplotlib.pyplot as plt
from scipy.io import loadmat
from  sklearn import svm

# 线性分类
# 读取数据
data=loadmat('ex6data1.mat')
X=data['X']
y=data['y']
# print(X.shape,y.shape)(51, 2) (51, 1)

# 可视化
def data_plot(X,y):
    plt.scatter(X[:,0],X[:,1],c=y.flatten())
    plt.xlabel('x1')
    plt.ylabel('x2')
    # plt.show()

决策边界,把已有的数据均匀分成500个区域,然后用等高线图画出决策边界

def plot_decision_boundary(model,X):
    x_min,x_max=X[:,0].min()*1.1,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))
    Z=model.predict(np.c_[xx.ravel(),yy.ravel()])
    Z=Z.reshape(xx.shape)
    plt.contour(xx,yy,Z,cmap=plt.cm.Spectral)
    plt.xlabel('x1')
    plt.ylabel('x2')

这里的model就是我们要训练的分类模型。

  • np.linspace 生成从最小值到最大值的等间隔数值,这里各生成 500 个点

  • np.meshgrid 将这些点转换为网格矩阵,xxyy 都是形状为 (500, 500) 的矩阵,分别代表网格中每个点的 x 坐标和 y 坐标

  • xx.ravel()yy.ravel() 将二维网格矩阵展平为一维数组

  • np.c_[] 将两个一维数组按列组合,形成形状为 (250000, 2) 的测试点矩阵

  • 使用训练好的模型对所有网格点进行预测,得到每个点的类别

使用 contour 函数绘制轮廓线,不同的类别区域会被区分开来,这些轮廓线就是模型的决策边界

通过调用sklearn.svm.SVC()创建支持向量机模型

models=[svm.SVC(C=c,kernel='linear')for c in [1,100]]
clfs=[model.fit(X,y.ravel()) for model in models]
score=[model.score(X,y) for model in clfs]
# print(score)[0.9803921568627451, 1.0]

这里的c是惩罚系数,是软间隔 SVM 中的关键参数,越大表示对误分类的惩罚越严厉

  • C较小时:模型允许更多误分类(松弛变量更大),更注重最大化间隔,决策边界更 “宽松”,可能欠拟合(对训练数据拟合不足)。

  • C较大时:对误分类的惩罚更严厉,模型会尽量减少误分类,甚至为了正确分类少数异常点而让间隔变窄,决策边界更 “陡峭”,可能过拟合(过度拟合训练数据中的噪声或异常点)。

model.fit()是对于传入数据集进行训练

SVM的损失函数比较特殊,它的优化目标为

前者是为了最小化间隔,后者是为了减少误分类。

画出决策边界

def plot():
    titles=['C=1','C=100']
    for model,title in zip(clfs,titles):
        data_plot(X, y)
        plot_decision_boundary(model,X)
        plt.title(title)
        plt.show()

plot()

非线性分类

高斯核函数

前面我们提到了处理非线性的方法之一是利用高阶特征项,这里我们可以使用另一个方法来达到同样的效果,我们可以把高斯核函数理解成指数函数,通过泰勒级数展开式来理解。

这里我们就可以避免高纬度计算了。

def gaussKernel(x1, x2, sigma):
    return np.exp(-(x1 - x2) ** 2).sum() / (2 * sigma ** 2)

读取数据及可视化

data_2=loadmat('ex6data2.mat')
X2=data_2['X']
y2=data_2['y']
# print(X.shape,y.shape)(863, 2) (863, 1)
# 可视化
# data_plot(X2,y2)
# plt.show()

通过调用sklearn.svm.SVC()创建支持向量机模型

sigma=0.1
gamma=1/(2*sigma**2)
model=svm.SVC(C=1,kernel='rbf',gamma=gamma)
model.fit(X2,y2.ravel())
# plot_decision_boundary(model,X2)
# plt.show()

如何找最佳权值

下面我们的目的是找出最佳权值,使得分类效果最好

读入数据及可视化

# 读入数据
data_3=loadmat('ex6data3.mat')
X3=data_3['X']
y3=data_3['y']
# 交叉验证集
X_val=data_3['Xval']
y_val=data_3['yval']
# print(X.shape,y.shape)(51, 2) (51, 1)
# 可视化
data_plot(X3,y3)
plt.show()

通过调用sklearn.svm.SVC()创建支持向量机模型

# 通过调用sklearn.svm.SVC()创建支持向量机模型
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)
for c in Cvalues:
    for sigma in sigmavalues:
        gamma=1/(2*sigma**2)
        model=svm.SVC(C=c,kernel='rbf',gamma=gamma)
        model.fit(X3,y3.ravel())
        score=model.score(X_val,y_val)
        if score > best_score:
            best_score = score
            best_pair = (c, sigma)

print('最优(C, sigma)权值:', best_pair, '决定系数:', best_score)

用确定好的权重再重新声明一次支持向量机

model = svm.SVC(C=1, kernel='rbf', gamma=np.power(0.1, -2.) / 2)
# 用确定好的权重再重新声明一次支持向量机
model.fit(X3, y3.flatten())
plot_decision_boundary(model, X3)
plt.show()

总结

读入数据——构建模型(确定线性还是非线性)——如果是非线性,可以找一下最佳权值——训练模型——测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值