支持向量机(SVM)是一种广泛应用于分类问题的机器学习算法,其核心思想是通过找到一个最优超平面将样本空间分割开来。然而,SVM的训练过程涉及一个复杂的二次规划(Quadratic Programming, QP)问题。为了高效求解这一问题,SMO(Sequential Minimal Optimization)算法应运而生。本文将详细介绍SMO算法的原理与实现。
SVM的基本目标是找到一个能够将不同类别样本正确分类的超平面,且该超平面到两类样本中的最近点的距离(即间隔)最大。这个问题可以转化为一个凸二次规划问题:
\[ \min_{\mathbf{w}, b} \frac{1}{2} \|\mathbf{w}\|^2 \\ \text{s.t.} \quad y_i (\mathbf{w} \cdot \mathbf{x}_i + b) \geq 1, \quad i = 1, 2, \ldots, m \]
其中,\(\mathbf{w}\)是权重向量,\(b\)是偏置项,\((\mathbf{x}_i, y_i)\)是训练样本。
SMO算法是一种迭代优化算法,其基本思想是每次只优化两个拉格朗日乘子,通过不断迭代直到所有乘子都满足KKT条件。这样做的好处是将一个复杂的二次规划问题分解成一系列简单的子问题,大大降低了计算复杂度。
以下是一个简化版的SMO算法实现示例(Python代码):
def smo_simple(C, tol, max_iter, X, y):
m, n = X.shape
alpha = np.zeros(m)
b = 0
K = np.dot(X, X.T) # 计算核矩阵
for iter in range(max_iter):
alpha_pairs_changed = 0
for i in range(m):
E_i = b + np.sum(alpha * y * K[:, i]) - y[i]
if ((y[i] * E_i < -tol and alpha[i] < C) or
(y[i] * E_i > tol and alpha[i] > 0)):
j = select_j(i, m, y, E_i, C, alpha, K)
E_j = b + np.sum(alpha * y * K[:, j]) - y[j]
alpha_i_old = alpha[i]
alpha_j_old = alpha[j]
L, H = compute_L_H(C, alpha, y, i, j)
if L == H:
continue
eta = 2 * K[i, j] - K[i, i] - K[j, j]
if eta >= 0:
continue
alpha[j] = alpha_j_old - (y[j] * (E_i - E_j)) / eta
alpha[j] = clip_alpha(alpha[j], L, H)
if abs(alpha[j] - alpha_j_old) < tol:
alpha[j] = alpha_j_old
else:
alpha[i] = alpha_i_old + y[i] * y[j] * (alpha_j_old - alpha[j])
b1 = b - E_i - y[i] * (alpha[i] - alpha_i_old) * K[i, i] - y[j] * (alpha[j] - alpha_j_old) * K[i, j]
b2 = b - E_j - y[i] * (alpha[i] - alpha_i_old) * K[i, j] - y[j] * (alpha[j] - alpha_j_old) * K[j, j]
if 0 < alpha[i] < C:
b = b1
elif 0 < alpha[j] < C:
b = b2
else:
b = (b1 + b2) / 2
alpha_pairs_changed += 1
if alpha_pairs_changed == 0:
print(f"Iteration {iter}: no pairs changed")
break
return alpha, b
SMO算法是支持向量机训练过程中的关键优化算法,通过将复杂的二次规划问题分解成一系列简单的子问题,实现了高效求解。本文详细介绍了SMO算法的原理与实现,希望能够帮助读者深入理解SVM的训练过程。