多重共線性的定義與影響
多重共線性(Multicollinearity)是指線性回歸模型中的解釋變量之間由于存在精確相關關系或高度相關關系而使模型估計失真或難以估計準確。
根據定義和影響程度,可以將多重共線性分為極端共線性和一般共線性。極端共線性一般是指變量間有準確的相關關系,例如x1=x2+1,x3=3x2x_1= x_2+ 1,x_3= 3x_2x1?=x2?+1,x3?=3x2?等,一般共線性則是指自變量高度相關。
多重共線性對模型的影響
光看定義比較抽象,所以下面我們結合多元線性回歸的原理具體說明一下什么是多重共線性以及其對線性模型的影響。
在多元線性回歸中,我們使用多個自變量來預測因變量,其方程可以表示為:
y=w0+w1x1+w2x2+?+wnxny =w_0 + w_1x_1 + w_2x_2 + \cdots + w_nx_ny=w0?+w1?x1?+w2?x2?+?+wn?xn?
其中:
x1,x2,…,xnx_1, x_2, …, x_nx1?,x2?,…,xn? 表示不同的自變量,w1,w2,…,wnw_1, w_2, …, w_nw1?,w2?,…,wn? 表示各個自變量對應的回歸系數。
對模型參數的影響
現在假設有這樣一個多元線性回歸方程模型:
y=10+2x1+5x2y = 10 + 2x_1 + 5x_2y=10+2x1?+5x2?
假設 x1x_1x1?和 x2x_2x2? 之間存在強相關性,我們可以將它們的關系表示為:
x1=x2+1x_1= x_2+ 1x1?=x2?+1
那么,原始方程可以轉化為以下幾種形式:
y=12+7x2y=5+7x1y=7.5+4.5x1+2.5x2?y = 12 + 7x_2 \\ y = 5 + 7x_1\\ y = 7.5 + 4.5x_1 + 2.5x_2 \\ \cdots y=12+7x2?y=5+7x1?y=7.5+4.5x1?+2.5x2??
可以發現如果存在多重共線性,可以得到一系列不同回歸系數下自變量的組合,這些回歸模型的回歸系數不同,但得到的預測值yyy完全相同(自變量精確相關,極端共線性)或相差不大(自變量高度相關,一般共線性),此時不同模型下的誤差平方和相同或相差不大,都可能是恰當的模型,所以如果存在多重共線性,會導致模型的截距項(intercept)和系數(coefficients)無法確定,回歸系數可能有很大波動,例如可能由正變負,還可能變為0等等。
對求解過程的影響
在之前的多元回歸原理的推導中我們講解并推導了最小二乘法求解的過程,如果對這一方面不熟悉的可以看一下這篇文章:https://smilecoc.blog.csdn.net/article/details/138210463,在這里我們推導出求解參數的矩陣形式:
w=(XTX)?1XTYw=(X^TX)^{?1}X^TYw=(XTX)?1XTY
可以看到計算公式中需要計算逆矩陣 w=(XTX)?1w=(X^TX)^{?1}w=(XTX)?1,且(XTX)?1=(XTX)?∣XTX∣(X^{T}X)^{-1}=\frac{(X^{T}X)^*}{|X^{T}X|}(XTX)?1=∣XTX∣(XTX)??,當存在共線性時,若
(1)自變量存在精確相關關系,則行列式 ∣XTX∣|X^{T}X|∣XTX∣ 為0,矩陣不可逆,不存在逆矩陣。即此時求不出
的最小二乘估計。
(2)自變量存在高度相關關系,比如 x1≈2x2x_1\approx 2x_2x1?≈2x2?,則行列式 ∣XTX∣|X^{T}X|∣XTX∣ 近似為0,由于處在計算公式的分母上,此時計算得到的回歸系數的偏差會很大。
多重共線性的判斷
那么如何判斷變量之間是否有多重共線性呢?一般可以通過方差膨脹因子(Variance inflation factor,VIF)和容忍度(tolerance,T)來診斷多重共線性,VIF和容忍度兩者互為倒數,兩者的計算公式分別為:
T=1?Ri2VIF=11?Ri2T={1-R_i^2}\\[15pt]VIF=\frac{1}{1-R_i^2}T=1?Ri2?VIF=1?Ri2?1?
這兩個指標中均涉及R方,先來復習一下這個概念:R方是回歸分析中的一個關鍵概念,也稱為決定系數(coefficient of determination),記作R2R^2R2。R2R^2R2用于評估回歸模型對數據的擬合優度。例如,R2=0.9R^2= 0.9R2=0.9 意味著目標變量yyy中90%的變化可以由模型中的自變量解釋。R2R^2R2的具體計算原理和公式在之前的線性回歸系列文章中也有說明過,感興趣的可以查看。
VIF如何判斷出多重共線性呢?VIF首先為每個自變量擬合一個線性回歸模型,使用其余的自變量作為預測變量。
x1=α1x2+α2x3+…+αn?1xnx2=θ1x1+θ2x3+…+θn?1xn?xn=δ1x1+δ2x2+…+δn?1xn?1x_1 = \alpha_1 x_2 + \alpha_2x_3 + … + \alpha_{n-1}x_n\\ x_2 = \theta_1 x_1 + \theta_2x_3 + … + \theta_{n-1}x_n \\ \cdots \\ x_n = \delta_1 x_1 + \delta_2x_2 + … + \delta_{n-1}x_{n-1} x1?=α1?x2?+α2?x3?+…+αn?1?xn?x2?=θ1?x1?+θ2?x3?+…+θn?1?xn??xn?=δ1?x1?+δ2?x2?+…+δn?1?xn?1?
之后對于每個線性回歸模型計算決定系數R2R^2R2。每個自變量,每個回歸方程都可以計算出對應的R2R^2R2值(記為Ri2R_i^2Ri2?),表示其他自變量能夠解釋該自變量變變化的程度。使用上面的VIF計算公式即可計算出每個自變量對應的VIF值。
一般地,當VIF的最大值>10(Ri2>0.9R_i^2 > 0.9Ri2?>0.9)時,則認為有嚴重的共線性,建議處理,如果5≤VIF<10(0.8≤Ri2<0.9)5 ≤ VIF < 10(0.8 ≤R_i^2 < 0.9)5≤VIF<10(0.8≤Ri2?<0.9)時,則認為有輕度共線性,需關注。
Python計算VIF
Python計算VIF的方法有:使用statsmodels庫、使用pandas和numpy庫手動計算,這里使用statsmodels庫,它提供了一個名為variance_inflation_factor()的函數來計算VIF
import pandas as pd
from statsmodels.stats.outliers_influence import variance_inflation_factor# 示例數據集
data = {'X1': [1, 2, 3, 4, 5],
'X2': [2, 4, 5, 8, 9],
'X3': [29, 3, 7, 18, 6],
'Y': [1, 2, 3, 4, 5]
}df = pd.DataFrame(data)#在計算VIF之前,我們需要移除目標變量,只保留自變量
X = df[['X1', 'X2', 'X3']]
vif_data = pd.DataFrame()
vif_data['Feature'] = X.columns
vif_data['VIF'] = [variance_inflation_factor(X.values, i) for i in range(len(X.columns))]
print(vif_data)
運行代碼后即可得到每一個自變量的VIF值。
Feature VIF
0 X1 256.918238
1 X2 266.626208
2 X3 1.835335
從結果可以看出前兩個自變量存在很強的共線性。
如何消除多重共線性
最后來說一下如何消除多重共線性。
進行建模時,首先需要計算兩兩相關系數,將相關系數較高的變量去除。這一步相當于對變量進行一次初篩,注意:這一步只是降維,不保證消除多重共線性,因為 3 個以上變量仍可能“抱團”。
其次在建模中,可以使用嶺回歸,Lasso回歸等正則化收縮回歸系數來減輕多重共線性的影響,并可以刪除系數趨近于0的變量。
最后可以計算VIF值,當VIF值過大的時候就需要對變量進行處理。
除了直接刪除變量外,如果有的時候不好刪除變量,可以使用PCA等降維方法保留大部分的變量信息。
參考文章:
https://zhuanlan.zhihu.com/p/355241680
https://avoid.overfit.cn/post/512ff1c71eb14f758ff82a94baf06f4c