1. 问题和数据

在本练习中,您将使用支持向量机(svm)构建一个垃圾邮件分类器。

在本练习的前半部分,您将使用支持向量机(svm)处理各种示例2D数据集。使用这些数据集进行试验将帮助您直观地了解支持向量机的工作方式,以及如何在支持向量机中使用高斯核。
在练习的下一部分中,您将使用支持向量机构建一个垃圾邮件分类器

对于线性可分案例,我们的任务是找到一条最佳的决策边界,使得离这条决策边界最近的点到该决策边界的距离最远,即为要有最大间隔。

损失函数公式如下:

在本节中要用到新的库,scikit-learn,简称sklearn。可以进行数据的预处理以及最后算法的评估。

2.线性可分案例

导入包,numpy和pandas是做运算的库,matplotlib是画图的库。
数据集是在MATLAB的格式,所以要加载它在Python,我们需要使用一个SciPy工具。

import numpy as np
import scipy.io as sio
import matplotlib.pyplot as plt

导入数据集

data = sio.loadmat('ex6data1.mat')
print('data.keys():', data.keys())

输出结果:

data.keys(): dict_keys(['__header__', '__version__', '__globals__', 'X', 'y'])

指定X, y, 打印shape来看看

X, y = data['X'], data['y']
print('X.shape, y.shape:', X.shape, y.shape)
print('X:', X)
print('y:', y)

输出shape和X,y

X.shape, y.shape: (51, 2) (51, 1)
X: [[1.9643   4.5957  ][2.2753   3.8589  ][2.9781   4.5651  ][2.932    3.5519  ][3.5772   2.856   ][4.015    3.1937  ][3.3814   3.4291  ][3.9113   4.1761  ][2.7822   4.0431  ][2.5518   4.6162  ][3.3698   3.9101  ][3.1048   3.0709  ][1.9182   4.0534  ][2.2638   4.3706  ][2.6555   3.5008  ][3.1855   4.2888  ][3.6579   3.8692  ][3.9113   3.4291  ][3.6002   3.1221  ][3.0357   3.3165  ][1.5841   3.3575  ][2.0103   3.2039  ][1.9527   2.7843  ][2.2753   2.7127  ][2.3099   2.9584  ][2.8283   2.6309  ][3.0473   2.2931  ][2.4827   2.0373  ][2.5057   2.3853  ][1.8721   2.0577  ][2.0103   2.3546  ][1.2269   2.3239  ][1.8951   2.9174  ][1.561    3.0709  ][1.5495   2.6923  ][1.6878   2.4057  ][1.4919   2.0271  ][0.962    2.682   ][1.1693   2.9276  ][0.8122   2.9992  ][0.9735   3.3881  ][1.25     3.1937  ][1.3191   3.5109  ][2.2292   2.201   ][2.4482   2.6411  ][2.7938   1.9656  ][2.091    1.6177  ][2.5403   2.8867  ][0.9044   3.0198  ][0.76615  2.5899  ][0.086405 4.1045  ]]
y: [[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][1]]

画出数据的散点图来看看分布状况

def plot_data():plt.scatter(X[:, 0], X[:, 1], c=y.flatten(), cmap='jet')  # cmap相当于是配色盘的意思,这次选择了jet这一套颜色。y.flatten()# 是将y拉伸成一列, 这样每一个X对应一个y,而y只有0,1两种,c是给数据点颜色,把0和1的数据点给出不同的颜色plt.xlabel('x1')plt.ylabel('y1')plt.show()plot_data()  # 调用函数,画出数据的散点图来看看分布状况

导入sklearn.svm,

from sklearn.svm import SVC

SVC的用法如下:

使用sklearn.svm的svc进行求解

svc1 = SVC(C=1, kernel='linear')  # C是误差惩罚系数,代替之前使用lamda的方式,用来调节模型方差与偏差的问题; kernel我们暂就用linear
svc1.fit(X, y.flatten())  # 此处默认跟着操作的,格式问题记住这样用就行
print(svc1)
print(svc1.predict(X))  # 预测结果
print(svc1.score(X, y.flatten()))  # 显示分数,当前预测的准确率为0.90039

打印svc1、预测结果和准确率;当前预测的准确率为0.90039

