一、概要
在机器学习中,多重共线性在一定程度上是不影响模型的预测能力,但是肯定会影响模型的可解释性。尤其是在获取构建模型时的特征重要性(或者对特征进行排名)时,多重共线性会严重影响其解释性。
二、方差膨胀因子
方差膨胀因子(Variance Inflation Factor,以下简称VIF),是指解释变量之间存在多重共线性时的方差与不存在多重共线性时的方差之比。
上图公式可以看出在方差膨胀因子的检测中:
每个自变量都会有一个膨胀因子值 ,最后根据值的大小来选择是否删减
- 听起来可能有点绕,这里举一下实例(用 “ 面积、卧室数量和浴室数量 ” 作为自变量来预测房价,在进行自变量的方差膨胀因子的检测时,面积、卧室数和浴室数轮流做单独的因变量,剩下的两个变量作为自变量,来看看这三个自变量中那个变量对其余两个变量的解释性高)
- 越大,如已经到了 0.9,那分母就很小, 的值就等于 10,即表示这个自变量已经同时解释了另外的
某个或多个自变量
,存在多元共线性,可以考虑删除一些自变量。 - VIF越大,显示共线性越严重。经验判断方法表明:当0<VIF<10,不存在多重共线性;当10≤VIF<100,存在较强的多重共线性;当VIF≥100,存在严重多重共线性。
三、实现
3.1 基于定义创建VIF函数
def vif(df, col_i):
from statsmodels.formula.api import ols
cols = list(df.columns)
cols.remove(col_i)
cols_noti = cols
formula = col_i + '~' + '+'.join(cols_noti)
r2 = ols(formula, df).fit().rsquared
return 1.0 / (1.0 - r2)
for i in data.columns:
print(i, "\t", vif(df=data, col_i=i))
3.2 基于内建函数
def checkVIF_new(df):
from statsmodels.stats.outliers_influence import variance_inflation_factor
# 默认情况下不会添加截距,使得获得的VIF值偏大;
# 因此,在数据框中再增加一列,代表一个常数(使用常数1)。这将是方程式的截距项。
df['c'] = 1 #
name = df.columns
x = np.matrix(df)
VIF_list = [variance_inflation_factor(x,i) for i in range(x.shape[1])]
VIF = pd.DataFrame({'feature':name,"VIF":VIF_list})
VIF = VIF.drop('c',axis = 0)
max_VIF = max(VIF_list)
print(max_VIF)
return VIF