使用Python检测和处理回归中的多重共线性问题

1. 多重共线性问题概述

在回归分析中,多重共线性问题(multicollinearity)是指在多元回归模型中,解释变量之间存在较高的相关性,线性回归模型的能力会受到影响,使得对线性回归系数的解释和预测变得不确定和不可靠。

多重共线性问题的表现有哪些?

在多重共线性的情况下,线性回归模型可能会出现以下表现:

系数估计值的标准误差变大

t值变小,p值变大

系数的符号可能与预期相反

模型的稳定性和可靠性减弱

2. 如何检测多重共线性问题?

可以采用如下方法检测多重共线性问题:

2.1 方差膨胀因子法

该方法是通过计算每个自变量的方差膨胀因子来检测多重共线性的存在。方差膨胀因子(Variance Inflation Factor, VIF)值越大,代表该自变量的共线性越强,通常将VIF值大于10的自变量视为存在多重共线性问题。

# 方差膨胀因子的计算

from statsmodels.stats.outliers_influence import variance_inflation_factor

def vif_cal(input_data, dependent_col):

x_vars=input_data.drop([dependent_col], axis=1)

xvar_names=x_vars.columns

for i in range(0,xvar_names.shape[0]):

y=x_vars[xvar_names[i]]

x=x_vars[xvar_names.drop(xvar_names[i])]

rsq=smf.OLS(y,x).fit().rsquared

vif=round(1/(1-rsq),2)

print (xvar_names[i], " VIF = " , vif)

2.2 相关系数矩阵法

该方法是通过计算自变量之间的相关系数矩阵,若矩阵中存在较高的相关系数,则表明自变量之间存在共线性问题。

# 相关系数矩阵的计算

import pandas as pd

import numpy as np

data=pd.read_csv('data.csv')

corr_matrix=data.corr()

corr_matrix

3. 如何处理多重共线性问题?

针对多重共线性问题,有哪些常用的解决方法?

删除共线性较强的自变量

对共线性变量进行主成分分析(Principal Component Analysis, PCA)降维处理

使用岭回归(Ridge Regression)或lasso算法

3.1 删除共线性较强的自变量

删除哪些变量?

可以基于变量的VIF值或者相关系数矩阵的解释选择性剔除,删除相关系数大于0.8或者VIF大于5的变量。

# 删除VIF值大于5的变量

from statsmodels.stats.outliers_influence import variance_inflation_factor

def calc_vif(X):

# 计算VIF

vif = pd.DataFrame()

vif["variables"] = X.columns

vif["VIF"] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]

return(vif)

while True:

vif = calc_vif(X_train)

if vif['VIF'].max() > 5:

remove_index = vif[vif['VIF'] == vif['VIF'].max()].index[0]

X_train.drop(X_train.columns[remove_index], axis=1, inplace=True)

else:

break

print('剩余的自变量为:', X_train.columns)

3.2 对共线性变量进行主成分分析

主成分分析(PCA)是一种线性降维方法,其能够将多个高度相关的变量压缩为几个线性无关的变量。

# 使用sklearn的PCA方法实现 PCA算法

from sklearn.decomposition import PCA

pca = PCA(n_components=3)

pca.fit(X_train)

# 转换数据集

X_transformed = pd.DataFrame(pca.transform(X_train), columns=['p1', 'p2', 'p3'])

3.3 使用岭回归或lasso算法

当线性回归存在多重共线性问题时,采用岭回归或lasso算法可以有助于改善模型表现。

# 使用sklearn的岭回归算法

from sklearn.linear_model import Ridge

alpha_list = [0.01, 0.1, 1, 10, 100]

for alpha in alpha_list:

ridge_model = Ridge(alpha=alpha)

ridge_model.fit(X_train, y_train)

print('alpha=', alpha, ', score=', ridge_model.score(X_test, y_test))

4. 实战案例

以下为一个基于sklearn中的糖尿病数据集的多重共线性检测和处理案例。

# 导入数据集

from sklearn.datasets import load_diabetes

X, y = load_diabetes(return_X_y=True)

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

# 模型训练与预测

reg = LinearRegression().fit(X_train, y_train)

print(reg.score(X_test, y_test))

# 方差膨胀因子法检测多重共线性

vif = calc_vif(pd.DataFrame(X_train, columns=load_diabetes().feature_names))

print(vif)

# 删除VIF值大于5的变量

while True:

vif = calc_vif(X_train)

if vif['VIF'].max() > 5:

remove_index = vif[vif['VIF'] == vif['VIF'].max()].index[0]

X_train.drop(X_train.columns[remove_index], axis=1, inplace=True)

else:

break

# PCA降维

pca = PCA(n_components=3)

pca.fit(X_train)

X_train = pd.DataFrame(pca.transform(X_train), columns=['p1', 'p2', 'p3'])

X_test = pd.DataFrame(pca.transform(X_test), columns=['p1', 'p2', 'p3'])

# 模型训练与预测

reg = LinearRegression().fit(X_train, y_train)

print(reg.score(X_test, y_test))

# 岭回归

alpha_list = [0.01, 0.1, 1, 10, 100]

for alpha in alpha_list:

ridge_model = Ridge(alpha=alpha)

ridge_model.fit(X_train, y_train)

print('alpha=', alpha, ', score=', ridge_model.score(X_test, y_test))

总结

多重共线性是回归分析中常见的问题,若不正确处理,会影响模型的表现和解释。常见的多重共线性检测方法有方差膨胀因子法和相关系数矩阵法,处理多重共线性问题可采用删除共线性较强的自变量、对共线性变量进行主成分分析或使用岭回归或lasso算法等方法。

需要注意的问题:

处理多重共线性问题后,需要再次评估模型表现,以保证模型的稳定性和可靠性。

多重共线性可能不会影响预测准确率,但会影响参数的解释,因此解决多重共线性问题的意义在于提高解释性。

后端开发标签