SVC(C=1, kernel='linear')
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0]
0.9803921568627451

绘制决策边界

def plot_boundary(model):x_min, x_max = -0.5, 4.5  # 根据散点图看出数据点的x范围y_min, y_max = 1.3, 5  # 根据散点图看出数据点的y范围xx, yy = np.meshgrid(np.linspace(x_min, x_max, 500), np.linspace(y_min, y_max, 500))  # np.meshgrid是画格子,这里xx和yy# 的shape为(500,500),意思就是画个均匀的500*500的格子z = model.predict(np.c_[xx.flatten(), yy.flatten()])  # 将xx,和yy都从500*500降成一维,再用np.c_[]合并成shape为(250000,2)zz = z.reshape(xx.shape)  # (500,500)plt.contour(xx, yy, zz)   # 绘制等高线 # 这个等高线暂时不是很理解,这个画法摘自网络plot_boundary(svc1)  # 调用边界函数画出决策边界
plot_data()    # 调用plot_data() 画出数据的散点图
plt.show()    # 上面两行只是调用,还没有画出来,有了这行之后是把上面两行画出的决策边界和散点图都显示到同一张图上来

可以看出C=1时有一个样本点是被错分的

接下来我们换一个C的值来看看预测效果

svc100 = SVC(C=100, kernel='linear')  # C改为100
svc100.fit(X, y.flatten())
print(svc100.predict(X))  # 打印C=100时的预测结果
print(svc100.score(X, y.flatten()))  # 显示分数,当前预测的准确率为1.0

输出预测结果和准确率:

[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 1]
1.0

调用边界函数画出C=100时的决策边界

plot_boundary(svc100)  # 调用边界函数画出C=100时的决策边界
plot_data()
plt.show()

这回原本被分错的点也被正确分类了,但是这样其实有点不太好,可能会出现过拟合?只是我们当前的数据点太少,看不出来。

完整代码:

# -*- coding: utf-8 -*-
"""
Created on Sat June 23 15:06:11 2022
@author: wzj
python version: python 3.9Title: 支持向量机(Support Vector Machines)案例:使用支持向量机(svm)构建一个垃圾邮件分类器。数据集:数据文件是ex6data1.mat
"""import numpy as np
import scipy.io as sio
import matplotlib.pyplot as pltdata = sio.loadmat('ex6data1.mat')
print('data.keys():', data.keys())X, y = data['X'], data['y']
print('X.shape, y.shape:', X.shape, y.shape)
print('X:', X)
print('y:', y)# ---------------------------
# 画出数据的散点图来看看分布状况
def plot_data():plt.scatter(X[:, 0], X[:, 1], c=y.flatten(), cmap='jet')  # cmap相当于是配色盘的意思,这次选择了jet这一套颜色。y.flatten()# 是将y拉伸成一列, 这样每一个X对应一个y,而y只有0,1两种,c是给数据点颜色,把0和1的数据点给出不同的颜色plt.xlabel('x1')plt.ylabel('y1')plt.show()# plot_data()  # 调用函数,画出数据的散点图来看看分布状况
# ---------------------------# ---------------------------
from sklearn.svm import SVC
svc1 = SVC(C=1, kernel='linear')  # C是误差惩罚系数,代替之前使用lamda的方式,用来调节模型方差与偏差的问题; kernel我们暂就用linear
svc1.fit(X, y.flatten())  # 此处默认跟着操作的,格式问题记住这样用就行
print(svc1)
print(svc1.predict(X))  # 打印预测结果
print(svc1.score(X, y.flatten()))  # 显示分数,当前预测的准确率为0.90039# 绘制决策边界
def plot_boundary(model):x_min, x_max = -0.5, 4.5  # 根据散点图看出数据点的x范围y_min, y_max = 1.3, 5  # 根据散点图看出数据点的y范围xx, yy = np.meshgrid(np.linspace(x_min, x_max, 500), np.linspace(y_min, y_max, 500))  # np.meshgrid是画格子,这里xx和yy# 的shape为(500,500),意思就是画个均匀的500*500的格子z = model.predict(np.c_[xx.flatten(), yy.flatten()])  # 将xx,和yy都从500*500降成一维,再用np.c_[]合并成shape为(250000,2)zz = z.reshape(xx.shape)  # (500,500)plt.contour(xx, yy, zz)   # 绘制等高线 # 这个等高线暂时不是很理解,这个画法摘自网络plot_boundary(svc1)  # 调用边界函数画出决策边界
plot_data()    # 调用plot_data() 画出数据的散点图
plt.show()    # 上面两行只是调用,还没有画出来,有了这行之后是把上面两行画出的决策边界和散点图都显示到同一张图上来
# 可以看出C=1时有一个样本点是被错分的# 接下来我们换一个C的值来看看预测效果
svc100 = SVC(C=100, kernel='linear')  # C改为100
svc100.fit(X, y.flatten())
print(svc100.predict(X))  # 打印C=100时的预测结果
print(svc100.score(X, y.flatten()))  # 显示分数,当前预测的准确率为1.0plot_boundary(svc100)  # 调用边界函数画出C=100时的决策边界
plot_data()
plt.show()

