1.Lasso的矩阵推导

对损失函数进行求导:

所以,这里的问题又回到了OLS中XTX的逆必须存在,回顾下岭回归最后的结果:

岭回归 vs Lasso
岭回归可以解决特征间的精确相关关系导致的最小二乘法无法使用的问题,而Lasso不行。

推导完成了,但是问题也来了,Lasso是如何把系数惩罚到0了,下一部分会说到。
2.Lasso vs Ridge
假设w是二维的,那么:


岭回归 vs Lasso
Lasso可以做特征选择,岭回归不行。
3.偏差与方差


偏差(bias): 偏差度量了模型的预测均值与真实结果的偏离程度,即刻画了学习算法本身的拟合能力。
方差(variance): 方差度量了同样大小的训练集的变动所导致的学习性能的变化,即刻画了数据扰动所造成的影响。
噪音(noise): 噪音表达了当前任务上任何学习算法所能达到期望泛化误差MSE的下界,即刻画了学习问题本身的难度。

Question:从上面的图中可以看出,模型不稳定时会出现偏差小、方差大的情况,那么偏差和方差作为两种度量方式有什么区别呢?
Answer:Bias的对象是单个模型,是期望输出与真实标记的差别。它描述了模型对本训练集的拟合程度。Variance的对象是多个模型,是相同分布的不同数据集训练出模型的输出值之间的差异。它刻画的是数据扰动对模型的影响。

4.Lasso的意义
5.Lasso的实战
library(ElemStatLearn) #contains the datalibrary(car) #package to calculate Variance Inflation Factorlibrary(glmnet) #allows ridge regression, LASSO and elastic nedata(prostate)str(prostate)##载入包和数据

train代表训练集和测试集;lpsa在这里作为响应y,1:8列数据在这里作为预测变量x
prostate$gleason <- ifelse(prostate$gleason == 6, 0, 1) ##divide gleason score into <=6 and >6 groupstable(prostate$gleason)##将gleason评分变为二分类变量 <=6 和 >6train <- subset(prostate, train == TRUE)[,1:9]test = subset(prostate, train==FALSE)[,1:9]##将数据集分为训练集和测试集
x <- as.matrix(train[, 1:8])y <- train[, 9]fit <- glmnet(x, y, family = "gaussian", alpha = 1)print(fit)


列 Df 是自由度,代表了非零的线性模型拟合系数的个数。列 %Dev 代表了由模型解释的残差的比例,对于线性模型来说就是模型拟合的R2(R-squred)。它在 0 和 1 之间,越接近 1 说明模型的表现越好,如果是 0,说明模型的预测结果还不如直接把因变量的均值作为预测值来的有效。列 Lambda 当然就是每个模型对应的 λ 值。我们可以看到,随着 λ 的变小,越来越多的自变量被模型接纳进来,%Dev 也越来越大。第 65 行时,模型包含了所有 8 个自变量,%Dev 也在 0.7 以上。其实我们本应该得到 100个不同的模型,但是连续几个 %Dev 变化很小时 glmnet() 会自动停止。分析模型输出我们可以看到当 Df 大于 6 的时候,%Dev 就达到了 0.66,而且继续缩小 λ,即增加更多的自变量到模型中,也不能显著提高 %Dev。所以我们可以认为当 λλ 接近 0.1 时,得到的包含 6 个自变量的模型,可以相当不错的描述这组数据。
plot(fit)

# 我们也可以通过指定λ值,抓取出某一个模型的系数:predict(fit,s = 0.1,type = 'coefficient')# coef(fit,s = 0.1)

计算一下在测试集的MSE
pred.lasso = predict(fit,newx = as.matrix(test[,-9]),s = 0.1,type = 'response')lpsa - pred.lasso)^2)

上期计算了几种方法的MSE,我们来比较一下:
OLS:0.4925
ridge(lambda=0.1):0.4784
ridge(lambda=optimal-λ):0.4777
lasso(lambda=0.1):0.4447
所以目前为止,lasso的泛化能力要比上面的结果都优秀
毕竟这个lambda是通过我们的观察选的,不是很科学,我们接下来用交叉验证来选择一个最优的lambda。
cv_fit <- cv.glmnet(x, y,family = 'gaussian',alpha = 1,# nfolds = 10,type.measure="mse")plot(cv_fit)
参数family规定了回归模型的类型:
-family="gaussian"适用于一维连续因变量
-family=mgaussian"适用于多维连续因变量
-family="poisson"适用于非负次数因变量(count)
-family="binomial"适用于二元离散因变量(binary)-family="multinomial"适用于多元离散因变量(category)
cv_fit$lambda.min #最佳lambda值cv_fit$lambda.1se#指在lambda.min一个标准差范围内得到的最简单模型的那一个lambda值。因为lambda值达到一定大小之后,继续增加模型自变量个数及缩小lambda值,并不能显著提高模型性能,lambda.lse给出的就是一个具备优良性能但是自变量个数最少的模型coefficients<-coef(fit,s=cv_fit$lambda.min)> 最佳lambda值Active.Index<-which(coefficients!=0)> 系数不为0的特征索引Active.coefficients<-coefficients[Active.Index]> 系数不为0的特征系数值

上图中,左边这条线是x=cv_fit$lambda.min,右边这条线是x=cv_fit$lambda.1se
当lambda为最优时,模型此时保留了所有变量
最佳lambda值:cv_fit$lambda.min

输出最佳lambda值时,lasso回归的系数
predict(fit,s = cv_fit$lambda.min,type = 'coefficient')

利用最佳lambda值拟合的lasso模型输出测试集的结果,并计算MSE
pred.lasso2 = predict(fit,newx = as.matrix(test[,-9]),s = cv_fit$lambda.min,type = 'response')mean((test$lpsa - pred.lasso2)^2)

我们发现一个现象,用最优的lambda建模发现泛化误差比以上几种方法的都大,这其实也能理解,毕竟模型复杂度改变不是很多,那么我们选择lambda.lse来建模,lambda.lse给出的就是一个具备优良性能但是自变量个数最少的模型,也就是更简单的模型。
pred.lasso3 = predict(fit,newx = as.matrix(test[,-9]),s = cv_fit$lambda.1se,type = 'response')mean((test$lpsa - pred.lasso3)^2)

这时候发现得到的MSE是这些方法中最小的,这也说明了机器学习的建模不是一种方法就可以走到底的,需要以结果为导向,不断的调试才能得到满意的模型。
参考资料:
周志华-机器学习
知乎-狗熊会-统计学习:变量选择之Lasso
统计之都:Lasso回归
Understanding the Bias-Variance Tradeoff
菜菜的sklearn

