机器学习&数据挖掘

使用sklearn库中的SVR做回归分析

Author
宋天龙
发布于 2017-09-18
3410 次阅读
0 次赞
0 次分享
使用sklearn库中的SVR做回归分析
AI 智能核心导读

本文演示了基于sklearn库的多模型回归分析完整流程。通过对比贝叶斯岭回归、线性回归、弹性网络、SVR与梯度增强回归(GBR)的训练效果,结合6折交叉检验与MAE、MSE、R2等指标进行性能评估,并使用matplotlib可视化拟合结果。最终得出GBR算法表现最优的结论,并应用该模型对新数据完成了回归预测。

sklearn 中的回归有多种方法,广义线性回归集中在 linear_model 库下,例如普通线性回归、Lasso、岭回归等;另外还有其他非线性回归方法,例如核 svm、集成方法、贝叶斯回归、K 近邻回归、决策树回归等,这些不同回归算法分布在不同的库中。

本示例主要使用 sklearn 的多个回归算法做回归分析、用 matplotlib 做图形展示。

本示例模拟的是针对一批训练集做多个回归模型的训练和评估,从中选择效果较好的模型并对新数据集做回归预测。本示例主要使用 sklearn 的多个回归算法做回归分析、用 matplotlib 做图形展示。

完整代码如下:

python
1# 导入库 2import numpy as np # numpy库 3from sklearn.linear_model import BayesianRidge, LinearRegression, ElasticNet # 批量导 4from sklearn.svm import SVR # SVM中的回归算法 5from sklearn.ensemble.gradient_boosting import GradientBoostingRegressor # 集成算法 6from sklearn.model_selection import cross_val_score # 交叉检验 7from sklearn.metrics import explained_variance_score, mean_absolute_error, mean_squa 8import pandas as pd # 导入pandas 9import matplotlib.pyplot as plt # 导入图形展示库 10# 数据准备 11raw_data = np.loadtxt('regression.txt') # 读取数据文件 12X = raw_data[:, :-1] # 分割自变量 13y = raw_data[:, -1] # 分割因变量 14# 训练回归模型 15n_folds = 6 # 设置交叉检验的次数 16model_br = BayesianRidge() # 建立贝叶斯岭回归模型对象 17model_lr = LinearRegression() # 建立普通线性回归模型对象 18model_etc = ElasticNet() # 建立弹性网络回归模型对象 19model_svr = SVR() # 建立支持向量机回归模型对象 20model_gbr = GradientBoostingRegressor() # 建立梯度增强回归模型对象 21model_names = ['BayesianRidge', 'LinearRegression', 'ElasticNet', 'SVR', 'GBR'] # 不 22model_dic = [model_br, model_lr, model_etc, model_svr, model_gbr] # 不同回归模型对象 23cv_score_list = [] # 交叉检验结果列表 24pre_y_list = [] # 各个回归模型预测的y值列表 25for model in model_dic: # 读出每个回归模型对象 26 scores = cross_val_score(model, X, y, cv=n_folds) # 将每个回归模型导入交叉检验模型中 27 cv_score_list.append(scores) # 将交叉检验结果存入结果列表 28 pre_y_list.append(model.fit(X, y).predict(X)) # 将回归训练中得到的预测y存入列表 29# 模型效果指标评估 30n_samples, n_features = X.shape # 总样本量,总特征数 31model_metrics_name = [explained_variance_score, mean_absolute_error, mean_squared_e 32model_metrics_list = [] # 回归评估指标列表 33for i in range(5): # 循环每个模型索引 34 tmp_list = [] # 每个内循环的临时结果列表 35 for m in model_metrics_name: # 循环每个指标对象 36 tmp_score = m(y, pre_y_list[i]) # 计算每个回归指标结果 37 tmp_list.append(tmp_score) # 将结果存入每个内循环的临时结果列表 38 model_metrics_list.append(tmp_list) # 将结果存入回归评估指标列表 39 df1 = pd.DataFrame(cv_score_list, index=model_names) # 建立交叉检验的数据框 40 df2 = pd.DataFrame(model_metrics_list, index=model_names, columns=['ev', 'mae', 'ms 41 print ('samples: %d \t features: %d' % (n_samples, n_features)) # 打印输出样本量和特 42 print (70 * '-') # 打印分隔线 43 print ('cross validation result:') # 打印输出标题 44 print (df1) # 打印输出交叉检验的数据框 45 print (70 * '-') # 打印分隔线 46 print ('regression metrics:') # 打印输出标题 47 print (df2) # 打印输出回归指标的数据框 48 print (70 * '-') # 打印分隔线 49 print ('short name \t full name') # 打印输出缩写和全名标题 50 print ('ev \t explained_variance') 51 print ('mae \t mean_absolute_error') 52 print ('mse \t mean_squared_error') 53 print ('r2 \t r2') 54 print (70 * '-') # 打印分隔线 55# 模型效果可视化 56plt.figure() # 创建画布 57plt.plot(np.arange(X.shape[0]), y, color='k', label='true y') # 画出原始值的曲线 58color_list = ['r', 'b', 'g', 'y', 'c'] # 颜色列表 59linestyle_list = ['-', '.', 'o', 'v', '*'] # 样式列表 60for i, pre_y in enumerate(pre_y_list): # 读出通过回归模型预测得到的索引及结果 61 plt.plot(np.arange(X.shape[0]), pre_y_list[i], color_list[i], label=model_names[i]) 62 plt.title('regression result comparison') # 标题 63 plt.legend(loc='upper right') # 图例位置 64 plt.ylabel('real and predicted value') # y轴标题 65plt.show() # 展示图像 66# 模型应用 67print ('regression prediction') 68new_point_set = [[1.05393, 0., 8.14, 0., 0.538, 5.935, 29.3, 4.4986, 4., 307., 21., 69[0.7842, 0., 8.14, 0., 0.538, 5.99, 81.7, 4.2579, 4., 307., 21., 386.75, 14.67], 70[0.80271, 0., 8.14, 0., 0.538, 5.456, 36.6, 3.7965, 4., 307., 21., 288.99, 11.69], 71[0.7258, 0., 8.14, 0., 0.538, 5.727, 69.5, 3.7965, 4., 307., 21., 390.95, 11.28]] # 72for i, new_point in enumerate(new_point_set): # 循环读出每个要预测的数据点 73 new_pre_y = model_gbr.predict(new_point) # 使用GBR进行预测 74 print ('predict for new point %d is: %.2f' % (i + 1, new_pre_y)) # 打印输出每个数据

