一. 支持向量机介绍
支持向量机
介绍
SVM全称是Supported Vector Machine(支持向量机)
即寻找到一个超平面使样本分成两类,并且间隔最大。
是一种监督学习算法,主要用于分类,也可用于回归
与逻辑回归和决策树等其他分类器相比,SVM 提供了非常高的准确度
优缺点
优点:
适合小样本、高纬度数据,比较强泛化能力
可有效地处理高维数据;可使用不同的核函数来适应不同的数据类型
缺点:
计算复杂度较高,对于大规模数据的处理可能会存在困难
超平面最大间隔
名词解释
硬间隔
如果样本线性可分,在所有样本分类都正确的情况下,寻找最大间隔,这就是硬间隔
如果出现异常值、或者样本不能线性可分,此时硬间隔无法实现。
软间隔
允许部分样本,在最大间隔之内,甚至在错误的一边
,寻找最大间隔,这就是软间隔
目标是尽可能在保持间隔宽阔和限制间隔违例之间找到良好的平衡。
通过惩罚系数C来控制这个平衡:C值越小,则间隔越宽,但是间隔违例也会越多
。
核函数
核函数将原始输入空间映射到新的特征空间,使得原本线性不可分的样本在核空间可分
总结
1、下列关于SVM的描述错误的是?(单选题)
A)它的全称为支撑向量机(SupportedVector Machine)
B)它的主要任务是找到一个超平面将不同的样本划分开来
C)硬间隔和软间隔都是SVM分割超平面中的一种
D)SVM模型可以通过调小C参数的取值,来减少间隔违例
答案解析: C值越小,间隔违例越多
答案:D
二. 支持向量机API的使用
API
初步代码演示
plot_util工具
import numpy as np import matplotlib.pyplot as plt 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_map = ListedColormap(["#EF9A9A", "#FFF59D", "#90CAF9"]) # plt.contourf(x0,x1,zz,linewidth=5,cmap=custom_map) plt.contourf(x0, x1, zz, cmap=custom_map) def plot_decision_boundary_svc(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_map = ListedColormap(["#EF9A9A", "#FFF59D", "#90CAF9"]) # plt.contourf(x0,x1,zz,linewidth=5,cmap=custom_map) plt.contourf(x0, x1, zz, cmap=custom_map) w = model.coef_[0] b = model.intercept_[0] # w0* x0 + w1* x1+ b = 0 # =>x1 = -w0/w1 * x0 - b/w1 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_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")
代码
import matplotlib.pyplot as plt from plot_util import plot_decision_boundary from sklearn.svm import LinearSVC from sklearn.datasets import load_iris from sklearn.preprocessing import StandardScaler def demo01_svm(): # 获取数据 data, label = load_iris(return_X_y=True) # print(data.shape) # print(label.shape) # print(pd.DataFrame( # data, # columns=[ # '花萼长度', # '花萼宽度', # '花瓣长度', # '花瓣宽度'] # ).head()) # 数据基本处理 # 特征和标签 data_sub = data[label < 2, :2] label_sub = label[label < 2] print(data_sub.shape) print(label_sub.shape) # 数据可视化 # plt.figure(figsize=(10, 5), dpi=100) # plt.scatter(data_sub[label_sub == 0, 0], data_sub[label_sub == 0, 1], c='r') # plt.scatter(data_sub[label_sub == 1, 0], data_sub[label_sub == 1, 1], c='c') # plt.show() # 特征工程 transfer = StandardScaler() data_sub = transfer.fit_transform(data_sub) # 模型训练 model = LinearSVC(C=100) model.fit(data_sub, label_sub) y_pred = model.predict(data_sub) print(y_pred) # 绘制模型的边界 plot_decision_boundary(model, axis=[-3, 3, -3, 3]) plt.scatter(data_sub[label_sub == 0, 0], data_sub[label_sub == 0, 1], c='r') plt.scatter(data_sub[label_sub == 1, 0], data_sub[label_sub == 1, 1], c='b') plt.show() if __name__ == '__main__': demo01_svm()
结果图
惩罚参数的影响
代码
import matplotlib.pyplot as plt from plot_util import plot_decision_boundary from sklearn.svm import LinearSVC from sklearn.datasets import load_iris from sklearn.preprocessing import StandardScaler def demo01_svm(): # 获取数据 data, label = load_iris(return_X_y=True) # print(data.shape) # print(label.shape) # 数据基本处理 # 特征和标签 data_sub = data[label < 2, :2] label_sub = label[label < 2] print(data_sub.shape) print(label_sub.shape) # 数据可视化 # plt.figure(figsize=(10, 5), dpi=100) # plt.scatter(data_sub[label_sub == 0, 0], data_sub[label_sub == 0, 1], c='r') # plt.scatter(data_sub[label_sub == 1, 0], data_sub[label_sub == 1, 1], c='c') # plt.show() # 特征工程 transfer = StandardScaler() data_sub = transfer.fit_transform(data_sub) # C=100 # 模型训练 model1 = LinearSVC(C=100, dual='auto') model1.fit(data_sub, label_sub) y_pred = model1.predict(data_sub) print(y_pred) # 绘制模型的边界 plot_decision_boundary(model1, axis=[-3, 3, -3, 3]) plt.scatter(data_sub[label_sub == 0, 0], data_sub[label_sub == 0, 1], c='r') plt.scatter(data_sub[label_sub == 1, 0], data_sub[label_sub == 1, 1], c='b') plt.show() # C=0.1 # 模型训练 model2 = LinearSVC(C=0.1, dual='auto') model2.fit(data_sub, label_sub) y_pred = model2.predict(data_sub) print(y_pred) # 绘制模型的边界 plot_decision_boundary(model2, axis=[-3, 3, -3, 3]) plt.scatter(data_sub[label_sub == 0, 0], data_sub[label_sub == 0, 1], c='r') plt.scatter(data_sub[label_sub == 1, 0], data_sub[label_sub == 1, 1], c='b') plt.show() if __name__ == '__main__': demo01_svm()
结果图
三. SVM算法原理
SVM思想:要去求一组参数(w,b),使其构建的超平面函数能够最优地分离两个集合。
求解w和b最小
求解最终超平面
四. 核函数
核函数的作用
将原始输入空间映射到的新的特征空间, 从而, 使原本的线性不可分的样本, 可能在核空间可分
核函数分类
线性核:一般是不增加数据维度,而是预先计算内积,提高速度
多项式核:一般是通过增加多项式特征,提升数据维度,并计算内积
高斯核(RBF、径向基函数):产生将样本投射到无限维空间的运算效果,使得原来不可分的数据变得可分。使用最多其他了解即可
高斯核函数基本原理
高斯核函数API
gama值越大越容易过拟合, gama值与拟合成正比
模型API
解释gama函数
代码演示
# 1.导入依赖包 from sklearn.datasets import make_moons import matplotlib.pyplot as plt from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.svm import SVC from plot_util import plot_decision_boundary # 2.获取数据 x, y = make_moons(noise=0.15) plt.scatter(x[y == 0, 0], x[y == 0, 1]) plt.scatter(x[y == 1, 0], x[y == 1, 1]) plt.show() # 3.构建函数 def RBFsvm(gamma=0.1): return Pipeline( [ ('std_scalar', StandardScaler()), ('svc', SVC(kernel='rbf', gamma=gamma)) ] ) ## 4.实验测试【0.5,1.0,100,0.1】,模型训练 # svc1 = RBFsvm(0.5) # x_std=svc1['std_scalar'].fit_transform(x) # svc1.fit(x_std,y) # plot_decision_boundary(svc1,axis=[-3,3,-3,3]) # plt.scatter(x_std[y==0,0],x_std[y==0,1]) # plt.scatter(x_std[y==1,0],x_std[y==1,1]) # plt.show() svc1 = RBFsvm(1.0) svc1.fit(x, y) plot_decision_boundary(svc1, axis=[-1.5, 2.5, -1, 1.5]) plt.scatter(x[y == 0, 0], x[y == 0, 1]) plt.scatter(x[y == 1, 0], x[y == 1, 1]) plt.title("gamma=1.0") plt.show() svc2 = RBFsvm(100) svc2.fit(x, y) plot_decision_boundary(svc2, axis=[-1.5, 2.5, -1, 1.5]) plt.scatter(x[y == 0, 0], x[y == 0, 1]) plt.scatter(x[y == 1, 0], x[y == 1, 1]) plt.title("gamma=100") plt.show() svc3 = RBFsvm(0.1) svc3.fit(x, y) plot_decision_boundary(svc3, axis=[-1.5, 2.5, -1, 1.5]) plt.scatter(x[y == 0, 0], x[y == 0, 1]) plt.scatter(x[y == 1, 0], x[y == 1, 1]) plt.title("gamma=0.1") plt.show()