作者萝卜
来源|早起python(id:Zaoqi-python ) )。
“多元线性回归模型”非常常见,是很多人进入机器学习的第一个案例,但其中有很多值得学习和关注的地方。 其中多元共线性这一问题贯穿于所有的机器学习模型,本文旨在通过“将原理知识嵌入代码段”,以不同的视角阐述和说明“如何更好地建立和优化多元线性回归模型”。 主要分为两个部分。
详细原理
Python 实战
Python 实战Python多元线性回归的模型实战案例非常多。 虽然这里采用的是经典的房价预测,但贵在流程简洁完整,其中所用的精度优化方法效果出众,可提供较好的参考价值。
数据探索本文的数据集是清洗后的美国某地区房价数据集。
importpandasaspdimportnumpyasnpimportseabornassnsimportmatplotlib.pyplotaspltdf=PD.read _ CSV (house _ prices.CSV df )
参数说明:
neighborhood/area:所属街区和面积
bedrooms/bathrooms:卧室和浴室
style:住宅风格
多元线性回归建模目前,我们直接建立多元线性回归模型:
fromstatsmodels.formula.apiimportols #小写ols函数具有截尾项,但ols没有#固定格式。 变量~参数(编号连接) lm=ols (price~areabedroomsbathrooms
从模型优化上的图中可以看出,模型的精度很低。 这是因为类别变量neighborhood和style没有被完全利用。 现在,我们先来看看类别变量的类别分布。
#类变量,也称为名义变量,由nominalvariablesnominal _ vars=[ ' neighborhood ',' style ' ] foreachinnnominal _ vars 3360 print (电子邮件地址) 在' : ' ) print(df[each].AgG ) [ ' value_counts ' ].t ] # pandas骚动操作#直接. value _ counts ).t中,实现以下效果必须得到##agg,而且大括号[]也不能直接将print('='*35 )虚拟变量的设置类变量放入模型中,因此需要在此处进行转换原理其实很简单,将不能直接用于建模的名义变量转换为可以放入模型的虚拟变量的核心只有8个字符。 “四散分解,不是这个”。 以下,使用仅4行的微数据集辅助说明。
从上表可以看出:
这个名义变量如果有n类,就可以分割n个虚拟变量。
巧用的0和1,达到“用虚拟变量列替换有原始名义变量的类”。
接下来要做的是将生成的虚拟变量们放入多元线性回归模型中,但请注意,为了得到完全秩矩阵,“必须舍弃一个变换后的虚拟变量们”。 关于具体原因和线性代数的解释可以理解为笔者可以看到打包的论文,如果这个名义变量可以分为n类,那么只需要n-1个虚拟变量就可以知道所有的信息。 应该放弃哪一个,可以根据实际情况决定。
因此,将虚拟变量添加到原始数据集的某个名义变量的步骤为:
提取要转换的名义变量(一个或多个) ) ) ) ) ) ) ) )。
pandas的get_dummies函数
与原始数据集横向连接
请注意,如果虚拟变量设置成功,则必须连接到原始数据集并将其放入模型中。
重新建模后,模型的精度有了很大的提高,但也出现了潜在的多变量共线性问题。
在说明模型中虚拟变量的系数之前,请先消除模型中多元共线性的影响。 这是因为排除共线性后,模型中的各个自我变化
量的系数又会改变,最终的多元线性回归模型的等式又会不一样。多重线性回归模型的主要假设之一是我们的预测变量(自变量)彼此不相关。我们希望预测变量(自变量)与反应变量(因变量)相关,而不是彼此之间具有相关性。方差膨胀因子 ( Variance Inflation Factor,以下简称 VIF ),是「指解释变量之间存在多重共线性时的方差与不存在多重共线性时的方差之比」。上图公式可以看出在方差膨胀因子的检测中:
每个自变量都会有一个膨胀因子值 ,最后根据值的大小来选择是否删减。
既然 表示相关性,是谁跟谁的相关性呢? 是自变量中的某一变量与除它外剩余的自变量进行多元线性回归,取回归结果,即模型精度来作为这个变量与剩余自变量的相关性。听起来可能有点绕,这里举一下实例:用 “面积、卧室数量和浴室数量” 作为自变量来预测房价,在进行自变量的方差膨胀因子的检测时,面积、卧室数和浴室数轮流做单独的因变量,剩下的两个变量作为自变量,来看看这三个自变量中哪个变量对其余两个变量的解释性高。
越大,如已经到了 0.9,那分母就很小, 值就等于 10,即表示这个自变量已经同时解释了另外的某个或多个自变量,存在多元共线性,可以考虑删除一些自变量。
VIF 越大,显示共线性越严重。经验判断方法表明:当 0< VIF <10,不存在多重共线性;当10≤ VIF < 100,存在较强的多重共线性;当 VIF≥ 100,存在严重多重共线性。方差膨胀因子的检测
我们自己来写一个方差膨胀因子的检测函数。
def vif(df, col_i): """ df: 整份数据 col_i:被检测的列名 """ cols = list(df.columns) cols.remove(col_i) cols_noti = cols formula = col_i + '~' + '+'.join(cols_noti) r2 = ols(formula, df).fit().rsquared return 1. / (1. - r2)现在进行检测。
test_data = results[['area', 'bedrooms', 'bathrooms', 'A', 'B']]for i in test_data.columns: print(i, 't', vif(df=test_data, col_i=i))发现 bedrooms 和 bathrooms 存在强相关性,可能这两个变量是解释同一个问题,方差膨胀因子较大的自变量通常是成对出现的。
果然,bedrooms 和 bathrooms 这两个变量的方差膨胀因子较高,这里删除自变量 bedrooms 再次进行建模。
lm = ols(formula='price ~ area + bathrooms + A + B', data=results).fit()lm.summary()模型精度稍降,但消除了多元共线性后能够使模型的泛化能力提升。再次进行多元共线性检测。
test_data = results[['area', 'bedrooms', 'A', 'B']]for i in test_data.columns: print(i, 't', vif(df=test_data, col_i=i))那么多元共线性就只有通过方差膨胀因子才能看的出来吗? 其实并不一定,通过结合散点图或相关稀疏矩阵和模型中自变量的系数也能看出端倪。下图是未处理多元共线性时的自变量系数。
可以很明显的看出,bathrooms 的参数很可能是有问题的,怎么可能 bathrooms 的数据量每增加一个,房屋总价还减少 1.373*10 的四次方美元呢?简单的画个散点图和热力图也应该知道房屋总价与 bathrooms 个数应该是成正比例关系的。
模型解释
多元线性回归模型的可解释性比较强,将模型参数打印出来即可求出因变量与自变量的关系。
所以最终的建模结果如下,且该模型的精度为0.916。
另外在等式结果中,截距项 Intercept 和 area, bedrooms 等变量的系数都还好理解;A,B 这两个虚拟变量可能相对困难些。其实根据原理部分的表格来看,如果房屋在 C 区,那等式中 A 和 B 这两个字母的值便是 0,所以这便引出了非常重要的一点:使用了虚拟变量的多元线性回归模型结果中,存在于模型内的虚拟变量都是跟被删除掉的那个虚拟变量进行比较。所以这个结果便表示在其他情况完全一样时(即除虚拟变量外的项) A 区的房屋比 C 区低 8707.18 美元,B 区则比 C 区贵 449896.73.7 美元。当然我们也可以画个箱线图来查看与检验,发现结果正如模型中 A 与 B 的系数那般显示。
本文以多元线性回归为基础和前提,在因变量房价与多个自变量的实际观测值建立了多元线性回归模型;分析并检验各个预测变量对因变量的综合线性影响的显著性,并尽可能的消除多重共线性的影响,筛选出因变量有显著线性影响的自变量,对基准模型进行优化,并对各自变量相对重要性进行评定,进而提升了回归模型的预测精度。