支持向量机模型 0基础小白也能懂(附代码)
支持向量机模型 0基础小白也能懂(附代码)
支持向量机(SVM)是一种在机器学习领域具有重要影响力的算法,尤其在处理中小型数据集时表现出色。本文将从零开始,详细讲解SVM的基本概念、数学原理以及实际应用,适合机器学习初学者阅读。
什么是支持向量机模型
支持向量机(Support Vector Machine,简称SVM)是一种监督学习模型,主要用于分类和回归分析。SVM在机器学习界曾占据主导地位,即使在深度学习兴起的今天,它在某些场景下仍具有不可替代的优势。
针对不同的数据情况,SVM有多种变体:
- 线性可分支持向量机:适用于数据完全线性可分的情况,通过硬间隔最大化学习线性分类器。
- 线性支持向量机:适用于近似线性可分的数据,通过软间隔最大化学习线性分类器。
- 非线性支持向量机:适用于线性不可分的数据,通过核技巧将数据映射到高维空间,实现非线性分类。
核函数是SVM处理非线性问题的关键。它将低维数据映射到高维空间,使得原本线性不可分的数据在高维空间中变得线性可分。常见的核函数包括多项式核和高斯径向基核。
最大间隔分类器
分类问题与线性模型
分类问题是监督学习的核心任务之一。当输出变量取有限个离散值时,预测问题就成为分类问题。实际生活中,许多问题本质上都是分类问题,如文本分类、图像识别等。
最大间隔分类器
在分类问题中,决策边界的选择至关重要。SVM的目标是找到一个具有最大间隔的决策边界,使得分类结果具有最佳的鲁棒性和稳定性。具体来说,SVM希望找到一个决策边界,使得该边界与最近的数据点之间的距离最大化。
在这个决策边界中,位于边界两侧最近的数据点被称为支持向量。支持向量决定了决策边界的最终位置。
支持向量机详解
线性可分SVM与硬间隔最大化
考虑一个二分类问题,其中红色点表示+1类,蓝色点表示-1类。我们的目标是找到一个最优的划分直线,使得两类点被正确分开。
决策边界可以用线性方程表示:(f(x) = w \cdot x + b),其中(w)是权重向量,(b)是偏置项。当(f(x) > 0)时,预测为+1类;当(f(x) < 0)时,预测为-1类。
SVM的目标是最大化间隔(M),其计算公式为:(M = \frac{2}{||w||})。为了实现这一目标,SVM需要解决一个约束最优化问题:
几何间隔
通过拉格朗日乘子法,可以将原始优化问题转化为对偶问题。具体步骤如下:
- 构建拉格朗日函数
- 求解拉格朗日函数对(w)和(b)的极小值
- 求解对偶问题
- 通过对偶问题的解反推原始问题的解
最终,分离超平面可以表示为:
[
\sum_{i=1}^N \alpha_i^* y_i (x \cdot x_i) + b^* = 0
]
分类决策函数可以表示为:
[
f(x) = \text{sign} \left( \sum_{i=1}^N \alpha_i^* y_i (x \cdot x_i) + b^* \right)
]
线性SVM与软间隔最大化
在实际应用中,数据往往不是完全线性可分的。为了解决这个问题,SVM引入了软间隔最大化。具体来说,允许某些样本点违反间隔约束,但需要付出一定的惩罚代价。
通过引入松弛变量和惩罚参数(C),可以将问题转化为带约束的优化问题:
非线性SVM与核函数
对于线性不可分的数据,可以通过核函数将数据映射到高维空间,使其在高维空间中变得线性可分。常见的核函数包括:
- 多项式核:(k(x, x') = (\gamma x \cdot x' + r)^d)
- 高斯径向基核:(k(x, x') = \exp(-\gamma ||x - x'||^2))
通过核函数,可以在不显式计算高维映射的情况下,直接在原始空间中计算内积,从而避免了维度灾难。
SVM总结
SVM是一种强大的分类算法,通过最大化间隔和使用核函数,能够有效处理线性和非线性分类问题。其主要优点包括:
- 对于中小型数据集效果显著
- 通过核函数可以处理非线性问题
- 具有较好的泛化能力
主要缺点包括:
- 对大规模数据集训练时间较长
- 参数选择(如核函数类型、惩罚参数C等)需要经验
实现代码
使用Python的scikit-learn库可以方便地实现SVM分类。以下是一个使用不同核函数的示例:
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm, datasets
# 加载数据集
iris = datasets.load_iris()
X = iris.data[:, :2] # 只取前两维特征,方便可视化
y = iris.target
# 线性核函数
svc = svm.SVC(kernel='linear', C=1).fit(X, y)
plot_decision_regions(X, y, classifier=svc, title='SVC with linear kernel')
# 多项式核函数
svc = svm.SVC(kernel='poly', degree=3).fit(X, y)
plot_decision_regions(X, y, classifier=svc, title='SVC with polynomial kernel')
# 高斯核函数
svc = svm.SVC(kernel='rbf', C=1).fit(X, y)
plot_decision_regions(X, y, classifier=svc, title='SVC with RBF kernel')
def plot_decision_regions(X, y, classifier, resolution=0.02, title=''):
markers = ('s', 'x', 'o', '^', 'v')
colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
cmap = ListedColormap(colors[:len(np.unique(y))])
x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
np.arange(x2_min, x2_max, resolution))
Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
Z = Z.reshape(xx1.shape)
plt.contourf(xx1, xx2, Z, alpha=0.3, cmap=cmap)
plt.xlim(xx1.min(), xx1.max())
plt.ylim(xx2.min(), xx2.max())
for idx, cl in enumerate(np.unique(y)):
plt.scatter(x=X[y == cl, 0], y=X[y == cl, 1],
alpha=0.8, c=colors[idx],
marker=markers[idx], label=cl)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.legend(loc='upper left')
plt.title(title)
plt.show()
通过调整核函数类型和相关参数,可以观察到不同的分类效果。例如,高斯核函数的gamma参数控制着决策边界的平滑程度,较大的gamma值会导致过拟合。
通过这些实验,可以直观地理解SVM的工作原理和参数调优的重要性。