一、支持向量机(support vector machines. ,SVM)概念
1. SVM 绪论
支持向量机(SVM)的核心思想是找到一个最优的超平面,将不同类别的数据点分开。SVM 的关键特点包括:
① 分类与回归:
-
SVM 可以用于分类(SVC, Support Vector Classification)和回归(SVR, Support Vector Regression)。
-
分类任务中,SVM 通过找到一个超平面,最大化不同类别之间的间隔(margin)。
-
回归任务中,SVM 通过找到一个超平面,使得数据点尽可能接近该超平面。
② 核函数(Kernel):
-
SVM 通过核函数将数据映射到高维空间,从而解决非线性问题。
-
常用的核函数包括:
线性核(linear
)
多项式核(poly
)
径向基核(RBF, rbf
)
Sigmoid 核(sigmoid
)
③ 支持向量:
-
支持向量是离超平面最近的数据点,它们决定了超平面的位置和方向。
2. scikit-learn
中的SVM包
① SVC
:
-
用于分类任务的支持向量机。
-
主要参数:
kernel
:核函数类型(如 'linear'
、'rbf'
等)。
C
:正则化参数,控制模型的复杂度。
gamma
:核函数的系数(仅对 'rbf'
、'poly'
和 'sigmoid'
核有效)。
② SVR
:
-
用于回归任务的支持向量机。
-
主要参数与
SVC
类似。
③ LinearSVC
:
-
线性支持向量分类器,专门用于线性核的 SVM。
-
比
SVC(kernel='linear')
更高效。
④ LinearSVR
:
-
线性支持向量回归器,专门用于线性核的 SVM 回归。
3. SVM包中的主要参数
① kernel
:
-
核函数类型,默认为
'rbf'
。 -
可选值:
'linear'
、'poly'
、'rbf'
、'sigmoid'
或自定义核函数。
② C
:
-
正则化参数,默认为
1.0
。 -
较小的
C
值表示更强的正则化,较大的C
值表示更弱的正则化。
③ gamma
:
-
核函数的系数,默认为
'scale'
(即1 / (n_features * X.var())
)。 -
较小的
gamma
值表示核函数的影响范围较大,较大的gamma
值表示核函数的影响范围较小。
④ degree
:
-
多项式核的阶数,默认为
3
。 -
仅对
kernel='poly'
有效。
⑤ probability
:
-
是否启用概率估计,默认为
False
。 -
如果为
True
,可以使用predict_proba
方法获取类别概率。
4. SVM示例代码
import numpy as np
from sklearn.svm import SVC
import matplotlib.pyplot as plt
# 1. 自定义数据集
np.random.seed(42)
X = np.random.randn(100, 2) # 100 个样本,每个样本有 2 个特征
y = (X[:, 0] + X[:, 1] > 0).astype(np.int32) # 根据特征的线性组合生成标签
# 2. 初始化 SVM 模型
svm_model = SVC(kernel='linear', C=1.0, random_state=42)
# 3. 训练模型
svm_model.fit(X, y)
# 4. 可视化决策边界
def plot_decision_boundary(model, X, y):
# 创建网格点
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01),
np.arange(y_min, y_max, 0.01))
# 预测网格点的类别
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# 绘制决策边界
plt.contourf(xx, yy, Z, alpha=0.8, cmap='viridis')
# 绘制样本点
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', marker='o', cmap='viridis')
plt.title("SVM 决策边界")
plt.xlabel("特征 1")
plt.ylabel("特征 2")
plt.show()
# 可视化决策边界
plot_decision_boundary(svm_model, X, y)
二、SVM类型
1. 线性可分支持向量机(Linear Separable SVM)
① 定义
-
适用于数据 线性可分 的情况,即存在一个超平面可以将不同类别的样本完全分开。
-
目标是找到一个最优超平面,使得两类样本之间的间隔(margin)最大化。
② 数学形式
-
超平面方程:w⋅x+b=0,其中:
w 是法向量,决定了超平面的方向。
b 是偏置项,决定了超平面的位置。
-
优化目标:
- 约束条件:
其中 是样本的类别标签。
③ 特点
-
适用于数据完全线性可分的情况。
-
通过最大化间隔,提高模型的泛化能力。
2. 线性支持向量机(Linear SVM)
① 定义
-
适用于数据 近似线性可分 的情况,即数据中存在少量噪声或异常点,无法完全分开。
-
引入 松弛变量(slack variables),允许部分样本违反间隔约束。
② 数学形式
- 优化目标:
- 约束条件:
其中:
是松弛变量,表示第个样本违反间隔约束的程度。
是正则化参数,控制模型对误分类的惩罚力度。
③ 特点
-
通过引入松弛变量,允许部分样本误分类,提高模型的鲁棒性。
-
适用于数据近似线性可分的情况。
3. 非线性支持向量机(Nonlinear SVM)
① 定义
-
适用于数据 非线性可分 的情况,即无法通过一个超平面将不同类别的样本分开。
-
通过 核函数(Kernel Function) 将数据映射到高维空间,使得数据在高维空间中线性可分。
② 数学形式
- 核函数的作用是将原始特征空间映射到高维特征空间:
其中,甚至可以是无限维。
- 优化目标:
- 约束条件:
③ 常用核函数
- 线性核(Linear Kernel):
- 多项式核(Polynomial Kernel):
- 径向基核(RBF Kernel):
- Sigmoid 核(Sigmoid Kernel):
④ 特点
-
通过核函数,可以处理非线性可分的数据。
-
核函数的选择对模型性能有重要影响。
4. 总结
类型 | 适用场景 | 核心思想 | 关键参数/技术 |
---|---|---|---|
线性可分支持向量机 | 数据完全线性可分 | 最大化间隔 | 无松弛变量 |
线性支持向量机 | 数据近似线性可分 | 允许部分样本误分类 | 松弛变量、正则化参数 C |
非线性支持向量机 | 数据非线性可分 | 通过核函数映射到高维空间 | 核函数、正则化参数 C |
-
线性可分支持向量机 是理想情况,现实中较少见。
-
线性支持向量机 通过引入松弛变量,提高了模型的鲁棒性。
-
非线性支持向量机 通过核函数,可以处理复杂的非线性问题。
三、自定义数据集 使用scikit-learn中svm的包实现svm分类
1. 代码示例
import numpy as np
from sklearn.svm import SVC
import matplotlib.pyplot as plt
# 1. 自定义数据集
# 生成 200 个样本,每个样本有 2 个特征
np.random.seed(42) # 设置随机种子以确保结果可重复
X = np.random.randn(200, 2).astype(np.float32)
# 根据特征的线性组合生成标签,大于 0 标记为 1,否则标记为 0
y = (2 * X[:, 0] + 3 * X[:, 1] > 0).astype(np.int32)
# 2. 初始化 SVM 模型
# 使用线性核函数
svm_model = SVC(kernel='linear', random_state=42)
# 3. 训练模型
svm_model.fit(X, y)
# 4. 可视化决策边界和支持向量
def plot_decision_boundary(model, X, y):
# 创建网格点
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01),
np.arange(y_min, y_max, 0.01))
# 预测网格点的类别
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# 绘制决策边界
plt.contourf(xx, yy, Z, alpha=0.8, cmap='viridis')
# 绘制样本点
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', marker='o', cmap='viridis')
# 绘制支持向量
plt.scatter(model.support_vectors_[:, 0], model.support_vectors_[:, 1],
s=100, facecolors='none', edgecolors='r', label='支持向量')
plt.title("SVM 决策边界")
plt.xlabel("特征 1")
plt.ylabel("特征 2")
plt.legend()
plt.show()
# 可视化训练集的决策边界和支持向量
plot_decision_boundary(svm_model, X, y)
2. 代码解释
① 自定义数据集:
-
X = np.random.randn(200, 2).astype(np.float32)
:
生成 200 个样本,每个样本有 2 个特征。
使用 np.random.randn
生成符合标准正态分布的随机数。
astype(np.float32)
将数据类型转换为 32 位浮点数。
-
y = (2 * X[:, 0] + 3 * X[:, 1] > 0).astype(np.int32)
:
根据特征的线性组合生成标签。
公式 2 * X[:, 0] + 3 * X[:, 1] > 0
表示特征的线性组合是否大于 0。
大于 0 的样本标记为 1
,否则标记为 0
。
astype(np.int32)
将标签转换为 32 位整数。
② 初始化 SVM 模型:
-
svm_model = SVC(kernel='linear', random_state=42)
:
使用线性核函数初始化 SVM 模型。
kernel='linear'
表示使用线性核函数。
random_state=42
确保每次运行代码时结果一致。
③ 训练模型:
-
svm_model.fit(X, y)
:
使用训练集数据训练 SVM 模型。
④ 可视化决策边界和支持向量:
-
plot_decision_boundary
函数:
绘制 SVM 的决策边界和支持向量。
使用 np.meshgrid
创建网格点,覆盖整个特征空间。
使用 model.predict
预测网格点的类别。
使用 plt.contourf
绘制决策边界。
使用 plt.scatter
绘制样本点和支持向量。