数学建模学习-支持向量回归(Support Vector Regression)教程(9) 支持向量机SVM扩展
数学建模学习-支持向量回归(Support Vector Regression)教程(9)
目录
写在最前
注意本文的相关代码及例子为同学们提供参考,借鉴相关结构,在这里举一些通俗易懂的例子,方便同学们根据实际情况修改代码,很多同学私信反映能否添加一些可视化,这里每篇教程都尽可能增加一些可视化方便同学理解,但具体使用时,同学们要根据实际情况选择是否在论文中添加可视化图片。
系列教程计划持续更新,同学们可以免费订阅专栏,内容充足后专栏可能付费,提前订阅的同学可以免费阅读,同时相关代码获取可以关注博主评论或私信。
算法简介
支持向量回归(Support Vector Regression, SVR)是支持向量机(SVM)在回归问题上的扩展应用。SVR的基本思想是在高维特征空间中构建一个最优超平面,使得所有样本点到这个超平面的距离最小,同时允许一定的误差范围。
SVR的核心思想可以用以下数学公式表示:
对于给定的训练数据集 { ( x 1 , y 1 ) , . . . , ( x n , y n ) } \{(x_1,y_1), ..., (x_n,y_n)\} {(x1,y1),...,(xn,yn)},SVR试图找到一个函数 f ( x ) f(x) f(x):
f ( x ) = ⟨ w , x ⟩ + b f(x) = \langle w,x \rangle + b f(x)=⟨w,x⟩+b
其中目标是最小化:
1 2 ∥ w ∥ 2 + C ∑ i = 1 n ( ξ i + ξ i ∗ ) \frac{1}{2}\|w\|^2 + C\sum_{i=1}^n(\xi_i + \xi_i^*) 21∥w∥2+C∑i=1n(ξi+ξi∗)
满足约束条件:
- y i − ⟨ w , x i ⟩ − b ≤ ϵ + ξ i y_i - \langle w,x_i \rangle - b \leq \epsilon + \xi_i yi−⟨w,xi⟩−b≤ϵ+ξi
- ⟨ w , x i ⟩ + b − y i ≤ ϵ + ξ i ∗ \langle w,x_i \rangle + b - y_i \leq \epsilon + \xi_i^* ⟨w,xi⟩+b−yi≤ϵ+ξi∗
- ξ i , ξ i ∗ ≥ 0 \xi_i, \xi_i^* \geq 0 ξi,ξi∗≥0
算法特点
- 非线性映射:通过核函数可以将数据映射到高维空间,处理非线性问题
- 容错能力:引入软间隔,允许一定的预测误差
- 全局最优:求解过程是一个凸优化问题,可以得到全局最优解
- 稀疏性:最终模型只由支持向量决定,具有良好的泛化能力
- 适应性:通过选择不同的核函数可以适应不同类型的数据分布
环境准备
首先需要安装必要的Python包:
# requirements.txt
numpy>=1.21.0
scikit-learn>=0.24.2
matplotlib>=3.4.2
pandas>=1.3.0
安装依赖:
pip install -r requirements.txt
代码实现
1. 数据生成
首先,我们生成一个带有噪声的正弦函数数据作为示例:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVR
from sklearn.preprocessing import StandardScaler
# 设置随机种子以确保结果可重复
np.random.seed(42)
def generate_data():
# 生成x值
X = np.sort(5 * np.random.rand(100, 1), axis=0)
# 生成带有噪声的y值
y = np.sin(X).ravel() + np.random.normal(0, 0.1, X.shape[0])
return X, y
2. 模型训练
实现SVR模型的训练,包括数据标准化和不同核函数的比较:
def train_svr(X, y):
# 数据标准化
scaler_X = StandardScaler()
scaler_y = StandardScaler()
X_scaled = scaler_X.fit_transform(X)
y_scaled = scaler_y.fit_transform(y.reshape(-1, 1)).ravel()
# 创建SVR模型
svr_rbf = SVR(kernel='rbf', C=100, gamma=0.1, epsilon=0.1)
svr_lin = SVR(kernel='linear', C=100, epsilon=0.1)
svr_poly = SVR(kernel='poly', C=100, degree=3, epsilon=0.1)
# 训练模型
svr_rbf.fit(X_scaled, y_scaled)
svr_lin.fit(X_scaled, y_scaled)
svr_poly.fit(X_scaled, y_scaled)
return svr_rbf, svr_lin, svr_poly, scaler_X, scaler_y
3. 结果可视化
实现结果的可视化展示:
def plot_results(X, y, svr_rbf, svr_lin, svr_poly, scaler_X, scaler_y):
# 生成预测用的X值
X_plot = np.linspace(0, 5, 100)[:, np.newaxis]
X_plot_scaled = scaler_X.transform(X_plot)
# 预测
y_rbf = scaler_y.inverse_transform(svr_rbf.predict(X_plot_scaled))
y_lin = scaler_y.inverse_transform(svr_lin.predict(X_plot_scaled))
y_poly = scaler_y.inverse_transform(svr_poly.predict(X_plot_scaled))
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 绘制结果
plt.figure(figsize=(10, 8))
plt.scatter(X, y, color='darkorange', label='数据点', s=10)
plt.plot(X_plot, y_rbf, color='navy', label='RBF核函数', lw=2)
plt.plot(X_plot, y_lin, color='c', label='线性核函数', lw=2)
plt.plot(X_plot, y_poly, color='cornflowerblue', label='多项式核函数', lw=2)
plt.xlabel('X')
plt.ylabel('y')
plt.title('支持向量回归 (SVR) 不同核函数的比较')
plt.legend()
plt.grid(True)
plt.savefig('images/svr_comparison.png', dpi=300, bbox_inches='tight')
plt.close()
4. 主函数
将所有功能组合在一起:
def main():
# 生成数据
X, y = generate_data()
# 训练模型
svr_rbf, svr_lin, svr_poly, scaler_X, scaler_y = train_svr(X, y)
# 可视化结果
plot_results(X, y, svr_rbf, svr_lin, svr_poly, scaler_X, scaler_y)
if __name__ == "__main__":
main()
运行结果
运行代码后,我们可以得到不同核函数SVR的拟合效果比较图:

从图中可以看出:
- RBF核函数(径向基函数)表现最好,能够很好地捕捉数据的非线性特征
- 线性核函数表现最差,这是因为原始数据具有明显的非线性特征
- 多项式核函数的表现介于两者之间,能够部分捕捉非线性特征
总结
支持向量回归是一种强大的回归算法,特别适合处理非线性回归问题。通过选择合适的核函数和参数,SVR可以很好地平衡模型的复杂度和预测精度。在实际应用中,我们需要根据数据的特点选择合适的核函数,并通过交叉验证等方法选择最优的超参数。
主要优点:
- 可以处理非线性问题
- 泛化能力强
- 计算效率高
- 全局最优解
主要缺点:
- 对参数选择敏感
- 计算复杂度随样本量增加而显著增加
- 对特征尺度敏感,需要进行标准化处理
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)