文章目录
- 一、准备工作
- 二、支持向量机SVM(Support Vector Machine)
- 三、对鸢尾花Iris数据集进行SVM线性分类练习
- 四、参考🔗
一、准备工作
实验环境
Anaconda + python3.6 + jupyter
实验所需的python包有:numpy、sklearn、matplotlib,用 pip install即可安装
二、支持向量机SVM(Support Vector Machine)
支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大使它有别于感知机;SVM还包括核技巧,这使它成为实质上的非线性分类器。SVM的的学习策略就是间隔最大化,可形式化为一个求解凸二次规划的问题,也等价于正则化的合页损失函数的最小化问题。SVM的的学习算法就是求解凸二次规划的最优化算法。
更多详细说明和数学推导,请参考:【ML】支持向量机(SVM)从入门到放弃再到掌握
三、对鸢尾花Iris数据集进行SVM线性分类练习
LinearSVC(Linear Support Vector Classification)线性支持向量机,核函数是 linear,不是基于libsvm实现的
参数:
- C:目标函数的惩罚系数C,默认C = 1.0;
- loss:指定损失函数. squared_hinge(默认), squared_hinge
- penalty : 惩罚方式,str类型,l1, l2
- dual :选择算法来解决对偶或原始优化问题。当nsamples>nfeatures时dual=false
- tol :svm结束标准的精度, 默认是 1e - 3
- multi_class:如果y输出类别包含多类,用来确定多类策略, ovr表示一对多,“crammer_singer”优化所有类别的一个共同的目标 。如果选择“crammer_singer”,损失、惩罚和优化将会被被忽略。
- max_iter : 要运行的最大迭代次数。int,默认1000
导入所需包
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
获取数据
iris = datasets.load_iris()
x = iris.data
y = iris.target
对数据进行处理,并绘制散点图
x = x[y<2,:2] #只取y<2的类别,也就是0 1 并且只取前两个特征
y = y[y<2] # 只取y<2的类别
# 分别画出类别0和1的点
plt.scatter(x[y==0,0],x[y==0,1],color='red')
plt.scatter(x[y==1,0],x[y==1,1],color='blue')
plt.show()
数据归一化处理,C=1e9
standardScaler = StandardScaler()
standardScaler.fit(x) # 计算训练数据的均值和方差
X_standard = standardScaler.transform(x) # 再用scaler中的均值和方差来转换X,使X标准化
svc = LinearSVC(C=1e9) # 线性SVM分类器
svc.fit(X_standard, y)
画出决策边界
相关函数的说明:
- meshgrid() 返回了有两个向量定义的方形空间中的所有点的集合。x0是x值,x1是y的值
- ravel() 将向量拉成一行
- c_[] 将向量排列在一起
- contourf() 等高线
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),# 600个,影响列数
np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1, 1),# 600个,影响行数
)
# x0 和 x1 被拉成一列,然后拼接成360000行2列的矩阵,表示所有点
X_new = np.c_[x0.ravel(), x1.ravel()] # 变成 600 * 600行, 2列的矩阵
y_predict = model.predict(X_new) # 二维点集才可以用来预测
zz = y_predict.reshape(x0.shape) # (600, 600)
from matplotlib.colors import ListedColormap
custom_cmap = ListedColormap(['#EF9A9A','#FFF59D','#90CAF9'])
plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)
#print(X_new)
plot_decision_boundary(svc, axis=[-3, 3, -3, 3])
plt.scatter(X_standard[y==0,0], X_standard[y==0,1],color='red')
plt.scatter(X_standard[y==1,0], X_standard[y==1,1],color='blue')
plt.show()
添加上下边界
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),# 600个,影响列数
np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1, 1),# 600个,影响行数
)
# x0 和 x1 被拉成一列,然后拼接成360000行2列的矩阵,表示所有点
X_new = np.c_[x0.ravel(), x1.ravel()] # 变成 600 * 600行, 2列的矩阵
y_predict = model.predict(X_new) # 二维点集才可以用来预测
zz = y_predict.reshape(x0.shape) # (600, 600)
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]
index_x = np.linspace(axis[0], axis[1], 100)
# f(x,y) = w[0]x1 + w[1]x2 + b
# 1 = w[0]x1 + w[1]x2 + b 上边界
# -1 = w[0]x1 + w[1]x2 + b 下边界
y_up = (1-w[0]*index_x - b) / w[1]
y_down = (-1-w[0]*index_x - b) / w[1]
x_index_up = index_x[(y_up<=axis[3]) & (y_up>=axis[2])]
x_index_down = index_x[(y_down<=axis[3]) & (y_down>=axis[2])]
y_up = y_up[(y_up<=axis[3]) & (y_up>=axis[2])]
y_down = y_down[(y_down<=axis[3]) & (y_down>=axis[2])]
plt.plot(x_index_up, y_up, color="black")
plt.plot(x_index_down, y_down, 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='red')
plt.scatter(X_standard[y==1,0], X_standard[y==1,1],color='blue')
plt.show()
修改常数C,C=0.01
svc = LinearSVC(C=0.01)
svc.fit(X_standard, y)
plot_svc_decision_boundary(svc, axis=[-3, 3, -3, 3])
plt.scatter(X_standard[y==0,0], X_standard[y==0,1],color='red')
plt.scatter(X_standard[y==1,0], X_standard[y==1,1],color='blue')
plt.show()
常数C越大,容错空间越小,上下边界越远;常数C越小,容错空间越大,上下边界越远。
四、参考🔗
- sklearn中的SVM
- SVM线性分类——鸢尾花Iris数据集