在构建回归模型时,一个基本假设是自变量之间不应相互关联。这种独立性对于分离每个变量对目标变量的独立影响至关重要,正如回归系数所指示的那样。当变量之间存在相关性时,就会出现多重共线性问题,这使得难以区分它们对目标变量的各自影响。
为什么多重共线性是个问题?
多重共线性会导致以下两个主要问题:首先,它会生成估计系数的高方差,因此,与这些相关解释变量对应的系数估计值将无法准确反映实际情况。它们可能对模型中的微小变化非常敏感。其次,每个单独斜率的t比率可能会受到影响,导致系数不显著。即使模型的调整R平方值很好,整体F检验统计量也很显著,但一些个别系数在统计上不显著,这可能是多重共线性存在的迹象,因为多重共线性影响系数及其对应的p值,但不会影响拟合优度统计量或模型的整体显著性。
如何测量多重共线性?
使用一个简单的测试,即VIF测试,来评估回归模型中的多重共线性。方差膨胀因子(VIF)识别预测变量之间的相关性强度。可能会思考为什么需要使用VIF而不是简单地使用所有预测变量之间的成对相关性。然而,即使有五个预测变量,每对之间的成对相关性并不特别高,仍然有可能三个预测变量共同解释第四个预测变量的大部分方差。
VIF公式
VIF = 1 / (1 - Rj^2)
这里的Rj^2是单个预测变量相对于所有其他预测变量的模型的R平方值。下标j表示预测变量,每个预测变量都有一个VIF。更准确地说,VIF使用多元回归模型来计算多重共线性的程度。假设有四个预测变量——X1、X2、X3和X4。因此,要计算VIF,所有独立变量将轮流成为因变量。每个模型将产生一个R平方值,指示其他预测变量集解释的单个预测变量方差的百分比。
什么是方差膨胀因子?
“方差膨胀因子”(VIF)表示预测变量之间的相关性如何膨胀方差。例如,VIF为10意味着现有的多重共线性使系数方差比没有多重共线性的模型膨胀了十倍。VIF评估系数估计的精度,影响置信区间的宽度。较低的VIF值更可取;1到5之间的值表明相关性是可管理的,而超过5的值则表明严重的多重共线性。行业标准通常建议将VIF保持在5以下,尽管一些文献认为VIF大于10是严重的,需要在决定纠正措施时进行判断。
如何在模型中修复多重共线性?
潜在的解决方案包括以下几点:简单地删除一些相关的预测变量。从实际角度来看,没有必要在模型中保留两个非常相似的预测变量。因此,VIF也被广泛用作变量选择标准,当有很多预测变量可供选择时。可以尝试通过从每个观测值中减去它们的均值来标准化预测变量。可以直接在模型中使用这些标准化变量。标准化变量的优点是系数继续表示在给定1单位变化的预测变量下,因变量的平均变化。
# 假设X是预测变量,Y是目标变量
# 标准化预测变量的R代码
X_standardized <- scale(X)
# 标准化预测变量的Python代码
X_standardized = (X - X.mean()) / X.std()
进行一些线性变换,例如添加/减去两个预测变量以创建一个新的定制预测变量。作为前两点的延伸,另一种非常流行的技术是执行主成分分析(PCA)。当想要减少数据中的变量数量,但不确定要删除哪个变量时,会使用PCA。它是一种变换,它以一种只保留最有信息量的部分的方式组合现有的预测变量。
# 执行PCA的R代码
pca_result <- prcomp(X_standardized, scale. = TRUE)
# 执行PCA的Python代码
from sklearn.decomposition import PCA
pca = PCA(n_components='mle')
pca_result = pca.fit_transform(X_standardized)
然后,它创建了新的变量,称为主成分,这些主成分是不相关的。因此,如果有10维数据,PCA变换将给10个主成分,并将最大可能的信息压缩在第一个成分中,然后是第二个成分中剩余的最大信息,依此类推。这种方法的主要限制是结果的可解释性,因为原始预测变量失去了它们的身份,并且有可能丢失信息。归根结底,这是准确性和可解释性之间的权衡。
如何计算VIF(R和Python代码)?
使用了Kaggle上的房价数据的一个子集。这个数据集中的因变量/目标变量是“SalePrice”。实际数据集中大约有80个预测变量(包括定量和定性)。为了简单起见,根据直觉选择了10个预测变量,认为它们将是房价的合适预测变量。请注意,没有对定性变量进行任何处理,例如,为定性变量创建虚拟变量。这个例子只是为了表示目的。
# 计算R中VIF的代码
library(car)
vif_result <- vif(linear_model)
# 计算Python中VIF的代码
from statsmodels.stats.outliers_influence import variance_inflation_factor
vif_result = [variance_inflation_factor(X, i) for i in range(X.shape[1])]
print(vif_result)
如所见,大多数预测变量的VIF <= 5。