在回归模型中筛选(多重)共线性

64

我希望这不是一个“问答”问题...以下是内容:

(多)共线性是指回归模型中预测变量之间的相关性非常高。如何“治愈”呢……有时候你不需要“治愈”共线性,因为它并不影响回归模型本身,但会影响各个预测变量的效果解释。

发现共线性的一种方法是将每个预测变量作为因变量,其他预测变量作为自变量,确定R2,如果大于0.9(或0.95),我们可以认为该预测变量是多余的。这是一种“方法”...还有其他方法吗?其中有些方法很耗时,比如从模型中排除预测变量然后观察b系数的变化-它们应该明显不同。

当然,我们必须始终牢记分析的具体背景/目标......有时唯一的解决方法是重新进行研究,但我现在对在回归模型中出现(多)共线性时筛选冗余预测变量的各种方法感兴趣。


5
我很高兴没有人认为这不够"程序员范儿",并且有很多人给这个问题点了赞。对于我们这些"用数据来编程"的人来说,这是一个非常好的问题。 - JD Long
很棒的问题,精彩的答案。阅读收获颇丰 - 谢谢。 - Tal Galili
...而且碰巧我们在R中进行统计。=) 虽然问题标题没有明确说明,但问题标记为r特定...最终,答案最重要。再次感谢这些出色的答案! - aL3xa
真正重要的是StackOverflow中[r]标签社区认为什么是合适的。而这是有史以来评分最高的R语言问题之一。QED - JD Long
1
这个问题似乎与统计实践无关,因此应该迁移到CrossValidated(当时提出问题时还不存在...)。 - Ben Bolker
显示剩余8条评论
5个回答

40

kappa() 函数可以帮助解决问题。以下是一个模拟示例:

> set.seed(42)
> x1 <- rnorm(100)
> x2 <- rnorm(100)
> x3 <- x1 + 2*x2 + rnorm(100)*0.0001    # so x3 approx a linear comb. of x1+x2
> mm12 <- model.matrix(~ x1 + x2)        # normal model, two indep. regressors
> mm123 <- model.matrix(~ x1 + x2 + x3)  # bad model with near collinearity
> kappa(mm12)                            # a 'low' kappa is good
[1] 1.166029
> kappa(mm123)                           # a 'high' kappa indicates trouble
[1] 121530.7

而我们通过使第三个回归器更加共线来进一步推进:

> x4 <- x1 + 2*x2 + rnorm(100)*0.000001  # even more collinear
> mm124 <- model.matrix(~ x1 + x2 + x4)
> kappa(mm124)
[1] 13955982
> x5 <- x1 + 2*x2                        # now x5 is linear comb of x1,x2
> mm125 <- model.matrix(~ x1 + x2 + x5)
> kappa(mm125)
[1] 1.067568e+16
> 

这里使用了一些近似值,请查看help(kappa)了解详细信息。


35

关于条件数方法,补充一下Dirk所说的,一个经验法则是当 CN > 30 时表明存在严重共线性问题。除了条件数方法之外,还有以下方法:

1)协方差矩阵行列式的取值范围为0(完全共线)到1(无共线性)。

# using Dirk's example
> det(cov(mm12[,-1]))
[1] 0.8856818
> det(cov(mm123[,-1]))
[1] 8.916092e-09

2) 利用对角矩阵的行列式是特征值的乘积这一事实 => 存在一个或多个小的特征值表示线性相关

> eigen(cov(mm12[,-1]))$values
[1] 1.0876357 0.8143184

> eigen(cov(mm123[,-1]))$values
[1] 5.388022e+00 9.862794e-01 1.677819e-09

3) 方差膨胀因子(Variance Inflation Factor,简称VIF)的值。对于预测变量i,VIF为1/(1-R_i^2),其中R_i^2是将预测变量i与其余预测变量进行回归得到的R^2值。当至少一个自变量的VIF很大时存在共线性。经验法则是:VIF>10有问题。在使用R进行实现时,请参见这里。我还想评论一下,使用R^2来确定共线性时应与散点图的视觉检查相结合,因为单个异常值可能会“导致”不存在的共线性,或者可能会掩盖存在的共线性。


1
谢谢Giorgos,+2分!非常好的回答! - aL3xa
1
为什么协方差矩阵的行列式会被限制在1以下? - kevinykuo
https://blog.exploratory.io/why-multicollinearity-is-bad-and-how-to-detect-it-in-your-regression-models-e40d782e67e - gd047

19

您可能会喜欢 Vito Ricci 的参考卡片 "R 函数用于回归分析"。 http://cran.r-project.org/doc/contrib/Ricci-refcard-regression.pdf

这份参考卡片简洁地列出了许多与回归分析相关的 R 函数,包括诊断函数。 特别地,它列出了 car 包中可评估多重共线性的 vif 函数。 http://en.wikipedia.org/wiki/Variance_inflation_factor

考虑到多重共线性问题,往往需要评估变量的重要性。如果您也面临此类问题,可以尝试使用 relaimpo 包: http://prof.beuth-hochschule.de/groemping/relaimpo/


1
从技术和算术角度来看,VIF = 1(1 - R^2),其中R^2是我在问题中提到的示例。我忘了提到VIF,所以感谢您在这方面的帮助!“relaimpo”是一个很好的发现! - aL3xa

9
请参阅本书第9.4节: Practical Regression and Anova using R [Faraway 2002]
多重共线性可以通过以下几种方法检测出来:
  1. 检查预测变量的相关矩阵,发现存在大的成对共线关系。

  2. 对所有其他预测变量回归x_i,得到R^2_i。重复以上过程对所有预测变量进行回归,R^2_i接近1时会出现问题——找到有问题的线性组合。

  3. 检查 t(X) %*% X 的特征值,其中X是模型矩阵;小的特征值表示有问题。2-范数条件数可以被证明是矩阵最大非零奇异值与最小非零奇异值之比($\kappa = \sqrt{\lambda_1/\lambda_p}$; 参见?kappa);\kappa >= 30 被认为是较大的。


1
在SO上,仅包含链接的答案已经过时了。 - Ben Bolker

8

由于之前没有提到VIF,因此我会添加我的答案。VIF大于10通常表示预测变量之间存在严重的冗余。VIF指示了如果一个变量与其他变量高度相关,则其系数的方差将增加的倍数。

vif() 可在包cars中获得,并应用于类lm的对象。它返回对象lm()中x1、x2...xn的VIF值。建议排除VIF>10的变量或对VIF>10的变量引入转换。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接