R package glmnet是做penalty和variable selection最经典的package了,是standford的那几个大牛写的,速度快得惊人。但是在使用cross validation选tuning的时候要千万小心。先看下面的示例:
> set.seed(1)
> x=matrix(rnorm(5*100),100,5)
> b=c(1,1,1,0,0)
> y=x%*%b+rnorm(100)
> coef(cv.glmnet(x,y,intercept=F),s="lambda.min")
6 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) .
V1 0.80006569
V2 0.89865205
V3 0.89268246
V4 -0.02624328
V5 .
得到上面的结果,现在我用同样的数据再运行2遍。
> coef(cv.glmnet(x,y,intercept=F),s="lambda.min")
6 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) .
V1 0.84550269
V2 0.94449809
V3 0.93811796
V4 -0.06717155
V5 -0.02125696
> coef(cv.glmnet(x,y,intercept=F),s="lambda.min")
6 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) .
V1 0.81248850
V2 0.91128404
V3 0.90607610
V4 -0.03874806
V5 .
以上三次运行的计算结果都不一样,有时差异还挺大的。
这里的问题在哪里呢?问题在于做cross validation时,随机抽取的样本不一样了,选出的最优tunning parameter不一样,导致结果不一样。
从理论上讲,一组数据的分析结果只有一个,但是现在出现了多个,到底哪个是对的?
其实每个都是对的,问题还是在于tuning。这里一种可行的办法就是做CV的时候固定seed,这样每次出来的结果都一样了,因为CV时样本的抽样给固定了。