如何基于Bonferroni校正结果高效移除回归不显著特征
自动化构建Bonferroni校正后简化回归模型的实现方案
你之前手动指定列索引删除特征的方式存在明显隐患:使用公式接口拟合模型时,C()包裹的分类变量会自动生成多个哑变量系数,系数顺序和原始数据集的列顺序不是一一对应的,手动计数很容易错位删错特征,且代码可复用性极差。可以直接通过模型对象自带的属性匹配显著特征,全程不需要手动计数索引。
实现步骤
1. 存储多重检验返回结果
首先把Bonferroni校正的返回值赋值给变量,方便后续调用:
# 执行Bonferroni校正并存储结果 reject, p_corrected, alpha_sidak, alpha_bonf = smt.multipletests( model_a.pvalues, alpha=0.05, method='bonferroni', is_sorted=False, returnsorted=False )
返回的reject是布尔数组,顺序和model_a.pvalues的系数顺序完全一致,True代表校正后特征显著,False代表不显著;数组第一个元素对应模型截距项,不属于输入特征。
2. 提取所有显著特征
直接通过模型的参数索引匹配特征名,跳过第一个截距项即可:
# 提取校正后显著的特征名(排除截距项) significant_coefs = model_a.params.index[1:][reject[1:]].tolist()
3. 两种方式构建简化模型
方式1:直接自动生成公式拟合(最推荐,零出错)
不需要手动修改原始数据集,直接基于显著特征拼接新的公式拟合即可,完全兼容分类变量的哑变量编码逻辑:
# 拼接简化模型公式 simplified_formula = f"cost ~ {' + '.join(significant_coefs)}" # 拟合简化模型 model_simplified = smf.ols(formula=simplified_formula, data=train).fit()
方式2:生成过滤后的简化数据集
如果你确实需要得到只保留相关列的train_simplified数据集,需要先把哑变量名映射回原始数据集的列名,避免把自动生成的哑变量当成原始列处理:
import re original_keep_cols = set() for coef_name in significant_coefs: # 匹配C()包裹的分类变量,提取原始列名 if coef_name.startswith("C("): raw_col = re.match(r"C\((.*?)\)", coef_name).group(1) original_keep_cols.add(raw_col) # 连续变量直接保留 else: original_keep_cols.add(coef_name) # 加上因变量列,生成最终简化数据集 train_simplified = train[["cost"] + list(original_keep_cols)].copy()
注意事项
- 不要直接用布尔数组的索引去删原始train的列,分类变量生成的哑变量不对应原始数据集的独立列,直接按索引删列会出现匹配错位
- 如果后续调整模型公式、修改数据集列顺序,上述自动化代码不需要做任何手动修改,可直接运行
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