3.线性不可分案例

我们在之前面对线性不可分时用的方法都是建立特征多项式,通过把低维的变量映射到高维,就有可能变成可分的。

而在本次中,我们使用核函数,它的原理也和之前差不多的,可以自动将低维空间映射到高维空间,可以在低微空间计算出高维空间的点积结果(后半句不太明白啥意思,先不管)。

常用的核函数有多项式核,高斯核,拉普拉斯核等,如下 所示。本次会使用的是高斯核。在高斯核中,会有一个叫σ\sigmaσ的参数(可能我看的讲解的视频的作者叫错了,叫它gamma),gamma对模型复杂度的影响如下 ,我们之后会通过调整gamma的大小来观察对模型的影响情况。

首先导入库

import numpy as np
import scipy.io as sio
import matplotlib.pyplot as plt

导入数据集,打印表头看看

data = sio.loadmat('ex6data2.mat')
print('data.keys():', data.keys())

输出表头

data.keys(): dict_keys(['__header__', '__version__', '__globals__', 'X', 'y'])

获取X,y,并打印shape来看看

X, y = data['X'], data['y']
print('X.shape, y.shape:', X.shape, y.shape)

输出X,y的shape

X.shape, y.shape: (863, 2) (863, 1)

画出数据的散点图来看看分布状况

def plot_data():plt.scatter(X[:, 0], X[:, 1], c=y.flatten(), cmap='jet')  # cmap相当于是配色盘的意思,这次选择了jet这一套颜色。y.flatten()# 是将y拉伸成一列, 这样每一个X对应一个y,而y只有0,1两种,c是给数据点颜色,把0和1的数据点给出不同的颜色plt.xlabel('x1')plt.ylabel('y1')plt.show()plot_data()  # 调用函数,画出数据的散点图来看看分布状况

输出散点图:

导入sklearn.svm的库

from sklearn.svm import SVC

调用SVC进行模型预测

svc1 = SVC(C=1, kernel='rbf', gamma=1)  # C是误差惩罚系数,代替之前使用lamda的方式,用来调节模型方差与偏差的问题; kernel的rbf是我们要用的高斯核
# 函数的意思,先设置gamma=1,之后会调整采用不同的gamma值来查看不同的gamma对模型的影响
svc1.fit(X, y.flatten())  # 此处跟上一步是配套操作,默认跟着操作的,格式问题记住这样用就行
print(svc1.score(X, y.flatten()))  # 显示预测准确率

输出准确率,当前预测的准确率为0.8088064889918888

0.8088064889918888

绘制决策边界

def plot_boundary(model):x_min, x_max = 0, 1.0  # 根据散点图看出数据点的x范围y_min, y_max = 0.4, 1.0  # 根据散点图看出数据点的y范围xx, yy = np.meshgrid(np.linspace(x_min, x_max, 500), np.linspace(y_min, y_max, 500))  # np.meshgrid是画格子,这里xx和yy# 的shape为(500,500),意思就是画个均匀的500*500的格子z = model.predict(np.c_[xx.flatten(), yy.flatten()])  # 将xx,和yy都从500*500降成一维,再用np.c_[]合并成shape为(250000,2)zz = z.reshape(xx.shape)  # (500,500)plt.contour(xx, yy, zz)   # 绘制等高线 # 这个等高线暂时不是很理解,这个画法摘自网络plot_boundary(svc1)  # 调用边界函数画出决策边界
plot_data()    # 调用plot_data() 画出数据的散点图
plt.show()    # 上面两行只是调用,还没有画出来,有了这行之后是把上面两行画出的决策边界和散点图都显示到同一张图上来

