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

在回歸分析中,多重共線性發生於自變數彼此相關時。這使得難以確定每個預測變數對因變數的獨特影響。結果是標準誤差增加,進而影響係數的顯著性。

方差膨脹因子(VIF)是檢測多重共線性的重要工具,提供超越簡單成對相關的見解。本教程解釋了VIF的工作原理,如何計算和解釋它,以及當發現高VIF值時應該怎麼做。這些步驟將幫助您作為數據專業人士和數據科學家來改善模型的穩定性。

雖然VIF是一個重要的診斷工具,學習它是很值得的,但它僅代表我們Python機器學習科學家職業軌道中您將發展的技能集中的一部分,因此立即註冊。

什麼是方差膨脹因子(VIF)?

由統計學家卡斯伯特·丹尼爾(Cuthbert Daniel)開發,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表示非常正面的經歷。在每家商店的顧客評分的平均值上取了四個關鍵參數:

  • 氛圍:顧客對商店環境的感知,包括清潔度、佈局、燈光和整體氛圍。

  • 客戶服務:對商店工作人員提供的服務進行評分,包括樂於助人、友好和對顧客需求的回應能力。

  • 優惠:店鋪提供給客戶的促銷優惠、折扣和交易的評分。

  • 產品範圍:評估商店中提供的產品種類和質量。

目標變量性能衡量每家商店的整體表現。但從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的新數據框中。然後使用.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)。然後,擬合線性回歸模型以使用X預測y,並使用模型的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)

輸出:

我們得到相同的結果,明顯地變數Product_range 的VIF值超過5,需要干預。

VIF vs. Correlation Matrix and Other Methods

簡而言之,以下是檢測多重共線性的流行方法:

  • 高的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