作者 | 宋老师
来源 | JSong的数据科学小站
多重共线性是使用线性回归算法时经常要面对的一个问题。在其他算法中,例如决策树和贝叶斯,前者的建模过程是逐步递进,每次拆分只有一个变量参与,这种建模机制含有抗多重共线性干扰的功能;后者干脆假定变量之间是相互独立的,因此从表面上看,也没有多重共线性的问题。但是对于回归算法,不论是一般回归,逻辑回归,或存活分析,都要同时考虑多个预测因子,因此多重共线性是不可避免需要面对的,在很多时候,多重共线性是一个普遍的现象。在构造预测模型时如何处理多重共线性是一个比较微妙的议题。既不能不加控制,又不能一刀切,认为凡是多重共线性就应该消除。
1、共线性的原理
假设有k个自变量的多元线性回归模型:
其中误差项是一个期望值为0且服从正态分布的随机变量:
则利用最小二乘法可得参数的估计值为:
该求解公式唯一的条件是矩阵X是列满秩的,不然会有无穷多解:
当各变量之间存在共线性问题,即各变量之间存在部分线性相关时,例如:
易知此时X近乎是不满秩的(实际情况很难完全共线性),X^TX近乎是奇异的,X的最小奇异值会非常小,那它的影响到底有多大呢?我们先从矩阵计算的角度来看。
1.1 扰动分析
对于一个方程或者系统而言,当输入有一个非常微小的扰动时,我们希望方程或系统的输出变化也非常微小,如果输出的变化非常大,且不能被控制,那这个系统的预测就无效了,蝴蝶效应讲的就是这个。在矩阵计算中,这叫做扰动分析。
【扰动分析定理】设非奇异方阵A满足方程
它的精确解为x* ,当A存在一个小扰动时,假设 $\hat{x}$ 是新方程的解:
可以证明x* 的扰动满足:
可以看到矩阵的条件数越大,扰动就越大,即x的求解值会变得非常不准确。回到上面讲的线性回归问题,容易证明最小二乘法的解满足下面的正定方程:
此时
当方程有共线性问题时,X的最小特征值非常小,相应的,上述的条件数会非常大。也就是说机器学习中的共线性问题实际上就是矩阵计算中的条件数问题。
从实际应用的角度,一般若K<100,则认为多重共线性的程度很小,若是100<=K<=1000,则认为存在一般程度上的多重共线性,若是K>1000,则就认为存在严重的多重共线性。
1.2 方差分析
再从统计学的角度来看共线性。可以证明参数的协方差矩阵为
又对任意的常数矩阵A和随机变量x有
代入上式即可得
具体到每个参数,有:
其中是将第i个变量作为因变量,其他k-1个变量作为自变量进行线性回归获得的,且令
为方差膨胀因子(variance inflation factor,VIF)。当
时,即当第i个变量和其他变量之间存在线性关系时,VIF趋于无穷大。所以 VIF 的大小反应了变量的共线性程度。一般地,当VIF大于5或10时,认为模型存在严重的共线性问题。
同时考虑参数显著性检验的 t 统计量:
当存在共线性时,参数的标准差偏大,相应的 t 统计量 会偏小,这样容易淘汰一些不应淘汰的解释变量,使统计检验的结果失去可靠性。
另外考虑线性回归的残差
其中M是一个投影矩阵,且满足
易证明
而矩阵M的范数与X的条件数毫无关系,于是可以得出共线性并不影响模型的训练精度。但是对于泛化精度,由于参数的估计已经不准确啦,所以泛化误差肯定要差些,具体差多少,我还很难用公式表示出来。
总结一下,共线性问题对线性回归模型有如下影响:
2、共线性问题的解决方法
根据上一节的描述,共线性问题有如下几种检验方法:
当变量数不多,样本数不是很大时,上述的方法是没问题的,检验某个变量有共线性问题时,可以结合实际业务考虑直接剔除该变量。但是有的时候变量数大到有上千个,VIF的计算需要建立上千个回归模型(条件数仅能判定是否存在共线性,但不能找到对应的变量),这将耗费很长时间。
事实上我们可以从模型角度来直接规避共线性问题。
主成分分析法作为多元统计分析的一种常用方法在处理多变量问题时具有其一定的优越性,其降维的优势是明显的,主成分回归方法对于一般的多重共线性问题还是适用的,尤其是对共线性较强的变量之间。当采取主成分提取了新的变量后,往往这些变量间的组内差异小而组间差异大,起到了消除共线性的问题。
2.2 逐步回归法
逐步回归(Stepwise Regression)是一种常用的消除多重共线性、选取“最优”回归方程的方法。其做法是将逐个引入自变量,引入的条件是该自变量经F检验是显著的,每引入一个自变量后,对已选入的变量进行逐个检验,如果原来引入的变量由于后面变量的引入而变得不再显著,那么就将其剔除。引入一个变量或从回归方程中剔除一个变量,为逐步回归的一步,每一步都要进行F 检验,以确保每次引入新变量之前回归方程中只包含显著的变量。这个过程反复进行,直到既没有不显著的自变量选入回归方程,也没有显著自变量从回归方程中剔除为止。
2.3 岭回归、L2正则化(ridge regression)
岭回归是一种可用于共线性数据分析的有偏估计回归方法,它是一种改良的最小二乘估计法,通过放弃最小二乘法的无偏性,以损失部分信息、降低精度为代价获得回归系数更为符合实际、更可靠的回归方法,对条件数很大(病态数据)的拟合要强于最小二乘法。
而岭回归则是加入了L2惩罚项:
这样参数的方差不会过大,且随着惩罚项系数C的增大,共线性的影响将越来也小。在这个过程中,可以记录 (岭迹)的变化情况,通过对岭迹的波动来判断我们是否要剔除该变量。
那为什么说岭回归能解决共线性问题呢?从矩阵计算的角度来看,L2正则化下方程的解为:
在上一节我们讲到共线性代表正定矩阵X^T^X的条件数很大:
而当条件数很大时,矩阵的逆的数值计算也是非常不准确的,但是当我们给矩阵加上一个单位矩阵时,奇异性(不可逆)问题就完全没有啦。
进一步考虑对惩罚项对奇异值的影响,假设X的奇异值(SVD)分解为:
则容易证明
其中D是对角矩阵,且满足
其反应了惩罚项是如何影响到条件数的。
2.4 LASSO回归
LASSO回归和岭回归类似,只不过将惩罚项由L2范数改为了L1范数
L1范数没有L2范数那么圆润,毕竟存在不可导点,而且在L1范数下LASSO回归也给不出解析解啦,但是相对于岭回归,LASSO估计的参数能更容易收敛到0
2.5 ElasticNet回归等
ElasticNet回归同时兼顾了L1和L2惩罚项:
当许多变量是相关的时候,Elastic-net是有用的。Lasso一般会随机选择其中一个,而Elastic-net则会选在两个。
除此之外,还有L0范数(非零元的个数)、L1/2范数等。
3、Python实践
首先捏造一份好的数据,样本量为100,特征数为8,且满足方程:
其中误差项是期望为0,标准差为1.5的正态分布随机变量。
import numpy as npfrom sklearn.linear_model import LinearRegressionfrom sklearn import cross_validation coef0=np.array([5,6,7,8,9,10,11,12]) X1=np.random.rand(100,8) y=np.dot(X1,coef0)+np.random.normal(0,1.5,size=100) training=np.random.choice([True,False],p=[0.8,0.2],size=100) lr1=LinearRegression() lr1.fit(X1[training],y[training])# 系数的均方误差MSEprint(((lr1.coef_-coef0)**2).sum()/8)# 测试集准确率(R2)print(lr1.score(X1[~training],y[~training]))# 平均测试集准确率print(cross_validation.cross_val_score(lr1,X1,y,cv=5).mean())
此时平均准确率为0.934955,拟合的系数MSE为0.203657
然后我们基于这份数据另外构造出两份数据,第二份数据增加两个随机的特征用作对比,第一份数据则增加两个共线性特征:
X2=np.column_stack([X1,np.dot(X1[:,[0,1]],np.array([1,1]))+np.random.normal(0,0.05,size=100)]) X2=np.column_stack([X2,np.dot(X2[:,[1,2,3]],np.array([1,1,1]))+np.random.normal(0,0.05,size=100)]) X3=np.column_stack([X1,np.random.rand(100,2)])
先来看下它们的条件数
>>>print(np.linalg.cond(X1)) >>>print(np.linalg.cond(X2)) >>>print(np.linalg.cond(X3))6.29077685383110.9306124087.25066276479
可以看到X2的条件数很搭,最小奇异值为0.213,此时还不至于完全共线性。
拿这两份数据重新用线性回归拟合模型。
lr2=LinearRegression() lr2.fit(X2[training],y[training])# 系数的均方误差MSEprint(((lr2.coef_[:8]-coef0)**2).sum()/8)# 测试集准确率(R2)print(lr2.score(X2[~training],y[~training]))# 平均测试集准确率print(cross_validation.cross_val_score(lr2,X2,y,cv=5).mean()) lr3=LinearRegression() lr3.fit(X3[training],y[training])# 系数的均方误差MSEprint(((lr3.coef_[:8]-coef0)**2).sum()/8)# 测试集准确率(R2)print(lr3.score(X3[~training],y[~training]))# 平均测试集准确率print(cross_validation.cross_val_score(lr3,X3,y,cv=5).mean())
对于第二份共线性构造数据X2,有平均测试集准确率为0.932070,拟合的参数MSE为7.697837。可以看到MSE增加了很多,准确率也下降了0.2%,测试拟合的系数为:
>>>print(lr2.coef_) [ 10.506618 11.467777 6.35562175 7.56698262 9.44509206 9.81032939 11.66187822 12.29728702 -5.07439399 0.02649089]
在来看对比用的数据X3,其平均测试集准确率为0.934952,参数MSE为0.171651,与X1无异。
以上是直接的结果,我们再来看VIF
import matplotlib.pyplot as plt vif2=np.zeros((10,1))for i in range(10): tmp=[k for k in range(10) if k!=i] clf.fit(X2[:,tmp],X2[:,i]) vifi=1/(1-clf.score(X2[:,tmp],X2[:,i])) vif2[i]=vifi vif3=np.zeros((10,1))for i in range(10): tmp=[k for k in range(10) if k!=i] clf.fit(X3[:,tmp],X3[:,i]) vifi=1/(1-clf.score(X3[:,tmp],X3[:,i])) vif3[i]=vifi plt.figure() ax = plt.gca() ax.plot(vif2) ax.plot(vif3) plt.xlabel('feature') plt.ylabel('VIF') plt.title('VIF coefficients of the features') plt.axis('tight') plt.show()
可以看到第0、1、2、3、8、9个特征的VIF都过高。且可以看出第1个特征相对第0、2、3个特征的VIF较高。
最后我们试着用模型的方法来检测共线性问题
from sklearn.linear_model import Ridge plt.figure() n_alphas = 20alphas = np.logspace(-1,4,num=n_alphas) coefs = []for a in alphas: ridge = Ridge(alpha=a, fit_intercept=False) ridge.fit(X2, y) coefs.append(ridge.coef_) ax = plt.gca() ax.plot(alphas, coefs) ax.set_xscale('log') handles, labels = ax.get_legend_handles_labels() plt.legend(labels=[0,1,2,3,4,5,6,7,8,9]) plt.xlabel('alpha') plt.ylabel('weights') plt.title('Ridge coefficients as a function of the regularization') plt.axis('tight') plt.show()
其中当alpha取0.1时,岭回归估计的系数分别为
>>>print(coefs[0]) [ 2.70748655 0.95748918 3.53687372 5.2073456 8.70186695 9.84484102 10.67351759 11.74614246 2.46502016 3.19919212]
可以看到第0、1、2、3、8、9个变量都出现了波动,代表它们之间存在一定的共线性。观察岭迹,我们可以考虑剔除其中波动比较大的第1、8、9个变量。
另外Lasso回归类似,可以用sklearn中的linear_model.Lasso来学习,这里就不展示了。最后对于逻辑回归任务,sklearn函数内部提供了L1或L2正则化方案,通过它们也可以去检测共线性问题。
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
一、CDA持证人介绍 在数字化浪潮席卷商业领域的当下,数据分析已成为企业发展的关键驱动力。为助力大家深入了解数据分析在电商行 ...
2025-04-17CDA持证人简介:居瑜 ,CDA一级持证人,国企财务经理,13年财务管理运营经验,在数据分析实践方面积累了丰富的行业经验。 一、 ...
2025-04-16持证人简介: CDA持证人刘凌峰,CDA L1持证人,微软认证讲师(MCT)金山办公最有价值专家(KVP),工信部高级项目管理师,拥有 ...
2025-04-15持证人简介:CDA持证人黄葛英,ICF国际教练联盟认证教练,前字节跳动销售主管,拥有丰富的行业经验。在实际生活中,我们可能会 ...
2025-04-14在 Python 编程学习与实践中,Anaconda 是一款极为重要的工具。它作为一个开源的 Python 发行版本,集成了众多常用的科学计算库 ...
2025-04-14随着大数据时代的深入发展,数据运营成为企业不可或缺的岗位之一。这个职位的核心是通过收集、整理和分析数据,帮助企业做出科 ...
2025-04-11持证人简介:CDA持证人黄葛英,ICF国际教练联盟认证教练,前字节跳动销售主管,拥有丰富的行业经验。 本次分享我将以教培行业为 ...
2025-04-11近日《2025中国城市长租市场发展蓝皮书》(下称《蓝皮书》)正式发布。《蓝皮书》指出,当前我国城市住房正经历从“增量扩张”向 ...
2025-04-10在数字化时代的浪潮中,数据已经成为企业决策和运营的核心。每一位客户,每一次交易,都承载着丰富的信息和价值。 如何在海量客 ...
2025-04-09数据是数字化的基础。随着工业4.0的推进,企业生产运作过程中的在线数据变得更加丰富;而互联网、新零售等C端应用的丰富多彩,产 ...
2025-04-094月7日,美国关税政策对全球金融市场的冲击仍在肆虐,周一亚市早盘,美股股指、原油期货、加密货币、贵金属等资产齐齐重挫,市场 ...
2025-04-08背景 3月26日,科技圈迎来一则重磅消息,苹果公司宣布向浙江大学捐赠 3000 万元人民币,用于支持编程教育。 这一举措并非偶然, ...
2025-04-07在当今数据驱动的时代,数据分析能力备受青睐,数据分析能力频繁出现在岗位需求的描述中,不分岗位的任职要求中,会特意标出“熟 ...
2025-04-03在当今数字化时代,数据分析师的重要性与日俱增。但许多人在踏上这条职业道路时,往往充满疑惑: 如何成为一名数据分析师?成为 ...
2025-04-02最近我发现一个绝招,用DeepSeek AI处理Excel数据简直太爽了!处理速度嘎嘎快! 平常一整天的表格处理工作,现在只要三步就能搞 ...
2025-04-01你是否被统计学复杂的理论和晦涩的公式劝退过?别担心,“山有木兮:统计学极简入门(Python)” 将为你一一化解这些难题。课程 ...
2025-03-31在电商、零售、甚至内容付费业务中,你真的了解你的客户吗? 有些客户下了一两次单就消失了,有些人每个月都回购,有些人曾经是 ...
2025-03-31在数字化浪潮中,数据驱动决策已成为企业发展的核心竞争力,数据分析人才的需求持续飙升。世界经济论坛发布的《未来就业报告》, ...
2025-03-28你有没有遇到过这样的情况?流量进来了,转化率却不高,辛辛苦苦拉来的用户,最后大部分都悄无声息地离开了,这时候漏斗分析就非 ...
2025-03-27TensorFlow Datasets(TFDS)是一个用于下载、管理和预处理机器学习数据集的库。它提供了易于使用的API,允许用户从现有集合中 ...
2025-03-26