绘制出gamma=1时散点图和决策边界图像:

可以看出,当前还不能很好的区分数据点。

我们把上面的gamma=1换成gamma=50:
svc1 = SVC(C=1, kernel=‘rbf’, gamma=50)

绘制出gamma=50时的散点图和决策边界图像:

从图中可以看出目前准确率提高了不少,但仍存在一些点不能被区分;并且此时打印出的准确率也达到了0.9895712630359212

0.9895712630359212

我们再把上面的gamma=50换成gamma=1000:
svc1 = SVC(C=1, kernel=‘rbf’, gamma=1000)

此时模型复杂了很多,绘制出gamma=1000时的散点图和决策边界图像:

从图中可以看出目前准确率又得到提高了,每一个数据点都得到了正确的分类,并且此时打印出的准确率也达到了1.0

1.0

完整代码:

# -*- coding: utf-8 -*-
"""
Created on Sat June 23 18:01:23 2022
@author: wzj
python version: python 3.9Title: 支持向量机(Support Vector Machines)——线性不可分案例案例:使用支持向量机(svm)构建一个垃圾邮件分类器。数据集:数据文件是ex6data2.mat
"""import numpy as np
import scipy.io as sio
import matplotlib.pyplot as pltdata = sio.loadmat('ex6data2.mat')
print('data.keys():', data.keys())X, y = data['X'], data['y']
print('X.shape, y.shape:', X.shape, y.shape)# ---------------------------
# 画出数据的散点图来看看分布状况
def plot_data():plt.scatter(X[:, 0], X[:, 1], c=y.flatten(), cmap='jet')  # cmap相当于是配色盘的意思,这次选择了jet这一套颜色。y.flatten()# 是将y拉伸成一列, 这样每一个X对应一个y,而y只有0,1两种,c是给数据点颜色,把0和1的数据点给出不同的颜色plt.xlabel('x1')plt.ylabel('y1')plt.show()# plot_data()  # 调用函数,画出数据的散点图来看看分布状况
# ---------------------------# ---------------------------
from sklearn.svm import SVC  # 导入sklearn.svm的库svc1 = SVC(C=1, kernel='rbf', gamma=1000)  # 设置SVC模型参数;C是误差惩罚系数,代替之前使用lamda的方式,用来调节模型方差与偏差的问题; kernel的rbf是我们要用的高斯核
# 函数的意思,先设置gamma=1,之后会调整采用不同的gamma值来查看不同的gamma对模型的影响
svc1.fit(X, y.flatten())  # 使用SVC对X,y进行拟合预测操作
print(svc1.score(X, y.flatten()))  # 显示预测准确率,当前预测的准确率为0.8088064889918888
# ---------------------------# ---------------------------
# 绘制决策边界
def plot_boundary(model):x_min, x_max = 0, 1.0  # 根据散点图看出数据点的x范围y_min, y_max = 0.4, 1.0  # 根据散点图看出数据点的y范围xx, yy = np.meshgrid(np.linspace(x_min, x_max, 500), np.linspace(y_min, y_max, 500))  # np.meshgrid是画格子,这里xx和yy# 的shape为(500,500),意思就是画个均匀的500*500的格子z = model.predict(np.c_[xx.flatten(), yy.flatten()])  # 将xx,和yy都从500*500降成一维,再用np.c_[]合并成shape为(250000,2)zz = z.reshape(xx.shape)  # (500,500)plt.contour(xx, yy, zz)   # 绘制等高线 # 这个等高线暂时不是很理解,这个画法摘自网络plot_boundary(svc1)  # 调用边界函数画出决策边界
plot_data()    # 调用plot_data() 画出数据的散点图
plt.show()    # 上面两行只是调用,还没有画出来,有了这行之后是把上面两行画出的决策边界和散点图都显示到同一张图上来

4.寻找最优参数C和gamma

通过前面两个小练习我们已经知道了误差惩罚系数C和高斯核的参数gamma都会对模型精度产生影响,下面我们就来寻找一下最优参数C和gamma的组合方式。

