方差膨胀因子(VIF):解决回归分析中的多重共线性问题

在回归分析中,多重共线性发生在自变量彼此相关的情况下。这使得确定每个预测变量对因变量的独特影响变得困难。结果是,您会得到膨胀的标准误差,从而影响系数的显著性。

方差膨胀因子(VIF)是检测多重共线性的重要工具,提供了超出简单两两相关性的见解。本教程解释了VIF的工作原理,如何计算和解释它,以及如果发现高VIF值时应该怎么做。这些步骤将帮助数据专业人士和数据科学家提高模型的稳定性。

尽管VIF是一个重要的诊断工具,并且值得学习,但它只代表我们Python机器学习科学家职业发展道路中的一小部分,因此立即报名吧。

什么是方差膨胀因子(VIF)?

由统计学家卡思伯特·丹尼尔开发,VIF是回归分析中广泛使用的诊断工具,用于检测多重共线性,这会影响回归系数的稳定性和可解释性。从技术上讲,VIF通过量化回归系数的方差由于预测变量之间的相关性而膨胀的程度来工作。

所有这些都很重要,因为这些相关性使得难以分离每个预测变量对目标变量的独特影响,从而导致模型估计不够可靠。我还应该说,为了真正讲述正确的故事,VIF必须对模型中的每个预测变量进行计算。

方差膨胀因子公式

对于预测变量X的方差膨胀因子(VIF)计算如下:

其中:

  • R2是在将X回归到所有其他预测变量时获得的决定系数。

逐步计算

计算VIF是一个三步过程。第一步是为每个预测变量针对所有其他预测变量拟合单独的线性回归模型。第二步是获得每个模型的R2值。最后一步是使用上述公式计算VIF。

VIF值的解释

这里是如何解释VIF值以理解多重共线性水平:

  • VIF = 1:这表示没有多重共线性。预测变量与其他预测变量不相关,因此不会增加标准误差或影响模型的稳定性。
  • VIF介于1和5之间:这表明中度多重共线性。与其他预测变量存在一定的相关性,但通常不严重。然而,值得关注这些预测变量,看看是否多重共线性会成为问题,特别是如果其他VIF值很高。
  • VIF > 5:存在高度多重共线性。预测变量的标准误差可能明显膨胀,使其系数不太可靠。考虑采取措施减少多重共线性,比如移除或合并相关的预测变量。
  • VIF > 10:这表明存在严重的多重共线性。预测变量的标准误差被高度膨胀,其系数估计可能不稳定。通常需要采取纠正措施,例如移除该预测变量或使用正则化技术。

例如,如果一个预测变量的VIF为10,则表示该预测变量系数的方差是如果没有多重共线性时的10倍。

VIF如何解释回归中的多重共线性

多重共线性会导致标准误差增加,使得评估单个预测变量的显著性变得更加困难。这是因为共线性变量携带类似的信息,难以区分它们对因变量的具体影响。

虽然多重共线性不一定会损害模型的预测能力,但确实降低了系数的可靠性和清晰度。当我们想要理解每个预测变量的个体影响时,这一点尤为令人困扰。

方差膨胀因子(VIF)作为一种精确的诊断指标,用于识别多重共线性。与关于相关性的一般观察不同,VIF隔离了所有预测变量对每个变量的综合影响,突出了可能不会从成对相关性中明显看出的交互作用。

Python和R中的方差膨胀因子

为了使这一点可操作,让我们通过一个独特的数据集在 Python 和 R 中进行示例。我们将使用自动化包计算 VIF,并使用 VIF 公式来建立直觉。为了有良好的实践,我故意创建了一个数据集,我们将在其中发现 尽管任何两个变量之间没有非常高的成对相关性,但我们的一个变量却有很高的 VIF 值——所以我认为这是一个引人注目的例子。让我们首先概述一下我们将使用的数据集。

数据集概述:

这个虚构的数据集代表了一个零售巨头在 1,000 家商店中进行的调查结果。每家商店的顾客被要求在 -5 到 +5 的范围内对他们的购物体验的各个方面进行评分,其中 -5 表示非常负面的体验,+5 表示非常正面的体验。每家商店顾客评分的平均值是基于四个关键参数得出的:

  • 环境: 顾客对商店环境的感知,如清洁度、布局、照明和整体氛围。

  • 客户服务: 对店员提供的服务的评价,包括乐于助人、友好以及响应顾客需求的能力。

  • 优惠:店铺推出的促销优惠、折扣和交易对客户的可用性评分。

  • Product_range:评估商店中可用产品的种类和质量。

目标变量Performance衡量每家商店的整体表现。但从VIF的角度来看,这并不相关。 您可以在这里下载数据集。

Python中的方差膨胀因子

我们将使用Python包计算VIF值。第一步是加载数据集和所需的库。

