前言
“多元线性回归模型”很常见,是大多数人学习机器学习的第一个案例。不过还是有很多值得学习和注意的地方。多重共线性的问题会贯穿所有的机器学习模型,所以本文将“将原理知识插入代码段”,尝试从不同的角度叙述和解释“如何更好地建立和优化多元线性回归模型”。它将分为两部分:
详细原理
Python 实战
Python实战
Python的多元线性回归模型有很多实际案例。这里虽然选取了经典的房价预测,但是重要的过程简单完整,其中使用的精度优化方法有效,能够提供很好的参考价值。
数据探索
本文的数据集是经过清洗的美国某地区房价数据集。
import pandas as pdimport numpy as npimport seaborn as snsimport ***tplotlib.pyplot as pltdf = pd.read_csv('house_prices.csv')df.info();df.head()
参数描述:
neighborhood/area:所属街区和面积bedrooms/bathrooms:卧室和浴室style:房屋样式
多元线性回归建模
现在我们直接构建多元线性回归模型。
from stat***odels.formula.api import ols # 小写的 ols 函数才会自带截距项,OLS 则不会 # 固定格式:因变量 ~ 自变量(+ 号连接)lm = ols('price ~ area + bedrooms + bathrooms', data=df).fit()lm.sum***ry()
红框是我们关注的结果值,其中截距项的P值没有意义,可以忽略。
模型优化
从上图可以看出,模型的准确率较低,因为还有类别变量neighborhood和style没有被充分利用。这里,我们先来看看类别变量的类别分布:
# 类别变量,又称为名义变量,nominal variablesnominal_vars = ['neighborhood', 'style']for each in nominal_vars: print(each, ':') print(df[each].agg(['value_counts']).T) # Pandas 骚操作 # 直接 .value_counts().T 无法实现下面的效果 ## 必须得 agg,而且里面的中括号 [] 也不能少 print('='*35)
虚拟变量的设置
因为类别变量不能直接放入模型,所以这里需要进行转换,而多元线性回归模型中转换类别变量最常用的方法之一就是转换成虚拟变量。其实原理很简单。把不能直接用于建模的名义变量转换成可以放入模型的虚拟变量,核心就八个字:“分散,非此即彼”。下面是一个只有4行的监控数据集。
从上表中,我们不难发现:
该名义变量有 n 类,就能拆分出 n 个虚拟变量巧妙的使用 0 和 1 来达到
「用虚拟变量列代替原名义变量所在类别」
下一步是将生成的哑变量放入多元线性回归模型,但需要注意的是“转换后的哑变量需要舍弃一个”才能得到满秩矩阵。关于线性代数的具体原因和解释,可以在作者的打包论文中找到。我们可以理解,当名义变量可以分为N类时,只需要n-1个哑变量就足以知道所有的信息。丢弃哪一个可以根据实际情况决定。
因此,将虚拟变量添加到原始数据集的标称变量的步骤是:
抽出希望转换的名义变量(一个或多个)pandas的get_dummies函数与原数据集横向拼接
注意,虚拟变量设置成功后,需要与原始数据集进行拼接,才能一起放入模型中。
再次建模后,发现模型的精度大大提高,但潜在的多重共线性问题也随之浮现。
在解释模型中哑变量的系数之前,我们先消除模型中多重共线性的影响,因为消除了共线性之后,模型中自变量的系数又会发生变化,多元线性回归模型的最终方程也会不同。多元回归模型的一个主要假设是,我们预测的变量(自变量)是互不相关的。我们希望预测变量(自变量)与响应变量(因变量)相关,而不是彼此相关。方差膨胀因子(以下简称VIF)是“解释变量间有多重共线性时的方差与无多重共线性时的方差之比”
上述公式表明,在方差展开因子的检测中:
每个自变量都会有一个膨胀因子值 ,最后根据值的大小来选择是否删减
「既然 表示相关性,是谁跟谁的相关性呢?」
是自变量中的某一变量与除它外剩余的自变量进行多元线性回归,取回归结果,即模型精度来作为这个变量与剩余自变量的相关性。听起来可能有点绕,这里举一下实例(用 “面积、卧室数量和浴室数量” 作为自变量来预测房价,在进行自变量的方差膨胀因子的检测时,面积、卧室数和浴室数轮流做单独的因变量,剩下的两个变量作为自变量,来看看这三个自变量中那个变量对其余两个变量的解释性高)越大,如已经到了 0.9,那分母就很小, 的值就等于 10,即表示这个自变量已经同时解释了另外的某个或多个自变量,存在多元共线性,可以考虑删除一些自变量。
越大,共线性越严重。经验方法表明:“当,不存在多重共线性;当,有很强的多重共线性;当,存在严重的多重共线性"。
方差展开因子的检测
我们自己写一个方差展开因子的测试函数吧。
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))
发现卧室和卫生间有很强的相关性。可能这两个变量解释的是同一个问题,方差展开因子较大的自变量通常成对出现。
果然卧室和卫生间的方差扩展因子更高。这里,自变量believes被删除并再次建模。
lm = ols(formula='price ~ area + bathrooms + A + B', data=results).fit()lm.sum***ry()
模型精度略有下降,但消除复共线性后模型的泛化能力可以提高。再次执行多元共线性检测。
test_data = results[['area', 'bedrooms', 'A', 'B']]for i in test_data.columns: print(i, 't', vif(df=test_data, col_i=i))
那么,多重共线性就是“只能通过方差膨胀因子来看吗?”其实也不一定。还可以通过结合散点图或相关稀疏矩阵与模型中自变量的系数来看出线索。下图是未处理多重共线性时的自变量系数。
很明显,浴室的参数可能有问题。卫生间的数据每增加一次,总房价怎么可能会减少1.373*10美元的四次方?简单的画个散点图和热力图,就知道房子总价应该和卫生间数量成正比。
车型说明
多元回归模型具有很强的解释力,通过打印模型参数可以得到因变量和自变量之间的关系。
因此,最终建模结果如下,模型精度为0.916
此外,在方程结果中,截距项和面积、卧室等变量的系数很容易理解;a,b这两个哑变量可能相对比较难。其实根据原理部分的表格,如果房子在C区,那么方程中首字母A和B的值都是0,所以这就引出了很重要的一点:在使用哑变量的多元线性回归模型的结果中,模型中存在的哑变量与被删除的哑变量进行比较,所以这个结果意味着在其他东西完全相同的情况下(虚拟变量除外),A区的房子比C区的房子低8707.18美元,而B区的房子比C区的房子贵449896.73.7美元,当然我们也可以画一个箱线图来检查测试,发现结果在模型中显示为A和B的系数。
摘要
本文以多元线性回归为前提,建立了因变量房价和几个自变量的实际观测值的多元线性回归模型。分析和检验各预测变量对因变量的综合线性影响的显著性,尽可能消除多重共线性的影响,筛选出对因变量线性影响显著的自变量,优化基准模型,评估各变量的相对重要性,从而提高回归模型的预测精度。
本文来自少年我念你投稿,不代表舒华文档立场,如若转载,请注明出处:https://www.chinashuhua.cn/24/587041.html