上述代码以空行分为 6 个部分。

第一部分导入库。

本示例中用到的库比较多:numpy 用于文件读写和基本数据处理;sklearn.linear_model 中的三个广义线性回归下的回归算法 BayesianRidgeLinearRegressionElasticNetsklearn.svm 中的 svr 回归算法,sklearn.ensemble.gradient_boosting 中的 GradientBoostingRegressor 回归算法;cross_val_score 用来做交叉检验;sklearn.metrics 下的多个回归模型指标评估方法用来做模型评估;pandas 用来做格式化的数据框,便于数据结果输出;Matplotlib 用来做预测结果的展示和对比。这里导入多种回归算法,目的是检验在没有先验经验的条件下,通过多个模型的训练,从中找到最佳拟合算法做后续应用。

第二部分数据准备。

使用 numpyloadtxt 方法读取数据文件,并使用索引切片功能从数据集中分割出自变量 X 和因变量 y。自变量 X 拥有 506 个样本,13 个特征变量。

第三部分训练回归模型。

  1. 本过程使用交叉检验的方法评估不同模型的训练效果。先设置交叉检验的次数为 6(6 折交叉检验),后续会在交叉检验模型训练中用到;
  2. 接着分别建立贝叶斯岭回归(BayesianRidge)、普通线性回归(LinearRegression)、弹性网络回归(ElasticNet)、支持向量机回归(SVR)、梯度增强回归(GradientBoostingRegressor)模型对象,前 3 个算法属于广义线性回归,后两个属于支持向量机和梯度增强算法的变体;
  3. 然后分别建立不同模型的名称列表、回归模型对象的集合、交叉检验结果空列表、回归模型预测的 y 值空列表,分别用于后续名称读取、模型代入交叉检验算法、交叉检验结果数据存储和回归预测的结果存储。
  4. 最后通过 for 循环读出每个回归模型对象,对每个回归模型导入交叉检验模型 cross_val_score 中做训练检验并设置检验 6 次,并将交叉检验结果通过 append 方法存入结果列表,将回归训练中得到的预测 y 通过 append 方法存入列表。

相关知识点:cross_val_score

cross_val_scoresklearn.model_selection 中的交叉检验工具,可以对特定算法模型进行交叉检验。常用参数:

python
1sklearn.model_selection.cross_val_score(estimator, X, y=None, groups=None, scoring=None, cv=None, n_jobs=1, verbose=0, fit_params=None, pre_dispatch='2*n_jobs')
  • estimator:要应用交叉检验的模型对象,该模型在交叉检验中会通过使用 fit 方法来训练模型
  • X, y:交叉检验的数据集 X 和目标 y,其中 X 至少是 2 维数据
  • cv:要进行交叉检验的模式。如果 cv 值为空,那么默认使用 3 折交叉检验;如果 cv 值是整数,那么使用按照指定的数量做交叉检验。这两种情况下都会调用 model_selection.StratifiedKFold 方法实现。如果 cv 值是用来交叉检验的生成器对象或可迭代的测试和训练集,那么将使用 sklearn.model_selection.KFold 方法。
  • cross_val_score 交叉检验后返回的得分默认调用算法模型的 score 方法做得分估计,因此不同的算法模型其得分计算方法可能有差异,具体取决于模型本身 score 方法(scorer(estimator, X, y))的计算逻辑。当然,也可以通过设置 scoring 参数字符串来手动指定得分计算方法,例如 cross_val_score(estimator, X, y, scoring='r2', cv=6)