首先导入库

import numpy as np
import scipy.io as sio
import matplotlib.pyplot as plt
from sklearn.svm import SVC  # 导入sklearn.svm的库

导入数据集,打印表头看看

data = sio.loadmat('ex6data3.mat')
print('data.keys():', data.keys())

输出表头;可以看出这次X,y除了训练集还有验证集;我们将在训练集上进行模型训练,然后到验证集上对模型进行验证

data.keys(): dict_keys(['__header__', '__version__', '__globals__', 'X', 'y', 'yval', 'Xval'])

获取X,y,Xval, yval;并打印X, y的shape来看看

X, y = data['X'], data['y']
Xval, yval = data['Xval'], data['yval']
print('X.shape, y.shape:', X.shape, y.shape)

输出X,y的shape

X.shape, y.shape: (211, 2) (211, 1)

画出数据的散点图来看看分布状况

def plot_data():plt.scatter(X[:, 0], X[:, 1], c=y.flatten(), cmap='jet')  # cmap相当于是配色盘的意思,这次选择了jet这一套颜色。y.flatten()# 是将y拉伸成一列, 这样每一个X对应一个y,而y只有0,1两种,c是给数据点颜色,把0和1的数据点给出不同的颜色plt.xlabel('x1')plt.ylabel('y1')plt.show()plot_data()  # 调用函数,画出数据的散点图来看看分布状况

输出散点图:

寻找准确率最高时候的最优参数C和gamma

Cvalues = [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100]  # 设置9个误差惩罚系数的候选值C
gammas = [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100]  # 设置9个高斯核的参数候选值gammabest_score = 0  # 设置初始得分(即预测准确率)
best_params = (0, 0)  # 设置初始参数for c in Cvalues:  # 遍历Cvalues中的候选值for gamma in gammas:  # 遍历gammas中的候选值svc = SVC(C=c, kernel='rbf', gamma=gamma)   # 将候选值一个一个代入SVC中svc.fit(X, y.flatten())score = svc.score(Xval, yval.flatten())   # 将svc后的结果代入验证集中,对Xval,yval进行验证,显示预测准确率,if score > best_score:  # 如果当前的分数score大于之前的历史最好分数best_scorebest_score = score  # 就将当前的分数score赋值成历史最好分数best_scorebest_params = (c, gamma)  # 并且把当前的参数c和gamma赋值成历史最好参数best_params
print('best_score, best_params:', best_score, best_params)

输出最优准确率为0.965,最优参数C和gamma分别为0.3和100

best_score, best_params: 0.965 (0.3, 100)

将最优参数代回去,得到最后的最优分类图像

svc2 = SVC(C=best_params[0], kernel='rbf', gamma=best_params[1])  # 其实C和gamma分别就是0.3和100
svc2.fit(X, y.flatten())

绘制决策边界

def plot_boundary(model):x_min, x_max = -0.6, 0.4  # 根据散点图看出数据点的x范围y_min, y_max = -0.7, 0.7 # 根据散点图看出数据点的y范围xx, yy = np.meshgrid(np.linspace(x_min, x_max, 500), np.linspace(y_min, y_max, 500))  # np.meshgrid是画格子,这里xx和yy# 的shape为(500,500),意思就是画个均匀的500*500的格子z = model.predict(np.c_[xx.flatten(), yy.flatten()])  # 将xx,和yy都从500*500降成一维,再用np.c_[]合并成shape为(250000,2)zz = z.reshape(xx.shape)  # (500,500)plt.contour(xx, yy, zz)   # 绘制等高线 # 这个等高线暂时不是很理解,这个画法摘自网络plot_boundary(svc2)  # 调用边界函数画出决策边界
plot_data()    # 调用plot_data() 画出数据的散点图
plt.show()    # 上面两行只是调用,还没有画出来,有了这行之后是把上面两行画出的决策边界和散点图都显示到同一张图上来

最高的预测率best_score确实是0.965,但是能达到这个预测率的best_params其实不止有(0.3, 100)这一组,只是按照我们设置的遍历和赋值的特点,他们恰好是最靠后的一组。

完整代码:

