在多元回归分析中已经介绍过,当自变量之间具有显著的相关关系时,可能会存在多重共线性。严重的多重共线性会大大影响模型的预测结果。除了可以用容忍度与方差扩大因子来度量模型的多重共线性以外,还可以用条件数来度量,常用κ表示,条件数可以定义为:
,
其中,λ为的特征值(X代表自变量矩阵)。一般认为,当κ>15时,有共线性问题,当κ>30时,说明有严重的共线性问题。
本文拟采用R中lars包自带的diabetes数据集,该数据描述了一些关于糖尿病的血液等化验指标。通过str()函数先看一下该数据的结构。
> str(diabetes) 'data.frame': 442 obs. of 3 variables: $ x : AsIs [1:442, 1:10] 0.03808 -0.00188 0.0853 -0.08906 0.00538 ... ..- attr(*, "dimnames")=List of 2 .. ..$ : NULL .. ..$ : chr "age" "sex" "bmi" "map" ... $ y : num 151 75 141 206 135 97 138 63 110 310 ... $ x2: AsIs [1:442, 1:64] 0.03808 -0.00188 0.0853 -0.08906 0.00538 ... ..- attr(*, ".Names")= chr "age" "age" "age" "age" ... ..- attr(*, "dimnames")=List of 2 .. ..$ : chr "1" "2" "3" "4" ... .. ..$ : chr "age" "sex" "bmi" "map" ...
上说结果说明,diabetes数据为一个数据框,共有3列,442行。第一列是一个442X10数据框,是标准化后的自变量,第二列是因变量,第三列是442X64数据框,包括前者及一些交互作用。
VIF的值可以用软件包car中的vif()函数计算,条件数κ可以用R内置函数kappa()计算。
> write.csv(diabetes,"diabetes.csv",row.names = FALSE) > diabetes.test<-read.csv("diabetes.csv") > kappa(diabetes.test[,12:75]) [1] 11427.09 > vif.dia<-vif(lm(y~.,data = diabetes.test[,11:75])) > sort(vif.dia,decreasing = TRUE)[1:5] x2.tc x2.ldl x2.hdl x2.ltg x2.tc.ltg 1295001.21 1000312.11 180836.83 139965.06 61177.87
不管是从κ的值还是从VIF的值来看,该模型都存在严重的多重共线性。
1 岭回归
假定自变量数据矩阵为nxp矩阵,通常最小二乘法(ordinary least squares,或ols)通过使残差平方和达到最小以求得相应的β,即
.
岭回归则需要一个惩罚项来约束系数的大小,即在上面的公式中增加 ,既要使得残差平方和小,又要避免系数过大。
说白了,岭回归就是通过牺牲最小二乘法的无偏性,以损失部分信息、降低精度为代价获得回归系数,对于病态数据以及共线性强的数据具有良好效果。也就是说,在约束条件
下,满足
.
显然这里需要确定λ和s的值,一般用交叉验证或者MallowsCp等准则通过计算来确定。
R中的MASS包提供了lm.ridge()函数用于实现岭回归。
> library(MASS) > ridge.dia<-lm.ridge(y~.,lambda = seq(0,150,length.out = 151),data = diabetes.test[,11:75],model = TRUE) #拟合回归模型 > names(ridge.dia) #查看回归模型的详细内容 >[1] "coef" "scales" "Inter" "lambda"