基于粒子群优化算法优化支持向量回归模型(附完整代码)
关于作者
作者:小白熊
作者简介:精通python、matlab、c#语言,擅长机器学习,深度学习,机器视觉,目标检测,图像分类,姿态识别,语义分割,路径规划,智能优化算法,数据分析,各类创新融合等等。
联系邮箱 :xbx3144@163.com
科研辅导、知识付费答疑、个性化定制以及其他合作需求请联系作者~
在本文中,我们将详细探讨如何使用粒子群优化(Particle Swarm Optimization, PSO)算法来优化支持向量回归(Support Vector Regression, SVR)模型的参数,并展示这一过程在实际数据预测中的效果。我们将使用Python编程语言,并结合numpy
、pandas
、pyswarm
、sklearn
和matplotlib
等库来实现这一过程。
一、模型理论基础
1. 支持向量回归(SVR)
支持向量回归是一种用于回归分析的监督学习模型,它是支持向量机(SVM)在回归问题上的扩展。SVR的目标是找到一个函数,使得所有训练数据点尽可能接近该函数,同时允许一定的偏差。SVR的关键参数包括正则化参数C和核函数参数(如γ)。C参数控制模型的复杂度和训练数据的拟合程度,而γ参数影响核函数的宽度,从而影响模型的决策边界。
2. 粒子群优化(PSO)
粒子群优化是一种基于群体智能的优化算法,模拟鸟群或鱼群的觅食行为。在PSO中,每个粒子代表一个潜在的解决方案,通过不断调整自己的位置和速度来寻找最优解。算法的核心在于每个粒子根据自身的历史最优位置(pBest)和整个群体的历史最优位置(gBest)来更新自己的速度和位置。PSO算法简单、易于实现,且在许多实际问题中表现良好。
二、代码实现
1. 数据预处理
首先,我们加载数据并进行预处理。
python
import numpy as np
import pandas as pd
# 加载数据
data = pd.read_excel(r"数据.xlsx", sheet_name='2022')
# 填充缺失值
data = data.interpolate()
data = data.values
2. 特征提取与数据集划分
接下来,我们从数据中提取特征和目标变量,并将数据集划分为训练集和测试集。
python
from sklearn.model_selection import train_test_split
# 提取特征
features = data[:, [1, 2, 3, 4, 5, 12]]
labels = data[:, [6]]
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2, random_state=47)
3. 定义目标函数
目标函数用于评估给定参数下的SVR模型性能。我们使用均方误差(MSE)作为性能指标,并计算其平方根(RMSE)来评估模型的预测误差。
python
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error
# 定义目标函数
def fun_svr(params): # 最小化
global rmse_best
C, gamma = params
if C < 1e-6 or gamma < 1e-6:
return 1e10 # 避免参数过小
model = SVR(C=C, gamma=gamma, kernel='rbf')
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
if rmse < rmse_best:
rmse_best = rmse
rmse_list.append(rmse)
else:
rmse_list.append(rmse_best)
return rmse
4. 粒子群优化
使用pyswarm
库中的pso
函数来寻找最佳参数组合。
python
from pyswarm import pso
# 参数范围
lb = [1e-6, 1e-6] # 下界
ub = [100, 100] # 上界
# PSO
maxiter = 100 # 迭代次数
swarmsize = 300 # 种群大小
best_params, _ = pso(fun_svr, lb, ub, swarmsize=swarmsize, maxiter=maxiter, debug=True)
5. 模型训练与预测
使用找到的最佳参数训练最终的SVR模型,并进行预测。
python
# 提取最佳参数
best_C, best_gamma = best_params
# 使用最佳参数训练模型
final_model = SVR(C=best_C, gamma=best_gamma, kernel='rbf')
final_model.fit(X_train, y_train)
# 预测
final_y_pred = final_model.predict(X_test)
6. 评估模型性能
计算并打印模型的均方误差(MSE)、均方根误差(RMSE)、平均绝对误差(MAE)和平均绝对百分比误差(MAPE)。
python
from sklearn.metrics import mean_absolute_error, mean_absolute_percentage_error
mse = mean_squared_error(y_test, final_y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, final_y_pred)
mape = mean_absolute_percentage_error(y_test, final_y_pred)
print(f"Best C: {best_C}")
print(f"Best gamma: {best_gamma}")
print(f"RMSE: {rmse}")
print(f"MAE: {mae}")
print(f"MAPE: {mape}")
7. 结果可视化
绘制PSO迭代图和真实值与预测值的对比图,以直观地展示优化过程和模型性能。
python
import matplotlib.pyplot as plt
# 绘制PSO迭代图
plt.figure(figsize=(10, 6))
plt.plot(rmse_list1, label='RMSE')
plt.xlabel('迭代次数')
plt.ylabel('误差')
plt.title('PSO迭代图')
plt.show()
# 绘制真实值与预测值的对比图
plt.figure(figsize=(10, 6))
plt.plot(y_test, label='真实值')
plt.plot(final_y_pred, label='预测值')
plt.xlabel('样本序号')
plt.ylabel('预测值')
plt.title('验证集预测结果对比')
plt.legend()
plt.grid(True)
plt.show()
三、完整代码
python
import numpy as np
import pandas as pd
from pyswarm import pso
from sklearn.svm import SVR
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error, mean_absolute_percentage_error, mean_squared_error
import warnings
warnings.filterwarnings("ignore")
# 设置中文字体为SimHei
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 加载数据
data = pd.read_excel(r"数据.xlsx", sheet_name='2022')
# 填充缺失值
data = data.interpolate()
data = data.values
# 提取特征
features = data[:, [1, 2, 3, 4, 5, 12]]
labels = data[:, [6]]
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2, random_state=47)
# 保存每次迭代的RMSE
rmse_list = []
rmse_best = 1e10
# 定义目标函数
def fun_svr(params): # 最小化
global rmse_best
C, gamma = params
if C < 1e-6 or gamma < 1e-6:
return 1e10 # 避免参数过小
# 构建模型{'linear', 'poly', 'rbf', 'sigmoid', 'precomputed'}
model = SVR(C=C, gamma=gamma, kernel='rbf')
# 训练模型
model.fit(X_train, y_train)
# 预测
y_pred = model.predict(X_test)
# 计算均方误差
mse = mean_squared_error(y_test, y_pred)
# 记录RMSE
rmse = np.sqrt(mse)
if rmse < rmse_best:
rmse_best = rmse
rmse_list.append(rmse)
else:
rmse_list.append(rmse_best)
return rmse
# 参数范围
lb = [1e-6, 1e-6] # 下界
ub = [100, 100] # 上界
# PSO
maxiter = 100 # 迭代次数
swarmsize = 300 # 种群大小
best_params, _ = pso(fun_svr, lb, ub, swarmsize=swarmsize, maxiter=maxiter, debug=True)
# 提取最佳参数
best_C, best_gamma = best_params
# 使用最佳参数训练模型
final_model = SVR(C=best_C, gamma=best_gamma, kernel='rbf')
final_model.fit(X_train, y_train)
# 预测
final_y_pred = final_model.predict(X_test)
# 计算误差指标
mse = mean_squared_error(y_test, final_y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, final_y_pred)
mape = mean_absolute_percentage_error(y_test, final_y_pred)
print(f"Best C: {best_C}")
print(f"Best gamma: {best_gamma}")
print(f"RMSE: {rmse}")
print(f"MAE: {mae}")
print(f"MAPE: {mape}")
rmse_list1 = rmse_list[::swarmsize][:maxiter]
# 绘制PSO迭代图
plt.figure(figsize=(10, 6))
plt.plot(rmse_list1, label='RMSE')
plt.xlabel('迭代次数')
plt.ylabel('误差')
plt.title('PSO迭代图')
plt.show()
# 绘制真实值与预测值的对比图
plt.figure(figsize=(10, 6))
plt.plot(y_test, label='真实值')
plt.plot(final_y_pred, label='预测值')
plt.xlabel('样本序号')
plt.ylabel('预测值')
plt.title('验证集预测结果对比')
plt.legend()
plt.grid(True)
plt.show()
四、总结
本文详细介绍了如何使用粒子群优化算法来优化支持向量回归模型的参数。通过定义目标函数、设置参数范围、执行PSO算法、训练最终模型和评估模型性能等步骤,我们成功找到了最优的参数组合,并展示了模型在验证集上的预测效果。结果可视化部分进一步帮助我们直观地理解了优化过程和模型性能。这种方法不仅适用于SVR模型,还可以扩展到其他机器学习模型的参数优化中。