# -*- coding: utf-8 -*-
"""
Created on Sat June 23 18:01:23 2022
@author: wzj
python version: python 3.9Title: 支持向量机(Support Vector Machines)——寻找最优参数C和gamma案例:使用支持向量机(svm)构建一个垃圾邮件分类器。数据集:数据文件是ex6data3.mat
"""import numpy as np
import scipy.io as sio
import matplotlib.pyplot as plt
from sklearn.svm import SVC  # 导入sklearn.svm的库data = sio.loadmat('ex6data3.mat')
print('data.keys():', data.keys())X, y = data['X'], data['y']
Xval, yval = data['Xval'], data['yval']
print('X.shape, y.shape:', X.shape, y.shape)# ---------------------------
# 画出数据的散点图来看看分布状况
def plot_data():plt.scatter(X[:, 0], X[:, 1], c=y.flatten(), cmap='jet')  # cmap相当于是配色盘的意思,这次选择了jet这一套颜色。y.flatten()# 是将y拉伸成一列, 这样每一个X对应一个y,而y只有0,1两种,c是给数据点颜色,把0和1的数据点给出不同的颜色plt.xlabel('x1')plt.ylabel('y1')plt.show()# plot_data()  # 调用函数,画出数据的散点图来看看分布状况
# ---------------------------# ---------------------------
# 寻找准确率最高时候的最优参数C和gamma
Cvalues = [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100]  # 设置9个误差惩罚系数的候选值C
gammas = [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100]  # 设置9个高斯核的参数候选值gammabest_score = 0  # 设置初始得分(即预测准确率)
best_params = (0, 0)  # 设置初始参数for c in Cvalues:  # 遍历Cvalues中的候选值for gamma in gammas:  # 遍历gammas中的候选值svc = SVC(C=c, kernel='rbf', gamma=gamma)   # 将候选值一个一个代入SVC中svc.fit(X, y.flatten())score = svc.score(Xval, yval.flatten())   # 将svc后的结果代入验证集中,对Xval,yval进行验证,显示预测准确率,if score > best_score:  # 如果当前的分数score大于之前的历史最好分数best_scorebest_score = score  # 就将当前的分数score赋值成历史最好分数best_scorebest_params = (c, gamma)  # 并且把当前的参数c和gamma赋值成历史最好参数best_params
print('best_score, best_params:', best_score, best_params)
# ---------------------------# ---------------------------
# 将最优参数代回去,得到最后的最优分类图像
svc2 = SVC(C=best_params[0], kernel='rbf', gamma=best_params[1])  # 其实C和gamma分别就是0.3和100
svc2.fit(X, y.flatten())# 绘制决策边界
def plot_boundary(model):x_min, x_max = -0.6, 0.4  # 根据散点图看出数据点的x范围y_min, y_max = -0.7, 0.7 # 根据散点图看出数据点的y范围xx, yy = np.meshgrid(np.linspace(x_min, x_max, 500), np.linspace(y_min, y_max, 500))  # np.meshgrid是画格子,这里xx和yy# 的shape为(500,500),意思就是画个均匀的500*500的格子z = model.predict(np.c_[xx.flatten(), yy.flatten()])  # 将xx,和yy都从500*500降成一维,再用np.c_[]合并成shape为(250000,2)zz = z.reshape(xx.shape)  # (500,500)plt.contour(xx, yy, zz)   # 绘制等高线 # 这个等高线暂时不是很理解,这个画法摘自网络plot_boundary(svc2)  # 调用边界函数画出决策边界
plot_data()    # 调用plot_data() 画出数据的散点图
plt.show()    # 上面两行只是调用,还没有画出来,有了这行之后是把上面两行画出的决策边界和散点图都显示到同一张图上来

5.通过SVM判断一封邮件是否是垃圾邮件

首先导入库

import numpy as np
import scipy.io as sio
import matplotlib.pyplot as plt
from sklearn.svm import SVC  # 导入sklearn.svm的库

导入训练集数据和测试集数据,打印表头看看

# Training data
data1 = sio.loadmat('spamTrain.mat')
print('data1.keys():', data1.keys())# Testing data
data2 = sio.loadmat('spamTest.mat')
print('data2.keys():', data2.keys())

输出表头;可以看出这次X,y除了训练集还有验证集;我们将在训练集上进行模型训练,然后到验证集上对模型进行验证

