本站原创文章,转载请说明来自《老饼讲解-BP神经网络》www.bbbdata.com
逐步回归是一种常用的建模方式,它可以有效地减少入模变量个数,加强模型的泛化能力
本文讲解逐步回归的思想以及逐步回归的具体算法流程,并展示一个使用逐步回归筛选变量的例子
通过本文可以快速了解什么是逐步回归,以及如何使用逐步回归来筛选入模变量,加强模型泛化能力
本节讲解逐步回归是什么,初步了解逐步回归有什么用
什么是逐步回归
逐步回归是机器学习中建模时用于筛选入模变量的一种方法
使用逐步回归方式进行建模,可以减少入模变量,起到预防过拟合的作用
逐步回归分为"向前选择"与"向后删除"两种方式,如下:
一、向前选择-逐步回归:"向前选择"就是逐个增加建模变量
假设有n个变量,则从1个变量开始,将n个变量逐个变量添加到模型之中
直到新添加变量不再对模型有所贡献时,则停止添加变量
如图所示,先在所有变量中,选出建模效果最好的变量作为第一个入模变量
然后再在剩余的变量中选出与第一个入模变量建模效果最好的作为第二个入模变量
如些反复,直到建模效果不再提升,则停止添加变量,并输出已经选择的变量
二、向后删除-逐步回归:"向后删除"就是逐个减少建模变量
向后删除则是先将所有变量进行建模,然后逐个变量剔除
直到剔除变量会对模型性能有所影响,则停止剔除变量
逐步回归-算法流程
向前选择是逐个添加变量进行建模,而向后删除则是从所有变量中逐个删除变量
由于向前选择与向后删除是类似的,下面只展示向前选择-逐步回归的算法流程
向前选择-逐步回归的具体算法流程如下:
1. 初始化待选变量池、已选变量池
此时待选变量池就是所有变量,已选变量池为空
2. 逐个变量添加到已选变量池,直到待选变量池为空
按如下方法逐个添加变量:
2.1. 确定本次最优变量
历遍待选变量池,将每个变量和已选变量池的变量进行建模
哪个变量效果最好,就选哪个变量作为本次选择的变量
2.2. 查检最优变量是否能带来模型提升
检查模型加入新变量后的效果提升是否显著
如果不显著则放弃该变量并停止添加变量
3. 输出已选变量池中的变量
本节展示逐步回归的应用例子与实现代码,进一步具体掌握逐步回归的使用方法
逐步回归-实现代码
下面使用breast_cancer数据来展示如何使用逐步回归来筛选入模变量
这里我们使用breast_cancer数据的前29个变量,预测最后一个变量
由于变量较多,所以我们使用逐步回归,挑选出尽量少的变量来预测最后一个变量
具体代码示例如下:
from sklearn import linear_model
import numpy as np
from sklearn.datasets import load_breast_cancer
#----数据加载------
data = load_breast_cancer() # 加载breast_cancer数据
X = data.data[:,:29] # 前29个变量作为x
y = data.data[:,29:] # 最后一个变量作为y
feature_names = data.feature_names # 变量名称
#-----逐步回归挑选变量--------------------
select_var = [] # 已挑选的变量
var_pool = np.arange(X.shape[1]) # 待挑选变量池
init_err = (abs(y-y.mean())).mean() # 初始化模型误差
err_rec = [init_err] # 误差记录
print("\n===========逐回步归过程===============")
clf = linear_model.LinearRegression() # 初始化模型
while(len(var_pool)>0): # 如果变量池中还有变量,则继续添加变量
best_err = float('inf') # 初始化本轮最小误差
best_var = None # 初始化本轮选出的最优变量
#---选出剩余变量中能带来最好效果的变量--------
for i in var_pool: # 对剩余变量进行历遍
# -------将新变量和已选变量一起训练模型----
cur_x = X[:,select_var+[i]] # 新变量和已选变量作为建模数据
clf.fit(cur_x,y) # 训练模型
pred_y = clf.predict(cur_x) # 模型预测值
cur_err = (abs(y-pred_y)).mean() # 计算平均绝对误差
# ------更新最佳变量---------------------
if(cur_err<best_err): # 如果本次的误差更低
best_err = cur_err # 更新最佳误差
best_var = i # 更新最佳变量
#-------检验新变量能否带来显著效果-------------
err_desc = (best_err-err_rec[-1] )/err_rec[-1] # 误差下降比
valid = True if (err_desc<0.001) else False # 检验误差下降效果是否明显
# 如果有显著效果,则将该变量添加到已选变量
if(valid):
print("本轮最佳误差:",best_err,",本轮最佳变量:",feature_names[best_var]) # 打印本轮的结果
err_rec.append(best_err) # 记录添加本次变量后的误差
select_var.append(best_var) # 将本次选出的变量添加到已选变量池
var_pool = var_pool[var_pool!=best_var] # 将本次选出的变量移出待选变量池
# 如果没有显著效果,则停止添加变量
else:
print("本轮最佳误差:",best_err,",本轮最佳变量:"
,feature_names[best_var],',效果不明显,不再添加变量')
break # 如果没有显著效果,则停止添加变量
print("最终选用变量",len(select_var),"个:",feature_names[select_var]) # 打印最终结果
运行结果如下:
可以看到,最终选出了24个变量,再添加变量时模型的误差下降效果不明显,就不再添加变量
事实上,挑选到第14个变量worst concavity时,误差已经足够低了,实际建模可以只使用前14个变量
End