共线性系列故事
作者:互联网
我们经常听说,建模时应当尽量避免共线性(collinearity),会导致参数估计不稳定、模型不可靠等等。那么共线性究竟有多可怕?共线性具体会带来什么问题?共线性得到的模型是否真的不行?笔者通过自己的一些思考,结合模拟数据的测试,对共线性的问题进行了些探讨。笔者拙见,如有纰漏,烦请指教。
其实很多变量都存在少量的共线性关系,但是对建模基本没有造成影响。本文主要探讨的是共线性较严重的情况。
问题引入
现在模拟一个情景:现在需要建立一个关于消费水平的预测模型,对于每个消费者收集了3个变量:月收入 ,存款 ,所在地区的经济水平 ,假设月收入与存款之间存在线性关系,这里为了简化问题,假设是2倍的关系(当然实际情况不是2倍,而且不是严格线性关系),即 ,并且假定消费水平与这3个变量之间的关系为:。当然这些是假定的理想情况,实际关系要复杂很多。因果关系是存在的,月收入、存款或当地经济水平,任意一个因素都确实可能影响消费者的消费水平。
很明显,如果直接建模,变量之间存在严重的共线性关系。我们来看看具体会产生哪些现象。
代码测试
为了解答这个问题,我用 R 和 Python 做了些测试,下面以R 代码为例:
# Test the influence of collinearity
# add random effect for the variable
add_random<-function(x, sd){
# generate random effect on the full data, using sd=sd
len<-length(x)
y=x+rnorm(len, mean = 0, sd = sd*1)
# generate random effect on the random 20% of data, using sd=sd*1.6
len1<-round(len*0.2)
index<-sample(1:len,len1,replace = FALSE)
y[index]<-y[index]+rnorm(len1,mean = 0, sd = sd*1.6)
# generate random effect on the random 16% of data, using sd=sd*1.8
len2<-round(len*0.16)
index<-sample(1:len,len2,replace = FALSE)
y[index]<-y[index]+rnorm(len2,mean = 0, sd = sd*1.8)
return(y)
}
# x1, x2, x3 are the true factor that generate the event (result varaiable, Y)
x1<-rnorm(100, mean = 16, sd = 1)
x2<-2*x1
x3<-rnorm(100, mean = 18, sd = 3)
# add random effect for x1, x2, x3, using sd=0.001.
# to guarantee the collinearity, the random effect should be small.
x1<-add_random(x1, sd=0.001)
x2<-add_random(x2, sd=0.001)
x3<-add_random(x3, sd=0.001)
# validate the relationship between x1 and x2.
cor(x1, x2)
# [1] 0.9999981
# if the cause-effect relationship is: y=8*x1+8*x2+6*x3
y<-8*x1 + 8*x2 + 6*x3
y<-add_random(y, sd=1)
# validate the relationship between y and (8*x1 + 8*x2 + 6*x3).
cor(y, 8*x1 + 8*x2 + 6*x3)
# [1] 0.9990227
# x4 is the combination of x1 and x2 with the same weight.
x4<-x1+x2
# fit the model using x1 and x3
model_A<-lm(y~x1+x3)
summary(model_A)
# Coefficients:
# Estimate Std.Error t value Pr(>|t|)
# (Intercept) 0.14680 2.42208 0.061 0.952
# x1 24.03943 0.15005 160.207 <2e-16 ***
# x3 5.94959 0.04482 132.745 <2e-16 ***
# Multiple R-squared: 0.9981, Adjusted R-squared: 0.998
# fit the model using x2 and x3
model_B<-lm(y~x2+x3)
summary(model_B)
# Coefficients:
# Estimate Std.Error t value Pr(>|t|)
# (Intercept) 0.16278 2.42378 0.067 0.947
# x2 12.01916 0.07508 160.088 <2e-16 ***
# x3 5.94944 0.04485 132.643 <2e-16 ***
# Multiple R-squared: 0.9981, Adjusted R-squared: 0.998
# fit the model using x4 and x3
model_C<-lm(y~x4+x3)
summary(model_C)
# Coefficients:
# Estimate Std.Error t value Pr(>|t|)
# (Intercept) 0.15712 2.42293 0.065 0.948
# x4 8.01290 0.05003 160.146 <2e-16 ***
# x3 5.94949 0.04484 132.692 <2e-16 ***
# Multiple R-squared: 0.9981, Adjusted R-squared: 0.998
# fit the model using x1, x2 and x3. This is the case which existing the collinearity.
model_D<-lm(y~x1+x2+x3)
summary(model_D)
# Coefficients:
# Estimate Std.Error t value Pr(>|t|)
# (Intercept) 0.14387 2.43502 0.059 0.953
# x1 28.98087 75.73214 0.383 0.703
# x2 -2.47062 37.86443 -0.065 0.948
# x3 5.94962 0.04505 132.055 <2e-16 ***
# Multiple R-squared: 0.9981, Adjusted R-squared: 0.998
下面,我们对这些结果进行解读。
共线性对非共线性变量的影响
共线性对非共线性变量的影响。这句话有点拗口,具体来说,我想探讨的第一个问题是:如果保留共线性的变量,那么建模时,那些非公线性的变量的系数估计会不会受到影响?
由上述 model_D 可知, 的系数的估计没有受到任何影响。并且,在增加变量数目或改变样本量后重新进行测试,都显示:非共线性的变量的系数估计都没有受到任何影响。
因此得出结论1:共线性对非共线性的变量的系数估计不产生影响。
共线性对模型拟合优度的影响
共线性对模型拟合优度的影响。这句话有点学术化,具体来说,我想探讨的第二个问题是:如果保留共线性的变量,那么建立的模型的预测能力是否受到影响?
由上述 model_D 可知,模型的 没有下降。并且,在增加变量数目或改变样本量后重新进行测试,都验证了这个现象。
因此得出结论2:共线性不会影响模型的拟合优度。
共线性对模型产生的具体影响
会使得共线性的变量的系数估计变得不可靠
原理解析
共线性影响模型泛化的一种情况
其实,有一种情况下,共线性建模会影响模型的泛化能力。当共线性的情况是由数据偶然所造成时,换一批数据后,共线性关系如果消失了,那么使用原先数据训练的模型,在新的数据中预测准确性会很差。
这种情况是存在的,仍然以刚刚的模拟情景为例。当我们用之前包含共线性变量的模型去测试这样一群消费者:刚刚毕业进入IT大厂的高收入程序员。高收入程序员,由于刚刚毕业,存款极少,那么存款与收入之间的共线性关系就消失了,那么之前保留共线性所训练的模型就有可能出现问题(因为系数的估计是不准的)。
更一般的情况是,当前选定的样本中,某些变量确实存在共线性,但是当扩大样本量后,共线性的关系消失了,那么原先保留共线性建模所得到的规律,在扩大样本量后就不再适用了。这种现象,笔者称之为“数据偶然造成的共线性”。这种共线性会导致模型变得不准确,此时需要对变量进行取舍。比如在某个小样本中,变量A和B存在共线性,且这种共线性时偶然造成的,那么我们需要考虑仅保留A或B(在当前数据上看,保留A或B似乎是差不多的),假定我们保留了A,并且系数有统计学意义。当换一批数据,AB的共线性关系消失时,AB中有一个和结局变量的关系有可能变得不显著。如果此时A变得不显著了,说明我们保留变量时没选对,人为造成了假阳性和假阴性。因此,在共线性时,挑选变量这一过程又变得没那么轻而易举,不是一个LASSO或者逐步回归能简单处理的。似乎,更明智的做法是,将所有变量保留下来,等待其他数据进行验证,经得起考验的变量就可以考虑纳入模型了。
人为消除共线性的好处
解释变量的意义解读
相比非线性模型,线性模型有一个好处,就是得到的模型参数(也就是变量的系数;非线性模型中的模型参数就不一定是系数了)是有实际意义的,模型本身也是基于概率和正态分布而推导的。因此,笔者习惯于优先使用广义线性模型拟合数据,如果效果不好,再使用非线性模型(如SVM、XGBoost、神经网络等)。
那么对于线性模型的解释变量的系数,究竟有怎样的意义呢?在没有共线性存在时,变量的系数的意义是确定的。在线性回归模型中,系数 的意义是:该变量每增加一个单位数值都会使结局变量增加 。而在 Logistic 回归中,系数的意义可以从OR的角度来解释(此处不赘述,Logistic 回归中十分重要的基本知识)。在理想状态下(完全不存在任何共线性时),单变量建模所得的系数与多变量建模所得的系数是一致的(可以程序模拟验证这一结论),因此其解释意义是不变的。
然而,当存在共线性时,情况就不一样了。若直接包含共线性建模,则所得系数无法收敛(系数取值有无数种可能),无法解释。若只保留共线性变量中的一个变量进行建模,则得到的系数的解释意义,就不再应该是该系数原本的解释意义了,严格来说应该是共线性变量群体的综合意义。或者说,保留的变量是一群变量的“代表”。因此在选择性保留变量时,我们实际上已经赋予这个变量新的含义了,这一点值得注意。这一点有点像主成分分析(PCA)的哲学,保留的变量其实是一个复合含义的变量(虽然表明上没有做成分映射、就只是单纯保留了这个变量)。比如,上述 model_A。仅保留了月收入和当地经济水平这两个变量,但是此时对于月收入的系数(w1=24)的解读,应该是:由月收入和存款构成新的变量(我们称之为“个人经济能力”),该变量采用的数据暂时仍然是月收入的数据,该变量带来的效应可以用 w1来衡量的。
我们常说,变量的系数代表着变量的重要性或者贡献。但其实这个说法是有问题的。第一,变量的系数会受到数据方差和尺度的影响,不同方差和尺度的变量,比较其系数大小是不公平的。第二,变量的系数并非就反应了这个变量的真实意义(存在共线性时,其代表的是共线性变量群体的综合意义)。
基于此,我们需要更好的办法去评估各个变量的重要性。在线性回归中,我们可以评估各个变量的 贡献,在 Logistic 回归中我们可以使用似然比检验中的卡方值(或Wald检验近似替代的卡方值,Wald检验的卡方值就等于“系数/系数标准差”。Frank Harrell 教授很推荐使用Wald检验的卡方值来表示变量的重要性。不过个人对Wald检验的卡方值仍然持保守态度)。
进行多变量建模,我们一般会先对变量进行标准化处理(normalization,先中心化再尺度化),这样应该也是可以让各个变量在比较系数时变得公平。此外,标准化处理还有个好处,就是可以加快梯度下降的效率(当各个变量方差差别较大时,各个变量对应的系数的收敛速度差别很大,在CNN训练时也有这个问题,可以采用不同的学习率对各个参数更新迭代,也可以采用标准化的策略)。大概,BatchNormalization有助于训练深度模型,是有这个原因在里面的吧。
更广泛的场景
实际建模中,情况要比刚刚的讨论复杂很多,我们甚至不考虑“因果关系”,甚至试图建立“表型与表型之间关系”的模型,这将很可能引入更多的共线性变量!典型的案例是代谢组学研究,比如探索代谢物与疾病疗效之间的关系(代谢物是表型、疗效也是表型)的问题中,因变量(各个代谢物)之间存在高度的共线性。
因此,我们甚至会发现,共线性的情况变得更加普遍了。我们可以找到很多存在线性关系的特征,这就使得建模更加费劲了。当然,如果没有“因果关系”,建模时也就不那么关注系数的解释意义了(机器学习的黑箱也是如此,各个变量的解释意义被忽视)。那么,既然如此,参数是否收敛也就变得不那么重要,只要预测能力强且泛化能力强(外推性好),那就行啦。具体参数是啥不重要了,当作“黑箱模型”啦。
规律的简单性与复杂性
规律(模型)是简单的。我们可以利用少量关键的信息建立模型,能保证模型相对稳定。因为使用的特征是极其关键的特征,甚至是整个研究群体的普遍特征(比如模拟情景中的“当地经济水平与消费水平存在普遍的相关规律”),所以模型能保证稳定性、广泛适用性。
规律(模型)是复杂的。我们常常对简单的模型表示不满足(总是希望追求完美),因为预测结果相对粗糙,不够精准,我们希望能更精准地实现预测。那么就需要找出更多有用的信息,加入更多的特征进行建模。理想状态下,当我们找到所有有用的信息,建立因果作用网络模型,那么预测能力可以接近完美。但是我们找到的规律总是不全面的,由于规律的不全面,导致某些规律只适用于部分亚群体。尤其是存在共线性关系时,这将使得建立的模型变得不可靠(我们很难反推出各个共线性变量的真实系数);这时大家往往宁愿舍弃共线性的变量,来谋得模型的稳定。但是,如果我们能够挖掘到更多有用的信息(比如建立更复杂的理论或者加入更多的先验知识,推导出各个共线性变量的真实系数,甚至建立各种非线性关系、网络关系等),有可能可以模拟出真实的规律。
不同的规律,复杂性是不同的。有的规律本身就很简单,那么就很容易模拟得很接近真实(比如根据身高体重来预测合适的衣服尺寸)。而有的规律本身就很复杂(比如预测任意一个人得癌症的风险),则模型是复杂的(当然我们常常会根据少数关键信息建立简单的模型)。
标签:共线性,系数,系列,变量,故事,模型,保留,建模 来源: https://blog.csdn.net/fjsd155/article/details/94852770