data1.keys(): dict_keys(['__header__', '__version__', '__globals__', 'X', 'y'])
data2.keys(): dict_keys(['__header__', '__version__', '__globals__', 'Xtest', 'ytest'])

获取X,y,Xtest, ytest ;并打印X, y的shape以及X,y来看看

X, y = data1['X'], data1['y']
Xtest, ytest = data2['Xtest'], data2['ytest']
print('X.shape, y.shape:', X.shape, y.shape)
print('X:', X)
print('y:', y)

输出X,y的shape
X由1899种特征来表示,这些特征由0和1组成,0表示语义库不能找到该单词,1表示语义库可以找到该单
y只有0和1两种形式,1表示当前邮件为垃圾邮件,0表示不是垃圾邮件

X.shape, y.shape: (4000, 1899) (4000, 1)
X: [[0 0 0 ... 0 0 0][0 0 0 ... 0 0 0][0 0 0 ... 0 0 0]...[0 0 0 ... 0 0 0][0 0 1 ... 0 0 0][0 0 0 ... 0 0 0]]
y: [[1][1][0]...[1][0][0]]

调用SVC进行邮件分类, 打印出最好的分数结果best_score与其对应的参数best_param

Cvalues = [3, 10, 30, 100, 0.01, 0.03, 0.1, 0.3, 1]  # 设置9个误差惩罚系数的候选值C
best_score = 0  # 设置初始得分(即预测准确率)
best_param = 0  # 设置初始参数for c in Cvalues:  # 遍历Cvalues中的候选值svc = SVC(C=c, kernel='linear')   # 将候选值一个一个代入SVC中,kernel采用线性分类linearsvc.fit(X, y.flatten())score = svc.score(Xtest, ytest.flatten())   # 将svc后的结果代入验证集中,对Xval,yval进行验证,显示预测准确率,if score > best_score:  # 如果当前的分数score大于之前的历史最好分数best_scorebest_score = score  # 就将当前的分数score赋值成历史最好分数best_scorebest_param = c  # 并且把当前的参数c和gamma赋值成历史最好参数best_paramsprint('best_score, best_param:', best_score, best_param)

输出最好的分数结果best_score与其对应的参数best_param:

best_score, best_param: 0.99 0.03

将最优的参数best_param分别带入训练集和测试集,得到在各自数据下的最好分数(预测准确率)

svc = SVC(C= best_param, kernel='linear')
svc.fit(X, y.flatten())
score_train = svc.score(X, y.flatten())
score_test = svc.score(Xtest, ytest.flatten())
print('score_train, score_test:', best_score, best_param)

分别输出代入最优参数best_param=0.03时,在测试集和验证集上得到的最优的分数结果,
在训练集上的预测准确率为0.99,在验证集上的预测准确率也为0.99。

best_score, best_param: 0.99 0.03
score_train, score_test: 0.99 0.03

参考文献:
[1] https://www.bilibili.com/video/BV1xJ411U7g9?p=5&spm_id_from=pageDriver&vd_source=72e4369cf6b54497a1e04f2071a47a1e

