线性可分支持向量机代码 举例说明 具体的变量数值变化
### 实现线性可分支持向量机
### 硬间隔最大化策略
class Hard_Margin_SVM:
### 线性可分支持向量机拟合方法
def fit(self, X, y):
# 训练样本数和特征数
m, n = X.shape
# 初始化二次规划相关变量:P/q/G/h
self.P = matrix(np.identity(n + 1, dtype=np.float))
self.q = matrix(np.zeros((n + 1,), dtype=np.float))
self.G = matrix(np.zeros((m, n + 1), dtype=np.float))
self.h = -matrix(np.ones((m,), dtype=np.float))
# 将数据转为变量
self.P[0, 0] = 0
for i in range(m):
self.G[i, 0] = -y[i]
self.G[i, 1:] = -X[i, :] * y[i]
# 构建二次规划求解
sol = solvers.qp(self.P, self.q, self.G, self.h)
# 对权重和偏置寻优
self.w = np.zeros(n,)
self.b = sol['x'][0]
for i in range(1, n + 1):
self.w[i - 1] = sol['x'][i]
return self.w, self.b
### 定义模型预测函数
def predict(self, X):
return np.sign(np.dot(self.w, X.T) + self.b)
通过一个具体的示例来展示硬间隔支持向量机的代码是如何运行的,并为每个变量提供具体的数据样例。
示例数据和解释
假设我们有如下的二维数据集,其中每个样本有两个特征(即二维坐标),并且样本属于两个类别 y ∈ { − 1 , 1 } y \in \{-1, 1\} y∈{−1,1}。我们将使用硬间隔支持向量机来找到一个最大化分类间隔的超平面。
示例数据
特征矩阵 X X X(每一行是一个样本的坐标):
X = np.array([
[1, 2],
[2, 3],
[3, 3],
[2, 1],
[3, 2]
])
标签向量 y y y(每个样本的类别标签):
y = np.array([1, 1, 1, -1, -1])
这个数据集包含 5 个样本,分别对应两个类别(1 和 -1)。前 3 个样本属于类别 + 1 +1 +1,后两个样本属于类别 − 1 -1 −1。
代码中的每个变量解释
让我们一步步来分析代码中的每个变量。
(1) 训练样本数和特征数
m, n = X.shape
X.shape
返回
m
m
m 和
n
n
n,分别表示样本数量和特征数量:
- m = 5 m = 5 m=5 表示有 5 个样本。
- n = 2 n = 2 n=2 表示每个样本有 2 个特征(二维数据)。
(2) 初始化二次规划相关矩阵
self.P = matrix(np.identity(n + 1, dtype=np.float))
self.q = matrix(np.zeros((n + 1,), dtype=np.float))
self.G = matrix(np.zeros((m, n + 1), dtype=np.float))
self.h = -matrix(np.ones((m,), dtype=np.float))
我们将定义二次规划问题的参数矩阵:
-
self.P
:用于构建目标函数的二次项 1 2 w T P w \frac{1}{2} w^T P w 21wTPw,在支持向量机中,目标是最小化 1 2 ∥ w ∥ 2 \frac{1}{2} \|w\|^2 21∥w∥2,因此 P P P 是一个 ( n + 1 ) × ( n + 1 ) (n+1) \times (n+1) (n+1)×(n+1) 的单位矩阵(表示 w 1 , w 2 w_1, w_2 w1,w2 和 b b b)。self.P = np.identity(3) # 2 个特征 + 1 个偏置 # 输出 [[1. 0. 0.] [0. 1. 0.] [0. 0. 0.]]
-
self.q
:表示线性项 q q q,其值为 0,因为硬间隔 SVM 中我们只需要最小化 1 2 ∥ w ∥ 2 \frac{1}{2} \|w\|^2 21∥w∥2,不需要其他线性项。self.q = np.zeros(3) # 输出 [0. 0. 0.]
-
self.G
和self.h
:这些是约束条件,用于确保每个样本都正确分类并满足硬间隔条件 y i ( w T x i + b ) ≥ 1 y_i(w^T x_i + b) \geq 1 yi(wTxi+b)≥1。self.G = np.zeros((5, 3)) # 5 个样本,每个样本对应 (w1, w2, b) self.h = -np.ones(5) # 对应每个样本的约束 # 输出 G 和 h G = [[0. 0. 0.] [0. 0. 0.] [0. 0. 0.] [0. 0. 0.] [0. 0. 0.]] h = [-1. -1. -1. -1. -1.]
(3) 构建约束矩阵 G G G 和 h h h
接下来,我们要根据数据构建约束条件:
self.P[0, 0] = 0 # 偏置 b 不需要惩罚
for i in range(m):
self.G[i, 0] = -y[i] # 对偏置项的影响
self.G[i, 1:] = -X[i, :] * y[i] # 对 w 的影响
每一行 G [ i ] G[i] G[i] 对应样本 X [ i ] X[i] X[i] 的约束 y i ( w T x i + b ) ≥ 1 y_i(w^T x_i + b) \geq 1 yi(wTxi+b)≥1:
样本 X X X | 标签 y y y | 约束条件 |
---|---|---|
(1, 2) | 1 | w 1 ⋅ 1 + w 2 ⋅ 2 + b ≥ 1 w_1 \cdot 1 + w_2 \cdot 2 + b \geq 1 w1⋅1+w2⋅2+b≥1 |
(2, 3) | 1 | w 1 ⋅ 2 + w 2 ⋅ 3 + b ≥ 1 w_1 \cdot 2 + w_2 \cdot 3 + b \geq 1 w1⋅2+w2⋅3+b≥1 |
(3, 3) | 1 | w 1 ⋅ 3 + w 2 ⋅ 3 + b ≥ 1 w_1 \cdot 3 + w_2 \cdot 3 + b \geq 1 w1⋅3+w2⋅3+b≥1 |
(2, 1) | -1 | − w 1 ⋅ 2 − w 2 ⋅ 1 − b ≥ 1 -w_1 \cdot 2 - w_2 \cdot 1 - b \geq 1 −w1⋅2−w2⋅1−b≥1 |
(3, 2) | -1 | − w 1 ⋅ 3 − w 2 ⋅ 2 − b ≥ 1 -w_1 \cdot 3 - w_2 \cdot 2 - b \geq 1 −w1⋅3−w2⋅2−b≥1 |
更新后的 G G G 矩阵和 h h h 向量为:
self.G = [[-1. -1. -2.] # 对应第一个样本的约束
[-1. -2. -3.] # 对应第二个样本的约束
[-1. -3. -3.] # 对应第三个样本的约束
[ 1. 2. 1.] # 对应第四个样本的约束
[ 1. 3. 2.]] # 对应第五个样本的约束
self.h = [-1. -1. -1. -1. -1.]
(4) 使用二次规划求解
使用 cvxopt.solvers.qp
进行求解:
sol = solvers.qp(self.P, self.q, self.G, self.h)
这个函数会求解二次规划问题,返回包含最优解的字典 sol
。
(5) 提取权重和偏置
从求解结果中提取权重 w w w 和偏置 b b b:
self.w = np.zeros(n,)
self.b = sol['x'][0] # 偏置 b
for i in range(1, n + 1):
self.w[i - 1] = sol['x'][i] # 提取权重 w
假设 sol['x']
返回如下最优解:
sol['x'] = [1.5, 0.5, -0.5]
则:
self.b = 1.5
是偏置项。self.w = [0.5, -0.5]
是权重向量 w 1 = 0.5 w_1 = 0.5 w1=0.5 和 w 2 = − 0.5 w_2 = -0.5 w2=−0.5。
6. 使用模型进行预测
def predict(self, X):
return np.sign(np.dot(self.w, X.T) + self.b)
假设我们用训练好的模型对样本进行预测,预测公式为:
y
预测
=
sign
(
w
T
x
+
b
)
y_{\text{预测}} = \text{sign}(w^T x + b)
y预测=sign(wTx+b)
例如,输入样本
X
=
[
1
,
2
]
X = [1, 2]
X=[1,2],计算
y
预测
y_{\text{预测}}
y预测:
y
预测
=
sign
(
0.5
⋅
1
+
(
−
0.5
)
⋅
2
+
1.5
)
=
sign
(
0.5
+
(
−
1
)
+
1.5
)
=
sign
(
1.0
)
=
1
y_{\text{预测}} = \text{sign}(0.5 \cdot 1 + (-0.5) \cdot 2 + 1.5) = \text{sign}(0.5 + (-1) + 1.5) = \text{sign}(1.0) = 1
y预测=sign(0.5⋅1+(−0.5)⋅2+1.5)=sign(0.5+(−1)+1.5)=sign(1.0)=1
模型预测结果为正类 + 1 +1 +1。
总结
- 数据:输入的训练数据 X X X 和标签 y y y。
- 目标:通过二次规划找到最优的超平面参数 w w w 和 b b b。
- 预测:使用得到的模型参数 w w w 和 b b b 对新数据进行预测。
另一篇文章是对这段代码的整体说明:线性可分支持向量机代码实现