监督学习之线性模型(4)-- 共线性问题

一、什么是多重共线性问题

多重共线性,是值线性模型中的解释变量之间存在较精确相关关系或高度相关关系(一组或多组线性关系),会导致训练出的模型失真。它影响的是那些底层为线性的模型,例如线性回归、逻辑回归、SVM等。在其他算法中,例如决策树和贝叶斯,前者的建模过程是逐步递进,每次拆分只有一个变量参与,这种建模机制含有抗多重共线性干扰的功能;后者干脆假定变量之间是相互独立的,因此从表面上看,也没有多重共线性的问题。在构造预测模型时如何处理多重共线性是一个比较微妙的议题。既不能不加控制,又不能一刀切,认为凡是多重共线性就应该消除。

二、如何诊断

1、相关系数矩阵诊断法

研究变量的两两相关分析,如果自变量间的二元相关系数值很大,则认为存在多重共线性。但无确定的标准判断相关系数的大小与共线性的关系。有时,相关系数值不大,也不能排除多重共线性的可能。

2、方差膨胀因子(the variance inflation factor,VIF)诊断法

方差膨胀因子表达式为:VIFi=1/(1-Ri2)。其中Ri为自变量xi对其余自变量作回归分析的复相关系数。当VIFi很大时,表明自变量间存在多重共线性。
一般来说当VIFi>10时,说明自变量xi与其余自变量之间存在严重的多重共线关系,这种多重共线性可能会过度地影响最小二乘估计值.

2、容忍值(Tolerance,简记为Tol)诊断法

容忍值实际上是VIF的倒数,即Tol=1/VIF,其取值在0~1之间,Tol越接近1,说明自变量间的共线性越弱。在应用时一般先预先指定一个Tol值,容忍值小于指定值的变量不能进入方程,从而保证进入方程的变量的相关系数矩阵为非奇异阵,计算结果具有稳定性。

三、如何消除

1、降维

主成分分析法作为多元统计分析的一种常用方法在处理多变量问题时具有其一定的优越性,其降维的优势是明显的,主成分回归方法对于一般的多重共线性问题还是适用的,尤其是对共线性较强的变量之间。当采取主成分提取了新的变量后,往往这些变量间的组内差异小而组间差异大,起到了消除共线性的问题。

2、逐步回归法

逐步回归(Stepwise Regression)是一种常用的消除多重共线性、选取”最优”回归方程的方法。其做法是将逐个引入自变量,引入的条件是该自变量经F检验是显著的,每引入一个自变量后,对已选入的变量进行逐个检验,如果原来引入的变量由于后面变量的引入而变得不再显著,那么就将其剔除。引入一个变量或从回归方程中剔除一个变量,为逐步回归的一步,每一步都要进行F 检验,以确保每次引入新变量之前回归方程中只包含显著的变量。这个过程反复进行,直到既没有不显著的自变量选入回归方程,也没有显著自变量从回归方程中剔除为止。

3、正则化

简单的说,就是在原有的损失函数后面加一个正则化项,这个正则化项可以避免模型参数过于发散无法收敛,也可以避免过拟合的现象。下面介绍的两种正则化方法,分别用的是两种不同的正则化项:
L1正则化:所有参数的绝对值之和,称为Lasso回归;
L2正则化:所有参数的平方和,称为岭回归。
L1、L2正则化结合:称为弹性网络。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from sklearn.linear_model import  LassoCV, RidgeCV, ElasticNetCV
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
import warnings; warnings.filterwarnings(action='ignore')

boston = load_boston()
X = boston.data
y = boston.target

# 把数据分为训练数据集和测试数据集(20%数据作为测试数据集)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=3)

#========================================================
# L1正则化: Lasso回归
#========================================================

model1 = LassoCV(alphas=(1.0, 0.1, 0.01, 0.001, 0.005, 0.0025, 0.001, 0.00025), normalize=True)
model1.fit(X_train, y_train)

train_score = model1.score(X_train, y_train) # 模型对训练样本得准确性
test_score = model1.score(X_test, y_test) # 模型对测试集的准确性
print('Lasso回归:')
print(train_score)
print(test_score)

#========================================================
# L2正则化: Ridge回归
#========================================================

model2 = RidgeCV(alphas=[1.0, 0.5, 0.1, 0.05, 0.01, 0.005, 0.001, 0.0005, 0.0001], normalize=True)
model2.fit(X_train, y_train)

train_score = model2.score(X_train, y_train) # 模型对训练样本得准确性
test_score = model2.score(X_test, y_test) # 模型对测试集的准确性
print('Ridge回归:')
print(train_score)
print(test_score)

#========================================================
# L1、L2结合: ElasticNet回归
#========================================================

model3 = ElasticNetCV(alphas=(0.1, 0.01, 0.005, 0.0025, 0.0001), l1_ratio=(0.1, 0.25, 0.5, 0.75, 0.9), normalize=True)
model3.fit(X_train, y_train)

train_score = model3.score(X_train, y_train) # 模型对训练样本得准确性
test_score = model3.score(X_test, y_test) # 模型对测试集的准确性
print('ElasticNet回归:')
print(train_score)
print(test_score)

[拓展阅读)
https://www.cnblogs.com/Belter/p/8536939.html

0%