吴恩达机器学习课后作业6——使用支持向量机(svm)构建一个垃圾邮件分类器相关推荐

  1. 目录:吴恩达机器学习课后作业

    简单介绍 本博客为作者自行完成的吴恩达机器学习课后练习题目录,均使用PyTorch进行实现,无法保证对错,仅供参考. 作业题目以及源代码 百度云盘连接 提取码:3dvb 题目的命名方式与下表中的作业名 ...

  2. 吴恩达机器学习课后作业——SVM支持向量机

    支持向量机 一.作业内容 在本练习的前半部分,您将对各种示例2D数据集使用支持向量机(svm).使用这些数据集进行试验将帮助您直观地了解支持向量机的工作方式,以及如何在支持向量机中使用高斯核.在练习的 ...

  3. 吴恩达机器学习课后作业——偏差和方差

    1.写在前面 吴恩达机器学习的课后作业及数据可以在coursera平台上进行下载,只要注册一下就可以添加课程了.所以这里就不写题目和数据了,有需要的小伙伴自行去下载就可以了. 作业及数据下载网址:吴恩 ...

  4. 吴恩达机器学习课后作业——线性回归(Python实现)

    1.写在前面 吴恩达机器学习的课后作业及数据可以在coursera平台上进行下载,只要注册一下就可以添加课程了.所以这里就不写题目和数据了,有需要的小伙伴自行去下载就可以了. 作业及数据下载网址:吴恩 ...

  5. 吴恩达机器学习课后作业ex1(python实现)

    作业介绍 吴恩达老师的作业资源可以在github或者网上找到 . ex1主要是对线性回归的一些复习和梯度下降.损失函数等的具体代码实现. pdf文件是对作业的说明.文件夹则是作业数据的各种格式,pyt ...

  6. 吴恩达机器学习课后作业1——单变量线性回归(Linear regression with one variable)

    1. 问题和数据 假设你是一家连锁餐车店的老板,但是你又和别的土老板不一样,你又刚好是个懂线性回归,还懂编程的老板,正在考虑在不同的城市开一家新店.该连锁店已经在各个城市开设了餐车,你可以获得这些城市 ...

  7. 吴恩达机器学习课后作业1.1——多变量线性回归(Linear regression with multiple variable)

    1. 问题和数据 假设你要卖掉你的房子,你想知道一个好的市场价格是多少.其中一种方法是,首先收集最近出售的房屋的信息.在本部分的练习中,你将使用多元线性回归来预测房屋价格. 数据ex1data2.tx ...

  8. 吴恩达机器学习课后作业——线性回归

    一.单变量线性回归 一.作业内容 假设你是一家特许经营餐厅的首席执行官,正在考虑在不同的城市开一家新店,该连锁店已经在各个城市开设了餐车,文件ex1data1.txt中包含你这些城市的利润和人口数据. ...

  9. 吴恩达机器学习课后作业ex3(python实现)

    ex3是机器学习中经典的手写数字识别(使用逻辑回归分类),给出的数据是.mat后缀,可以用python中load方法加载数据.手写体"1"到"9"的类别分别标为 ...

  10. 吴恩达机器学习课后作业深度解析(附答案)(ex2)

    作业ex2题目及答案源码下载地址ex2题目及答案 一.逻辑回归 问题背景,根据学生两门课的成绩和是否入学的数据,预测学生能否顺利入学 plotData.m:数据可视化 % Find Indices o ...

最新文章

  1. 【c语言】计算三角形面面积
  2. lucene反向索引——倒排表无论是文档号及词频,还是位置信息,都是以跳跃表的结构存在的...
  3. java c3p0 配置文件_【c3p0】 C3P0的三种配置方式以及基本配置项详解
  4. POJ3013 Big Christmas Tree(最短路径树)
  5. SQL- AND OR Order by INSERT INTO
  6. Python yaml处理
  7. accept 返回0_从0开始理解Vite的主要新特性(一)
  8. SWIFT调用C语言
  9. linux 目录提权,【安全科普】Linux提权——利用可执行文件SUID
  10. 如何在MyEclipse上耍Chrome
  11. 4.Linux性能诊断 --- Linux工作流程内存管理
  12. 181104每日一句
  13. SVM多分类的几种方式
  14. 风景怡人一个生态村子 -国稻种芯-百色:华润谋定希望小镇
  15. 躺着赚钱|闲鱼自动发货脚本|自动化|Auto.js
  16. java 针对专业技能可能会被问到的面试题
  17. JSP及MVC三层架构
  18. 组网胖模式_胖AP和瘦AP的区别、组网优缺点分析
  19. K210识别数字(0~9)并与单片机通信通过数字来控制小车移动
  20. NRF52832与NRF52840的性能区别

热门文章

  1. 【单片机基础】(四)单片机的引脚功能
  2. 短信机bug,发短信发的直吐血…………
  3. Android陀螺仪传感器
  4. JavaScript查找最长的公共前缀
  5. 显著性水平 P值 概念解释
  6. oracle全量增量_数据同步:全量与增量
  7. Cesium为3dTile模型添加气泡框
  8. [国家集训队]Tree I
  9. 港科夜闻丨香港科大团队最新研究:双色发射AIEgen用于无标记特异性识别dsDNA和SNPs检测...
  10. 《深入理解计算机系统(CSAPP)》—— 实验一 数据表示与运算实验