from sklearn.linear_model import LinearRegression from sklearn.metrics import r2_score import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from statsmodels.stats.outliers_influence import variance_inflation_factor from statsmodels.tools.tools import add_constant datacamp_retail_data = pd.read_csv(' vif_data.csv') datacamp_retail_data.head()

上面的代码将加载数据并显示前五条记录。

作为下一步,我们可以运行相关矩阵以检查成对相关性。

以下代码选择四列并将它们存储在名为 correl_data 的新 DataFrame 中。然后使用 .corr() 函数计算成对相关性矩阵。结果存储在对象 corr_matrix 中,它是一个显示所选列每对之间相关系数的表。

然后使用 Seaborn 的 heatmap() 函数对矩阵进行可视化,将每个相关系数显示为一个色彩编码的单元格,其中蓝色表示负相关,红色表示正相关,基于 coolwarm 颜色映射。

correl_data = datacamp_retail_data[['Ambience', 'Customer_service', 'Offers', 'Product_range']] # 计算成对相关性矩阵 corr_matrix = correl_data.corr() # 可视化相关性矩阵 plt.figure(figsize=(10, 8)) sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', vmin=-1, vmax=1) plt.title('Pairwise Correlation Matrix') plt.show()

输出:

  变量之间的相关性。图片由作者提供

该图提供了correl_data中变量之间关系的视觉总结。相关系数的取值范围为-1到1,数值越接近1表示强正相关,数值越接近-1表示强负相关,数值接近0表示没有相关性。很明显,在这些变量中没有强烈的成对相关性,没有一个相关系数大于0.6。

接下来的步骤是计算预测变量的VIF值。下面的代码计算数据集中每个预测变量的值,以检查多重共线性。

首先,它通过删除目标列Performance并添加一个截距来定义X。然后,创建一个DataFrame,datacamp_vif_data,用于存储预测变量的名称和它们的VIF值。使用循环,然后使用variance_inflation_factor()函数计算每个预测变量的VIF,其中较高的VIF值表示存在多重共线性。

# 定义预测变量 X = datacamp_retail_data.drop(columns=['Performance']) # 为模型添加一个常数(截距) X = add_constant(X) # 为每个特征计算VIF datacamp_vif_data = pd.DataFrame() datacamp_vif_data['Feature'] = X.columns datacamp_vif_data['VIF'] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])] print(datacamp_vif_data)

输出:

显示VIF值的输出。作者提供的图片

此输出显示了每个预测变量的VIF值,指示数据集中的多重共线性水平。 const 行表示截距项,其VIF接近1,意味着没有多重共线性。 在预测变量中,Product_range 的VIF最高(5.94),这表明需要采取纠正措施。 所有其他预测变量的VIF值均低于3,表明多重共线性水平较低。

使用手动方法计算VIF

另一种方法是通过将每个自变量与其他预测变量进行回归分析来单独计算这些值。

其工作原理是,对于retail_data中的每个特征,将该特征设置为因变量(y),其余特征设置为自变量(X)。 然后拟合线性回归模型以预测 y 使用 X,并使用模型的R平方值使用我们在初始部分讨论过的公式来计算VIF。

随后,每个特征及其对应的VIF值都存储在一个字典(vif_manual)中,然后转换为DataFrame(vif_manual_df)以便显示。

datacamp_retail_data = retail_data.drop(columns=['Performance']) # 手动计算VIF vif_manual = {} for feature in retail_data.columns: # 定义目标变量(当前特征)和预测变量(所有其他特征) y = datacamp_retail_data[feature] X = datacamp_retail_data.drop(columns=[feature]) # 拟合线性回归模型 model = LinearRegression().fit(X, y) # 计算R平方 r_squared = model.score(X, y) # 计算VIF vif = 1 / (1 - r_squared) vif_manual[feature] = vif # 将字典转换为DataFrame以便更好地显示 vif_manual_df = pd.DataFrame(list(vif_manual.items()), columns=['Feature', 'VIF']) print(vif_manual_df)

 输出:

显示VIF值的输出。作者提供图片

输出显示每个特征及其VIF值,有助于识别潜在的多重共线性问题。您可以看到结果与我们之前获得的结果显然相同;因此其解释也将相同,即Product_range变量显示出多重共线性。

R中的方差膨胀因子

在本节中,我们将重复上面Python部分中方差膨胀因子的练习,特别是针对使用R编程语言的开发人员。我们从加载数据集和必要的库开始。

library(tidyverse) library(car) library(corrplot) data <- read.csv('vif_data.csv') str(data)

输出:

下一步是计算成对相关矩阵,并使用热力图进行可视化。cor()corrplot函数帮助我们完成这一任务。

