支持向量机 SVM
支持向量机介绍
-
SVM全称是Supported Vector Machine(支持向量机)
- 即寻找到一个超平面使样本分成两类,并且间隔最大。
- 是一种监督学习算法,主要用于分类,也可用于回归
- 与逻辑回归和决策树等其他分类器相比,SVM 提供了非常高的准确度
-
优点:
- 适合小样本 高纬度数据 比较强泛化能力
- 可有效的处理高纬度数据;可使用不同和核函数来适应不同的数据类型
-
缺点:
- 计算复杂度高,对于大规模数据处理肯会存在困难
-
超平面最大间隔
- 硬间隔 Hard Margin
- 如果样本线性可分,在所有样本分类都正确的情况下,寻找最大间隔,这就是硬间隔
- 如果出现异常值或样本不能线性可分,此时硬间隔无法实现
-
软间隔 Soft Margin 和惩罚系数
- 允许部分样本,在最大间隔之内,甚至在错误的一边,寻找最大间隔,这就是软间隔
- 目标是尽可能在保持间隔宽度和限制间违例之间找到良好的平衡
- 通过惩罚系数C来控制职工平衡:C值越小,则间隔越宽,短时间隔违例也会越多
-
核函数 Kernel
- 核函数将原始输入空间映射到新的特征空间,使得原本线性不可分的样本在核空间可分
支持向量机API的使用
sklearn.svm.LinearSVC(C = 1.0)
- C: 惩罚系数, 类似于线性回归的正则化系数
- LinearSVC API 的使用方式:
from sklearn.svm import LinearSVC
mysvc = LinearSVC(C = 30)
mysvc.fit(X_standard,y)
print(mysvc.score(X_standard, y))
代码实现
import numpy as np # numpy
import matplotlib.pyplot as plt # 数据可视化
from sklearn import datasets # 数据集
from sklearn.datasets import load_iris
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler # 数据预处理
from sklearn.svm import LinearSVC # 线性SVM
from plot_util import plot_decision_boundary
def demo01():
'''
鸢尾花分类
:return:
'''
# 2.加载数据及数据预处理
# 2.1 加载数据
X, y = load_iris(return_X_y=True)
print(y.shape)
print(X.shape)
# 2.2 数据降维
x = X[y < 2, :2]
y = y[y < 2]
print(y.shape)
plt.scatter(x[y == 0, 0], x[y == 0, 1], c='red')
plt.scatter(x[y == 1, 0], x[y == 1, 1], c='blue')
plt.show()
# 2.3 数据预处理,标准化
transform = StandardScaler()
x_tran = transform.fit_transform(x)
# 3.模型训练
model = LinearSVC(C=10, dual='auto')
model.fit(x_tran, y)
# 4.模型预测
y_pred = model.predict(x_tran)
# 5.模型评估
# 5.1 准确率
print(accuracy_score(y_pred, y))
# 5.2 可视化
plot_decision_boundary(model, axis=[-3, 3, -3, 3])
plt.scatter(x_tran[y == 0, 0], x_tran[y == 0, 1], c='red')
plt.scatter(x_tran[y == 1, 0], x_tran[y == 1, 1], c='blue')
plt.show()
if __name__ == '__main__':
demo01()
运行结果
惩罚参数C对超平面影响代码实现
"""
## C值测试
# 1.导入依赖包
# 2.加载数据及数据预处理
# 2.1 加载数据
# 2.2 数据降维
# 2.3 数据预处理,标准化
# 3.模型训练
# 4.模型预测
# 5.模型评估
# 5.1 准确率
# 5.2 可视化
"""
# 1.导入依赖包
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
from sklearn.metrics import accuracy_score
from plot_util import plot_decision_boundary, plot_decision_boundary_svc
# 2.加载数据及数据预处理
# 2.1加载数据
X, y = load_iris(return_X_y=True)
# print(y.shape)
# print(X.shape)
# 2.2 数据降维
x = X[y < 2, :2]
y = y[y < 2]
# print(y.shape)
plt.scatter(x[y == 0, 0], x[y == 0, 1], c='red')
plt.scatter(x[y == 1, 0], x[y == 1, 1], c='blue')
plt.show()
# 2.3 数据的预处理,标准化
transform = StandardScaler()
x_tran = transform.fit_transform(x)
# --------------------测试一:C=30--------------------------------------------------- #
# 3.模型训练
model = LinearSVC(C=30, dual='auto')
model.fit(x_tran, y)
# 4.模型预测
y_pred = model.predict(x_tran)
# 5.模型评估
# 5.1 准确率
print(accuracy_score(y_pred, y))
# 5.2 可视化
plot_decision_boundary_svc(model, axis=[-3, 3, -3, 3])
plt.scatter(x_tran[y == 0, 0], x_tran[y == 0, 1], c='red')
plt.scatter(x_tran[y == 1, 0], x_tran[y == 1, 1], c='blue')
plt.show()
# --------------------测试二:C=0.01--------------------------------------------------- #
# 3.模型训练
model = LinearSVC(C=0.01, dual='auto')
model.fit(x_tran, y)
# 4.模型预测
y_pred = model.predict(x_tran)
# 5.模型评估
# 5.1 准确率
print(accuracy_score(y_pred, y))
# 5.2 可视化
plot_decision_boundary_svc(model, axis=[-3, 3, -3, 3])
plt.scatter(x_tran[y == 0, 0], x_tran[y == 0, 1], c='red')
plt.scatter(x_tran[y == 1, 0], x_tran[y == 1, 1], c='blue')
plt.show()
运行结果:
可以看见当惩罚参数不合适时,超参平面包含了较多错误
SVM的算法原理
支持向量机推导过程
SVM 核函数
核函数将原始输入空间映射到新的特征空间,从而,使原本线性不可分的样本可能在核空间可分。
核函数分类
- 线性核:一般是不增加数据维度,而是预先计算内积,提高速度
- 多项式核:一般是通过增加多项式特征,提升数据维度,并计算内积
- 高斯核(RBF、径向基函数):产生将样本投射到无限维空间的运算效果,使得原来不可分的数据变得可分。使用最多
- 其他了解即可
高斯核
高斯核 Radial Basis Function Kernel (径向基函数,又称RBF核)
结论:gamma越大,高斯分布越窄,gamma越小,高斯分布越宽
- 举例
高斯核API
from sklearn.svm import SVC
SVC(lernel='rbf',gamma=gamma)
高斯核对模型的影响:
gamma参数
代码实现
"""
## RBF参数测试
# 1.导入依赖包
# 2.获取数据
# 3.构建函数
# 4.实验测试【0.5,1.0,100,0.1】,模型训练
"""
# 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.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.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.show()
运行结果