机器学习——支持向量机(SVM)
支持向量机(Support Vector Machine,简称SVM)是一种强大的监督学习算法,常用于分类和回归任务。SVM在分类问题中尤其广受欢迎,因为它不仅能够在线性可分的情况下找到最优的分类超平面,还可以通过核函数处理非线性情况。
在本篇博客中,将介绍支持向量机的理论基础、关键概念以及通过Python代码实现一个简单的SVM分类器。
1. 线性分类基础
支持向量机是一种二分类模型,其基本思想是找到一个超平面来最大化不同类别之间的间隔,从而将数据分隔开来。在二维空间中,这个超平面就是一条直线,而在更高维的空间中,这个超平面就是一个超平面。
2. 间隔的定义
函数间隔与几何间隔
在SVM中,间隔(margin)是指分类超平面与支持向量之间的距离。对于一个样本点 ( x ( i ) , y ( i ) ) (x^{(i)}, y^{(i)}) (x(i),y(i)),函数间隔(functional margin)定义为:
γ ^ ( i ) = y ( i ) ( θ T x ( i ) + b ) \hat{\gamma}^{(i)} = y^{(i)} (\theta^T x^{(i)} + b) γ^(i)=y(i)(θTx(i)+b)
其中, θ \theta θ是超平面的法向量, b b b是截距, y ( i ) y^{(i)} y(i)是样本的类别标签。
几何间隔(geometric margin)定义为函数间隔除以 ∥ θ ∥ \|\theta\| ∥θ∥,即:
γ ( i ) = γ ^ ( i ) ∥ θ ∥ \gamma^{(i)} = \frac{\hat{\gamma}^{(i)}}{\|\theta\|} γ(i)=∥θ∥γ^(i)
最大间隔分类器的定义
SVM的目标是找到一个能够最大化几何间隔的分类超平面。这个超平面能够将不同类别的样本分开,并且使得支持向量到超平面的距离最大化。
3. 目标函数的优化求解
为了求解最大间隔分类器,我们需要优化一个目标函数。这个目标函数是一个凸二次规划问题,可以通过拉格朗日对偶性得到其对偶形式,然后通过求解对偶问题来得到原始问题的解。最终得到的优化问题如下:
max α ∑ i = 1 m α i − 1 2 ∑ i = 1 m ∑ j = 1 m y ( i ) y ( j ) α i α j ( x ( i ) ) T x ( j ) \underset{\alpha}{\max} \sum_{i=1}^{m} \alpha_i - \frac{1}{2} \sum_{i=1}^{m} \sum_{j=1}^{m} y^{(i)} y^{(j)} \alpha_i \alpha_j (x^{(i)})^T x^{(j)} αmaxi=1∑mαi−21i=1∑mj=1∑my(i)y(j)αiαj(x(i))Tx(j)
其中, α \alpha α是拉格朗日乘子, m m m是样本数量。
4. 核函数的定义
在处理非线性分类问题时,我们可以使用核函数将数据映射到高维空间中,从而使其在高维空间中线性可分。常用的核函数有线性核、多项式核、高斯核等。
5. 松弛变量的定义
在实际应用中,很难找到一个完全线性可分的数据集。为了处理部分重叠的情况,引入了松弛变量 ξ \xi ξ。松弛变量允许一些样本点距离超平面的函数间隔小于1,但是通过调节惩罚系数 C C C来控制这种情况的影响。
6. SVM总结
支持向量机是一种强大的监督学习算法,其核心思想是找到一个最大间隔的超平面来进行分类。通过引入核函数和松弛变量,支持向量机可以处理非线性分类问题,并且具有很好的泛化性能。
用Python实现SVM
接下来,用Python实现一个简单的SVM分类器,对一个合成数据集进行分类,并绘制出决策边界。
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.svm import SVC
# 生成合成数据集
X, y = datasets.make_classification(n_samples=100, n_features=2, n_informative=2, n_redundant=0, n_classes=2, n_clusters_per_class=1, random_state=42)
# 创建 SVM 模型
svm_model = SVC(kernel='linear')
# 训练模型
svm_model.fit(X, y)
# 绘制数据集和决策边界
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired, marker='o', edgecolors='k')
# 绘制决策边界
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
# 创建网格来评估模型
xx = np.linspace(xlim[0], xlim[1], 30)
yy = np.linspace(ylim[0], ylim[1], 30)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = svm_model.decision_function(xy).reshape(XX.shape)
# 绘制决策边界和间隔
ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--'])
ax.scatter(svm_model.support_vectors_[:, 0], svm_model.support_vectors_[:, 1], s=100, linewidth=1, facecolors='none', edgecolors='k')
plt.show()
运行以上代码后,将得到包含决策边界和支持向量的可视化结果。决策边界是一个直线,它将不同类别的样本点分开,并且距离最近的样本点到决策边界的距离是相等的,这些样本点就是支持向量。
通过以上步骤,成功地实现了一个简单的SVM分类器,并且用合成数据集进行了分类,并绘制出了决策边界和支持向量的可视化结果。
小结
本篇博客介绍了支持向量机的基本理论、关键概念以及优化求解方法,并通过Python代码实现了一个简单的SVM分类器。支持向量机作为一种强大的监督学习算法,在实际应用中具有广泛的应用前景,能够处理线性和非线性分类问题,并且具有很好的泛化能力。