删除目标列 predictors_data <- data[, !(names(data) %in% "Performance")] # 计算相关矩阵 correlation_matrix <- cor(predictors_data) # 绘制相关性热力图 # 加载必要的库 library(ggplot2) library(reshape2) melted_corr_matrix <- melt(correlation_matrix) # 使用ggplot2绘制热力图 ggplot(data = melted_corr_matrix, aes(x = Var1, y = Var2, fill = value)) + geom_tile(color = "white") + scale_fill_gradient2(low = "blue", high = "red", mid = "white", midpoint = 0, limit = c(-1, 1), space = "Lab", name="Correlation") + theme_minimal() + # 清爽风格的最小主题 theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) + labs(x = "", y = "") + # 去除坐标轴标签 geom_text(aes(Var1, Var2, label = round(value, 2)), color = "black", size = 4) + theme(axis.text=element_text(size=15))

输出:

变量之间的相关性。图像由作者提供

从相关性热力图可以明显看出,变量之间没有很强的成对相关性,甚至没有任何相关值大于0.6。接下来,我们将计算VIF值,看看是否有什么异常。以下代码会完成这个任务。

# 拟合回归模型 model <- lm(Performance ~ Ambience + Customer_service + Offers + Product_range, data = data) # 计算VIF vif(model)

输出:

从输出中,我们可以看到,在预测变量中,只有Product_range变量的VIF值大于5,这表明存在高共线性,需要采取纠正措施。

通过手动计算VIF的方法

另一种计算VIF的方法是分别计算每个变量的VIF值,通过将每个自变量回归到其他预测变量中。

下面的代码执行了这一操作,使用sapply()函数对每个预测变量进行操作,其中每个预测变量被设置为线性回归模型中的因变量,而其他预测变量则作为自变量。

然后使用每个模型的R平方值来计算VIF值,公式如下。最终,结果vif_values显示每个预测变量的VIF,有助于识别多重共线性问题。

# 为每个预测变量手动计算VIF predictors <- c("Ambience", "Customer_service", "Offers", "Product_range") vif_values <- sapply(predictors, function(pred) { formula <- as.formula(paste(pred, "~ .")) model <- lm(formula, data = data[, predictors]) 1 / (1 - summary(model)$r.squared) }) print(vif_values)

输出:

我们得到相同的结果,很明显,具有高于5的VIF值的变量Product_range需要干预。

VIF与相关矩阵和其他方法

回顾一下,以下是检测多重共线性的流行方法:

  • 高VIF值:高VIF值是多重共线性的明显指标。当这些值超过一定阈值时,表明一个预测变量与其他预测变量强相关,这可能影响模型的稳定性、可靠性和性能。
  • 相关矩阵:通过检查相关矩阵,您可以看到预测变量之间的成对相关性。高成对相关性表明这些特定预测变量之间存在多重共线性。然而,这种方法只能检测两个变量之间的直接线性关系,可能会忽略涉及多个变量之间更复杂相互作用的多重共线性。
  • 系数变化:如果在模型中添加或删除其他变量时,预测变量的系数发生显著变化,这可能是多重共线性的迹象。这种波动表明某些预测变量可能共享相同的信息,使得更难以确定每个变量对结果的独特影响。

在所有这些方法中,VIF特别有用,因为它可以检测到多重共线性,即使成对相关性很低,就像我们自己的例子中看到的那样。这使得VIF成为一个更全面的工具。

解决高VIF值的其他想法

如果VIF值表明存在高度多重共线性,并且您不仅仅想删除变量,还有一些其他更高级的策略可以缓解多重共线性:

  1. 特征选择:删除高度相关的预测变量之一,并重新计算VIF,以查看是否有助于简化模型并提高稳定性。
  2. 主成分分析(PCA):使用PCA将您的预测变量合并为一组较小的不相关成分。这将原始变量转换为新的、独立的、不相关的变量,捕捉大部分数据变化,有助于解决多重共线性问题,同时不会丢失宝贵信息。
  3. 正则化技术:应用岭回归或套索回归,向模型添加惩罚项。这些技术有助于通过缩小相关变量的影响来减少多重共线性,使模型更稳定可靠。

结论

了解如何使用VIF是识别和解决多重共线性的关键,可以提高回归模型的准确性和清晰度。定期检查VIF值,并在需要时应用纠正措施,有助于数据专业人士和分析师构建可信赖的模型。这种方法确保每个预测变量的效果清晰,使得更容易从模型中得出可靠的结论,并基于结果做出更好的决策。参加我们的Python中的机器学习科学家职业培训,真正了解如何构建模型并使用它们。此外,完成该计划将在简历上增光添彩。

此外,为了进一步学习,请考虑查阅DataCamp博客和教程部分的以下资源:

Source:
https://www.datacamp.com/tutorial/variance-inflation-factor