支持向量机(Support Vector Machine,SVM)是一种强大的监督学习算法,用于分类和回归任务。其核心思想是在高维空间中找到一个最优的超平面,将不同类别的数据分开。SVM的关键在于找到支持向量,即离超平面最近的数据点,这些支持向量决定了超平面的位置和方向。SVM通过最大化支持向量与超平面的间隔来实现分类,这个间隔被称为“间隔最大化”。对于非线性可分的数据,SVM可以通过核函数将数据映射到更高维的空间中,从而使其线性可分,常用的核函数有线性核、多项式核和高斯核等。SVM具有良好的泛化能力和鲁棒性,适用于处理小样本、高维度数据,并且不易受到局部极小值的影响。
一、支持向量机原理与数学描述
感知机算法使用误分类样本到分隔超平面的距离作为损失函数,通过最小化该距离调整参数\(w\)和\(b\)以得到最终的超平面。然而,初始参数和选择的误分类样本不同会导致不同的超平面。支持向量机通过在各种可能的超平面中选择最佳者来解决这个问题,考虑到参数的初值和误分类样本的影响,以此实现更好的分类效果。
线性向量支持 | 非线性向量支持 |
---|---|
2.1 线性可分支持向量机
给定一个线性可分的训练集,\(T=\left \{ (x_{1},y_{1}), (x_{2},y_{2}),..., (x_{N},y_{N})\right \}\)找到一个间隔最大的分隔超平面\(w^{*}\cdot x+b^{*}=0\)(确定\(w^{*}\)和\(b^{*}\)),将两类数据正确划分。分类确信度,一个正类样本点,被预测为正类,如果样本点距离超平面越近,预测结果的确信度越高,反之越低。负类样本亦如此。
为了能表示分类预测的确信度,需要定义函数间隔和几何间隔。
对于给定的训练数据集\(T\)和超平面 \((w,b)\), 函数间隔定义:
- 超平面 \((w, b)\) 关于样本点 \(\left(x_i, y_i\right)\) 的函数间隔为:
- 超平面 \((w, b)\) 关于训练数据 \(\mathrm{T}\) 的函数间隔为 所有样本点 \(\left(x_i, y_i\right)\) 的函数间隔最小值:
几何间隔是对分隔超平面的参数 \(\mathrm{W}\) 加上一个约束,即归一化 \(\mid W \|=1\) ,对于给定的训练数据集T和超平面 \((w,b)\) ,几何间隔定义:
- 超平面 \((w, b)\) 关于样本点 \(\left(x_i, y_i\right)\) 的几何间隔为:
- 超平面 \((w, b)\) 关于训练数据 \(\mathrm{T}\) 的几何间隔为所有样本点 \(\left(x_i, y_i\right)\) 的几何间隔最小值:
- 函数间隔和几何间隔的关系如下:
几何间隔最大的超平面:
\[\max _{w, b} \gamma \\ s.t. \quad y_i\left(\frac{w}{\|w\|} \cdot x_i+\frac{b}{\|w\|}\right) \geqslant \gamma, \quad i=1,2, \cdots, N\]考虑到函数间隔和几何间隔的关系,该最优化问题可改写为:
\[\begin{array}{ll} \max _{w, b} & \frac{\hat{\gamma}}{\|w\|} \\ \text { s.t. } & y_i\left(w \cdot x_i+b\right) \geqslant \hat{\gamma}, \quad i=1,2, \cdots, N \end{array} \]由于当 \(w\) 和 b同时扩大 2 倍,函数间隔 \(\hat{\gamma}\) 也会同时扩大为原来的 2 倍,这对于上述的优化问题和约束条件并没有影响,因此,可取 \(\hat{\gamma}=1\) ,则上述最优化问题变成:
\[\min _{w, b} \frac{1}{2}\|w\|^2 \\ s.t.\quad y_i\left(w \cdot x_i+b\right)-1 \geqslant 0, \quad i=1,2, \cdots, N\]SVM求解分隔超平面要满足两个条件:正确划分训练数据集;几何间隔最大,即距离分隔超平面最近的点的几何间隔最大。
2.2 支持向量和间隔边界
在线性可分情况下,训练数据集的样本点中与分隔超平面距离最近的样本点称为支持向量。
硬间隔 | 支持向量和间隔 |
---|---|
支持向量\(X^{i}\)对应的约束条件为:\(y^{(i)}(w\cdot X^{(i)}+b )-1=0\)。当\(y^{(i)}=+1\)时,支持向量所在的超平面为:\(H_{1}: w\cdot X+b=1\);当\(y^{(i)}=-1\)时,支持向量所在的超平面为:\(H_{2}: w\cdot X+b=-1\),在确定最终的分隔超平面时,只有支持向量起作用,其他的样本点不起作用。
2.3 对偶算法
怎样求解线性可分支持向量机的最优化问题?根据拉格朗日对偶性,将原始问题转化为对偶问题,通过求解对偶问题的最优解,然后进一步求解就得原始问题的最优解和,这就是线性可分支持向量机的对偶算法。采用对偶算法的优点,一是对偶算法往往更容易求解,二是自然的引入核函数,进而推广到非线性分类的问题。
对每个不等式约束引入拉格朗日乘子\(\alpha_i\) ,将其转化为无约束的最优化问题求解,定义以下拉格朗日函数:
其中, \(\alpha=\left(\alpha_1, \alpha_2, \cdots, \alpha_N\right)^{\mathrm{T}}\) 为非负的拉格朗日乘子向量。
根据拉格朗日对偶性,得到等价的对偶问题:
对线性可分训练数据集,假设对偶最优化问题对 \(\alpha\) 的解为 \(\alpha^*=\left(\alpha_1^*, \alpha_2^*, \ldots, \alpha_N^*\right)^T\) ,可以由 \(\alpha^*\) 求得原始最优化问题对 \(w\) 和 \(b\) 的最优解 \(w^*\) 和 \(b^*\) 。
\[\begin{array}{ll} \min _\alpha & \frac{1}{2} \sum_{i=1}^N \sum_{j=1}^N \alpha_i \alpha_j y_i y_j\left(x_i \cdot x_j\right)-\sum_{i=1}^N \alpha_i \\ \text { s.t. } & \sum_{i=1}^N \alpha_i y_i=0 \\ & \alpha_i \geqslant 0, \quad i=1,2, \cdots, N \end{array} \]
输入: 线性可分训练集 \(T=\left\{\left(x_1, y_1\right),\left(x_2, y_2\right), \cdots,\left(x_N, y_N\right)\right\}\), 其中 \(x_i \in \mathcal{X}=\mathbf{R}^n\), \(y_i \in \mathcal{Y}=\{-1,+1\}, i=1,2, \cdots, N ;\)
输出: 分离超平面和分类决策函数。
(1) 构造并求解约束最优化问题求得最优解 \(\alpha^*=\left(\alpha_1^*, \alpha_2^*, \cdots, \alpha_N^*\right)^{\mathrm{T}}\) 。
\[w^*=\sum_{i=1}^N \alpha_i^* y_i x_i \]
(2) 计算并选择 \(\alpha^*\) 的一个正分量 \(\alpha_j^*>0\), 计算
\[b^*=y_j-\sum_{i=1}^N \alpha_i^* y_i\left(x_i \cdot x_j\right) \](3)求得分离超平面
\[w^* \cdot x+b^*=0 \]分类决策函数:
\[f(x)=\operatorname{sign}\left(w^* \cdot x+b^*\right) \]
2.4 非线性支持向量机
对于非线性的分类问题,可以使用非线性支持向量机。非线性问题往往不好求解,通常采取的方法是进行一个非线性变换,将非线性问题变换成线性问题,通过求解变换后的线性问题的方法来求解原来的非线性问题。常常采用核技巧(使用一个线性变换将原空间的数据映射到新空间,然后在新空间里用线性分类学习方法从训练数据中学习分类模型。),核技巧应用到支持向量机的思想是,通过一个非线性变换将输入空间(欧氏空间)对应一个特征空间(希尔伯特空间),使得再输入空间中的超曲面模型对应于特征空间中的超平面模型,这样,分类问题的学习任务通过在特征空间中求解线性支持向量机就可以完成。
核函数的作用是在不显式计算高维特征空间的情况下,隐式地将样本映射到高维空间。这样可以避免直接计算高维特征空间的复杂性,而只需要在低维空间中进行计算,常用的核函数如下表所示。
名称 | 表达式 | 参数 |
---|---|---|
线性核 | \(\kappa\left(\boldsymbol{x}_i, \boldsymbol{x}_j\right)=\boldsymbol{x}_i^{\top} \boldsymbol{x}_j\) | |
多项式核 | \(\kappa\left(\boldsymbol{x}_i, \boldsymbol{x}_j\right)=\left(\boldsymbol{x}_i^{\top} \boldsymbol{x}_j\right)^d\) | \(d \geq 1\) 为多项式的次数 |
高斯核 | \(\kappa\left(\boldsymbol{x}_i, \boldsymbol{x}_j\right)=\exp \left(-\frac{\left|\boldsymbol{x}_i-\boldsymbol{x}_j\right|^2}{2 \delta^2}\right)\) | \(\delta>0\) 为高斯核的带宽(width) |
拉普拉斯核 | \(\kappa\left(\boldsymbol{x}_i, \boldsymbol{x}_j\right)=\exp \left(-\frac{\left|\boldsymbol{x}_i-\boldsymbol{x}_j\right|}{\delta}\right)\) | \(\delta>0\) |
Sigmoid核 | \(\kappa\left(\boldsymbol{x}_i, \boldsymbol{x}_j\right)=\tanh \left(\beta \boldsymbol{x}_i^{\top} \boldsymbol{x}_j+\theta\right)\) | \(\tan\) 为双曲正切函数,\(\beta>0\),\(\theta<0\) |
非线性支持向量机学习算法:
\[\begin{array}{ll} \min _\alpha & \frac{1}{2} \sum_{i=1}^N \sum_{j=1}^N \alpha_i \alpha_j y_i y_j K\left(x_i, x_j\right)-\sum_{i=1}^N \alpha_i \\ \text { s.t. } & \sum_{i=1}^N \alpha_i y_i=0 \\ & 0 \leqslant \alpha_i \leqslant C, \quad i=1,2, \cdots, N \end{array} \]
输入: 训练数据集 \(T=\left\{\left(x_1, y_1\right),\left(x_2, y_2\right), \cdots,\left(x_N, y_N\right)\right\}\), 其中 \(x_i \in \mathcal{X}=\mathbf{R}^n, y_i \in\) \(\mathcal{Y}=\{-1,+1\}, i=1,2, \cdots, N\);
输出: 分类决策函数。
(1)选取适当的核函数 \(K(x, z)\) 和适当的参数 \(C\), 构造并求解最优化问题求得最优解 \(\alpha^*=\left(\alpha_1^*, \alpha_2^*, \cdots, \alpha_N^*\right)^{\mathrm{T}}\) 。
\[b^*=y_j-\sum_{i=1}^N \alpha_i^* y_i K\left(x_i, x_j\right) \]
(2) 选择 \(\alpha^*\) 的一个正分量 \(0<\alpha_j^*<C\), 计算(3)构造决策函数:
\[f(x)=\operatorname{sign}\left(\sum_{i=1}^N \alpha_i^* y_i K\left(x, x_i\right)+b^*\right) \]
三、支持向量机回归
图1 | 图2 |
---|---|
传统的回归模型通常直接基于模型输出 \(f(x)\) 与真实输出 \(y\) 之间的差值来计算损失,当模型输出和真实输出完全相同时,损失才为零。支持向量回归能容忍 \(f(x)\) 和 \(y\) 之间最多有 \(\varepsilon\) 的偏差,仅当 \(f(x)\) 与 \(y\) 之间差别绝对值大于 \(\varepsilon\) 时才计算损失。如上图1所示,相当于以 \(f(x)\) 为中心,构建了一个宽度为 \(2 \varepsilon\) 的间隔带,若训练样本落入间隔带,则认为时被预测正确的。
SVR问题可形式化为:
其中, \(\ell_\epsilon(z)= \begin{cases}0, & \text { if }|z| \leqslant \epsilon ; \\ |z|-\epsilon, & \text { otherwise }\end{cases}\),见图2所示。
由于间隔带两侧的松他程度可不同,引入松驰变量 \(\xi\) 和 \(\hat{\xi}_i\) ,优化函数为:
四、支持向量机和回归的Python实现
4.1 支持向量机
import mglearn
import matplotlib.pyplot as plt
from sklearn.svm import SVC
# 假设 mglearn.tools.make_handcrafted_dataset() 是一个存在的函数,
# 它将返回一些手工制作的特征数据 X 和对应的标签 y
X, y = mglearn.tools.make_handcrafted_dataset()
# 使用 RBF 核的 SVC 模型,C=10, gamma=0.1
svm = SVC(kernel='rbf', C=10, gamma=0.1).fit(X, y)
# 使用 mglearn 可视化工具绘制二维分隔线
mglearn.plots.plot_2d_separator(svm, X, eps=.5)
# 绘制数据点
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
# 绘制支持向量
sv = svm.support_vectors_
# 支持向量的类别标签由对偶系数的符号决定
sv_labels = svm.dual_coef_.ravel() > 0
mglearn.discrete_scatter(sv[:, 0], sv[:, 1], sv_labels, s=20, markeredgewidth=5)
# 设置坐标轴标签
plt.xlabel("feature0")
plt.ylabel("feature1")
# 显示图形
plt.show()
4.2 支持向量机回归
使用Python自带的波士顿房价数据集作为数据集,并将其分为按三七开分为data_train和data_test数据集。该数据集中“y1”为响应变量,为房屋总价,而x1-x9为特征变量,依次表示房屋的卧室数量、客厅数量、面积、装修情况、有无电梯、房屋所在楼层位置、有无地铁、关注度、看房次数共计9项。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import preprocessing
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.datasets import load_boston
# 加载波士顿房价数据集
boston = load_boston()
data = pd.DataFrame(boston.data, columns=boston.feature_names)
data['y1'] = boston.target
# 打印数据集的前10行
print("波士顿房价数据集前10行:")
print(data.head(10))
# 划分特征和响应变量
X = data.drop('y1', axis=1)
y = data['y1']
# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 划分训练集和测试集
data_train, data_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.3, random_state=42)
# 使用径向基核函数(rbf)的支持向量机回归模型
model_rbf = SVR(kernel='rbf')
model_rbf.fit(data_train, y_train)
y_pred_rbf = model_rbf.predict(data_test)
score_rbf = model_rbf.score(data_test, y_test)
mse_rbf = mean_squared_error(y_test, y_pred_rbf)
mae_rbf = mean_absolute_error(y_test, y_pred_rbf)
r2_rbf = r2_score(y_test, y_pred_rbf)
coef_rbf = model_rbf.dual_coef_[0]
intercept_rbf = model_rbf.intercept_[0]
print("\n径向基核函数(rbf)支持向量机回归模型结果:")
print("拟合优度:", score_rbf)
print("均方误差(MSE):", mse_rbf)
print("平均绝对误差(MAE):", mae_rbf)
print("R^2决定系数:", r2_rbf)
print("回归关系式: y = ", end="")
for i in range(len(coef_rbf)):
print(f"{coef_rbf[i]} * x{i} + ", end="")
print(intercept_rbf)
# 绘制预测值与真实值比较图
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred_rbf, color='blue', label='Predicted')
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], '--', color='red', label='Actual')
plt.title("Comparison of Predicted and Actual Values (SVR with RBF Kernel)")
plt.xlabel("Actual Values")
plt.ylabel("Predicted Values")
plt.legend()
plt.grid(True)
plt.show()
总结
支持向量机(Support Vector Machine,简称SVM)算法是机器学习领域中的一种重要方法,尤其在分类和回归分析中展现出强大的性能。SVM算法在多个领域都有着广泛的应用,以下列举几个典型的例子:
图像识别:SVM算法能够处理高维数据,因此在图像识别领域具有独特的优势。图像可以表示为像素点的向量,而每个像素点都可以表示为颜色或灰度值。这些像素值可以用于训练SVM模型,从而实现对不同物体的识别。例如,SVM算法可以用于医学图像分析,检测病变和肿瘤,并对其进行分类。
文本分类:SVM算法在文本分类任务中也表现出色。它可以学习不同文本的特征,并在分类时使用这些特征。例如,SVM可以用于垃圾邮件检测,通过分析邮件中的特定单词或短语,将垃圾邮件与非垃圾邮件区分开来。此外,SVM还可以用于情感分析,判断文本所表达的情感倾向。
金融预测:在金融领域,SVM算法可以用于预测股票价格、信用风险等。通过对历史数据的学习,SVM可以捕捉到市场的潜在规律,为投资者提供有价值的参考信息。
支持向量机算法是一种强大而灵活的机器学习方法,通过在高维空间中寻找最优超平面实现数据的分类和回归。通过与其他算法进行集成,可以进一步提高其性能。在实际应用中,SVM算法在图像识别、文本分类、金融预测等多个领域都取得了显著的效果。随着机器学习技术的不断发展,相信SVM算法将在更多领域发挥重要作用。