第四部分模型效果指标评估。

先通过自变量数据集的 shape 获得总样本量和总特征数;

接着创建一个列表用于存储接下来用到的回归模型评估指标对象,explained_variance_score,mean_absolute_error,mean_squared_error,r2_score,这些对象在第一步导入库时已经导入,因此无需做其他处理便可直接使用;创建用于存储不同回归评估指标的列表。

  • explained_variance_score:解释回归模型的方差得分,其值取值范围是 [0,1],越接近于 1 说明自变量越能解释因变量的方差变化,值越小则说明效果越差。
  • mean_absolute_error:平均绝对误差(Mean Absolute Error,MAE),用于评估预测结果和真实数据集的接近程度的程度,其其值越小说明拟合效果越好。
  • mean_squared_error:均方差(Mean squared error,MSE),该指标计算的是拟合数据和原始数据对应样本点的误差的平方和的均值,其值越小说明拟合效果越好。
  • r2_score:判定系数,其含义是也是解释回归模型的方差得分,其值取值范围是 [0,1],越接近于 1 说明自变量越能解释因变量的方差变化,值越小则说明效果越差。

然后通过两层 for 循环来分别对每个模型和每种回归模型评估方法进行计算。需要注意的是里面有一个用于存储每个内循环的临时结果列表,需要在内循环结束之后,每次将其结果存储到外部循环中的回归评估指标列表。

下面是通过 pandasDataFrame 方法分别建立交叉检验和回归指标数据框,然后打印输出样本量和特征数量、交叉检验和回归指标数据框,并通过打印横线来做逻辑输出切分;

为了更好的理解指标的含义,打印输出缩写和全名标题对照表。在打印过程中使用的方法跟聚类中的类似,但是对于格式化的输出,这里使用了 pandas 的数据框,这样如果数据量比较多的情况下,更容易控制。输出结果如下:

code
1samples: 506 features: 13 2\-------------------------------------------------------------------------- 3cross validation result: 40 1 2 3 4 5 5BayesianRidge 0.662422 0.677079 0.549702 0.776896 -0.139738 -0.024448 6LinearRegression 0.642240 0.611521 0.514471 0.785033 -0.143673 -0.015390 7ElasticNet 0.582476 0.603773 0.365912 0.625645 0.437122 0.200454 8SVR -0.000799 -0.004447 -1.224386 -0.663773 -0.122252 -1.374062 9GBR 0.747920 0.809555 0.767936 0.862972 0.375267 0.559758 10\-------------------------------------------------------------------------- 11regression metrics: 12ev mae mse r2 13BayesianRidge 0.731143 3.319204 22.696772 0.731143 14LinearRegression 0.740608 3.272945 21.897779 0.740608 15ElasticNet 0.686094 3.592915 26.499828 0.686094 16SVR 0.173548 5.447960 71.637552 0.151410 17GBR 0.975126 1.151773 2.099835 0.975126 18\-------------------------------------------------------------------------- 19short name full name 20ev explained_variance 21mae mean_absolute_error 22mse mean_squared_error 23r2 r2

通过结果可以看出,增强梯度(GBR)回归是所有模型中拟合效果最好的,表现在能解释 97% 的方差变化,并且各个误差项的值都是最低的。另外,还有一个重要因素是,梯度增强算法在测试的 6 次中,其结果相对稳定性较高,这也说明了该算法在应对不同数据集的稳定效果。指标中 r2ev 的值是相同的,原因是 r2 作为判定系数,本身就是解释方差的比例,含义相同。

第五部分模型效果可视化。

该部分使用 Matplotlib 将原始数据 y 和其他 5 个回归模型预测到的 y 值通过趋势图进行对比。

先通过 figure 方法创建画布,然后画出原始数据 y 的分布,其中画图所需的 x 值域,使用自变量集 X 的形状得到一个自增数字列表。

接着画出其他 5 个回归预测结果展示所需要的颜色列表、样式列表,并通过 for 集合 plot 方法循环画出每个预测结果趋势线。

最后设置图形标题、图例位置(右上角)、y 轴标题并展示图像

注意 不要忘记设置图像位置,否则即使在 plot 方法中设置了 label 值(图例标签值),也会由于缺少图例位置而无法显示图例。

1
1

从图中看出,梯度增强算法(青色)的拟合程度跟原始数据(黑色)最接近,这也印证了在上面指标中输出的结果。

第六部分模型应用。

基于新给出的包含多个数据点的数据集,我们要预测未来值,直接使用 for 循环读出每个数据,然后使用最优回归模型梯度增强的 predict 方法做预测,得到如下结果:

code
1predict for new point 1 is: 21.49 2predict for new point 2 is: 16.84 3predict for new point 3 is: 19.50 4predict for new point 4 is: 19.16

上述过程中,主要需要考虑的关键点是:如何在样本维度较多的情况下,选择最佳的回归模型,这里我们使用了多个模型,并结合交叉检验的方法找到最优的回归方法。

分享
最后修订: 2017-09-18