模型介绍
支持向量回归
支持向量回归(Support Vector Regression,SVR)是一种基于支持向量机(SVM)的机器学习算法,用于建立训练数据的非线性回归模型。
优点
-
支持非线性回归
SVR可以通过使用核函数将非线性问题映射到高维空间,从而使得非线性回归问题变为线性回归问题,能够适应各种复杂的数据分布。 -
鲁棒性
由于SVR优化目标函数中引入了边界违例的罚项,使得模型对于异常值和噪声具有较好的鲁棒性,能够抵抗一定程度的干扰。 -
高维特征处理能力
SVR能够有效地处理高维特征,即使在特征空间维度较高的情况下也能取得较好的性能。 -
模型泛化能力强
由于SVR使用边界支持向量表示决策边界,因此可以将模型看作是基于边界的模型,对于新样本的预测能力较强。
缺点
-
对于大规模数据集来说,训练时间较长。支持向量回归的求解过程中需要构建和优化一个大规模的二次规划问题,这会大大增加训练时间。
-
对于非线性问题,支持向量回归需要使用核函数来将数据映射到高维空间中进行处理。但是选择合适的核函数和调整核函数的参数是一项具有挑战性的任务,可能需要经过多次试验和调整。
-
支持向量回归对噪声和离群点非常敏感。噪声和离群点的存在会对模型的预测结果造成很大的影响,可能导致模型的性能下降。
-
对于多维特征的数据集来说,支持向量回归的性能可能不如其他回归算法好。当特征维度增加时,支持向量回归的计算复杂度也会增加,可能导致模型的性能下降。
k折交叉验证
k折交叉验证(K-fold cross-validation)则是一种模型评估方法,通过将数据分成k个部分进行训练和测试,来评估模型的稳定性和泛化能力。
优点
-
充分利用数据
k折交叉验证可以将数据集的每个样本都用于训练和测试,充分利用了数据的信息。 -
减小模型评估的偏差
通过多次随机划分训练集和测试集,可以减小模型评估的偏差,提高评估结果的准确性。 -
可以检测模型的过拟合和欠拟合
通过对不同参数设置下的模型进行交叉验证,可以观察模型在不同数据集上的表现,从而判断模型是否过拟合或欠拟合。
缺点
-
计算开销较大
k折交叉验证需要将数据集划分为k个子集并重复训练k次,计算开销相对较大,特别是对于大规模数据集和复杂模型来说。 -
结果的方差较大
由于每次划分数据集都是随机的,导致每次交叉验证的结果可能略有不同,结果的方差较大。 -
可能导致信息泄露
在进行特征选择或参数调优时,可能会使用测试集的信息来指导模型的选择,导致最终评估结果的偏高。
模型搭建
在使用SVR进行回归分析时,可以使用k折交叉验证来进行模型选择和参数调优,以提高模型的性能和准确性。具体的流程如下:
- 将原始数据分成k个互不重复的子集。
- 对于每个子集i,在剩余的k-1个子集上训练一个SVR模型,并在第i个子集上进行测试。计算出模型的误差或精度指标。
- 通过对k个模型的误差或精度指标进行平均,确定最佳的模型参数和超参数。
- 使用确定的最佳参数来重新训练整个数据集。
代码分享
# 导入必要的库
from sklearn.model_selection import cross_val_score, KFold
from sklearn.svm import SVR
from sklearn.model_selection import GridSearchCV, train_test_split
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import pyplot
# 创建样本数据
# X = np.array([[0, 0], [2, 2], [4, 4], [6, 6], [8, 8], [10, 10]])
# y = np.array([0, 2.3, 4.6, 6.9, 9.2, 11.5])
X = pd.read_excel('C:/Users/Desktop/k折/n/x.xlsx', sheet_name='Sheet1') # 读取数据
y = pd.read_excel('C:/Users/Desktop/k折/n/y.xlsx', sheet_name='Sheet1') # 读取数据
# 将数据集划分为训练集和测试集(留出法)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 定义需要使用的SVM模型
svr = SVR()
# 创建k折交叉验证对象
kf = KFold(n_splits=3)
# 定义超参数空间和网格搜索对象
param_grid = {'kernel': ['linear', 'rbf'], 'C': [0.1, 0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2], 'gamma': ['scale', 'auto']}
grid_search = GridSearchCV(svr, param_grid, cv=kf)
# 在训练集上使用网格搜索进行超参数寻优
grid_search.fit(X_train, y_train)
# 输出最佳超参数组合和在测试集上的性能指标
print("Best parameters:", grid_search.best_params_)
print("Test score: %.2f" % grid_search.score(X_test, y_test))
# Best parameters: {'C': 0.6, 'gamma': 'scale', 'kernel': 'rbf'}
# Test score: -0.20
#优化后的基模型
# print(grid_search.best_params_['kernel'])
model_svr = SVR(C=grid_search.best_params_['C'], kernel=grid_search.best_params_['kernel'], gamma=grid_search.best_params_['gamma'])
model_svr.fit(X_train, y_train)
predict_results = model_svr.predict(X_test)
print(len(predict_results))#10
dat = []
for i in range(1, 11):
dat.append(i)
# plt.xlim(0, 160) # 限定横轴的范围
palette = pyplot.get_cmap('Set1')
# plt.scatter(y_test, predict_results)
plt.plot(dat, y_test, color=palette(3), marker='*', label='True')
plt.plot(dat, predict_results, color=palette(1), marker='^', label='Predict')
plt.xticks(size=15)
plt.yticks(size=15)
plt.legend() # 让图例生效
# plt.show()
plt.show()