【机器学习】3. 线性模型 - Lasso_ZhShy23的博客-程序员宅基地_lasso模型

技术标签: python  机器学习  人工智能  

上一篇:岭回归

文章目录

lasso

The Lasso 是估计稀疏系数的线性模型。 它在一些情况下是有用的,因为它倾向于使用具有较少参数值的情况,有效地减少给定解决方案所依赖变量的数量。 因此,Lasso 及其变体是压缩感知领域的基础。 在一定条件下,它可以恢复一组非零权重的精确集。
在数学公式表达上,它由一个带有 ℓ 1 \ell_1 1 先验的正则项的线性模型组成。 其最小化的目标函数是:
m i n   w 1 2 n s a m p l e s ∣ ∣ X w − y ∣ ∣ 2 2 + α ∣ ∣ w ∣ ∣ 1 \underset{w}{min\,} { \frac{1}{2n_{samples}} ||X w - y||_2 ^ 2 + \alpha ||w||_1} wmin2nsamples1Xwy22+αw1
lasso estimate 解决了加上罚项 α ∣ ∣ w ∣ ∣ 1 \alpha ||w||_1 αw1 的最小二乘法的最小化,其中, α \alpha α 是一个常数, ∣ ∣ w ∣ ∣ 1 ||w||_1 w1 是参数向量的 ℓ 1 − n o r m \ell_1-norm 1norm 范数。
Lasso 类的实现使用了 coordinate descent (坐标下降算法)来拟合系数。

>>> from sklearn import linear_model
>>> reg = linear_model.Lasso(alpha = 0.1)
>>> reg.fit([[0, 0], [1, 1]], [0, 1])
Lasso(alpha=0.1, copy_X=True, fit_intercept=True, max_iter=1000,
normalize=False, positive=False, precompute=False, random_state=None,
selection='cyclic', tol=0.0001, warm_start=False)
>>> reg.predict([[1, 1]])
array([ 0.8])

对于较低级别的任务,同样有用的是函数 lasso_path 。它能够通过搜索所有可能的路径上的值来计算系数。


设置正则化参数
alpha 参数控制估计系数的稀疏度。


使用交叉验证
scikit-learn 通过交叉验证来公开设置 Lasso alpha 参数的对象:LassoCVLassoLarsCVLassoLarsCV是基于下面解释的 最小角回归 算法。
对于具有许多线性回归的高维数据集, LassoCV 最常见。 然而,LassoLarsCV 在寻找 a l p h a alpha alpha 参数值上更具有优势,而且如果样本数量与特征数量相比非常小时,通常 LassoLarsCVLassoCV 要快。


基于信息标准的模型选择
有多种选择时,估计器 LassoLarsIC 建议使用 Akaike information criterion (Akaike 信息准则)(AIC)和 Bayes Information criterion (贝叶斯信息准则)(BIC)。 当使用 k-fold 交叉验证时,正则化路径只计算一次而不是 k + 1 次,所以找到 α 的最优值是一种计算上更便宜的替代方法。 然而,这样的标准需要对解决方案的自由度进行适当的估计,对于大样本(渐近结果)导出,并假设模型是正确的,即数据实际上是由该模型生成的。 当问题严重受限(比样本更多的特征)时,他们也倾向于打破。


与 SVM 的正则化参数的比较
alpha 和 SVM 的正则化参数C 之间的等式关系是 alpha = 1 / C 或者 alpha = 1 / (n_samples * C) ,并依赖于估计器和模型优化的确切的目标函数。

除了Ridge,还有一种正则化的线性回归是Lasso。与岭回归相同,使用lasso也是约束系数使其接近于0,但用到的方法不同,叫作L1正则化。
L1正则化的结果是,使用lasso时某些系数刚好为0。这说明某些特征被模型完全忽略。这可以看作是一种自动化的特征选择。
某些系数刚好为0,这样模型更容易解释,也可以呈现模型最重要的特征。
我们将lasso应用在扩展的波士顿房价数据集上:

lasso = Lasso().fit(X_train, y_train)

# 训练集和测试集的性能
print("Training set score: {:.2f}".format(lasso.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lasso.score(X_test, y_test)))
print("Number of feature used: {}".format(np.sum(lasso.coef_ != 0)))

=================================

Training set score: 0.29
Test set score: 0.21
Number of feature used: 4

如你所见,Lasso在训练集与测试集上的表现都很差。这表示存在欠拟合,我们发现模型只用到了105个特征中的4个。与Ridge类似,Lasso也有一个正则化参数alpha,可以控制系数趋向于0的强度。在上一个例子中,我们用的是默认值alpha=1.0。为了降低欠拟合,我们尝试减小alpha。这么做的同时,我们还需要增加max iter的值(运行迭代的最大次数):

lasso001 = Lasso(alpha=0.01, max_iter=100000).fit(X_train, y_train)

# 训练集和测试集的性能
print("Training set score: {:.2f}".format(lasso001.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lasso001.score(X_test, y_test)))
print("Number of feature used: {}".format(np.sum(lasso001.coef_ != 0)))

===================================
Training set score: 0.90
Test set score: 0.77
Number of feature used: 33

alpha值变小,我们可以拟合一个更复杂的模型,在训练集和测试集上的表现也更好。模型性能比使用Ridge时略好一点,而且我们只用到了105个特征中的33个。这样模型可能更容易理解。
但如果把alpha设得太小,那么就会消除正则化的效果,并出现过拟合,得到与LinearRegression类似的结果:

lasso00001 = Lasso(alpha=0.0001, max_iter=100000).fit(X_train, y_train)

# 训练集和测试集的性能
print("Training set score: {:.2f}".format(lasso00001.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lasso00001.score(X_test, y_test)))
print("Number of feature used: {}".format(np.sum(lasso00001.coef_ != 0)))

====================================
Training set score: 0.95
Test set score: 0.64
Number of feature used: 96

再次对不同模型的系数进行作图:

plt.plot(lasso.coef_, 's', label="Lasso_alpha = 1")
plt.plot(lasso001.coef_, '^', label="Lasso001_alpha = 0.01")
plt.plot(lasso00001.coef_, 'v', label="Lasso00001_alpha = 0.0001")
plt.plot(ridge01.coef_, 'o', label="Ridge_alpha = 0.1")

plt.xlabel("Coefficient_index")
plt.ylabel("Coefficient_magnitude")
plt.ylim(-25, 25)
plt.legend(ncol=2, loc=(0, 1.05))

plt.show()

在这里插入图片描述
在alpha=1时,我们发现不仅大部分系数都是0(我们已经知道这一点),而且其他系数也都很小。将alpha减小至0.01,我们得到图中向上的三角形,大部分特征等于0。alpha=0.0001时,我们得到正则化很弱的模型,大部分系数都不为0,并且还很大。为了便于比较,图中用圆形表示Ridge的最佳结果。alpha=0.1的Ridge模型的预测性能与alpha=0.01的Lasso模型类似,但Ridge模型的所有系数都不为0。
在实践中,在两个模型中一般首选岭回归。但如果特征很多,你认为只有其中几个是重要的,那么选择Lasso可能更好。同样,如果你想要一个容易解释的模型,Lasso可以给出更容易理解的模型,因为它只选择了一部分输入特征。scikit-learn还提供了ElasticNet类,结合了Lasso和Ridge的惩罚项。在实践中,这种结合的效果最好,不过代价是要调节两个参数:一个用于L1正则化,一个用于L2正则化。

完整代码

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso

import numpy as np
import mglearn as mglearn
import matplotlib.pyplot as plt

X, y = mglearn.datasets.load_extended_boston()
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

##################### LinearRegression

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

# 训练集和测试集的性能
print("\n[LinearRegression]")
print("Training set score: {:.2f}".format(lr.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lr.score(X_test, y_test)))

##################### Ridge

########### Ridge_alpha = 1

ridge = Ridge().fit(X_train, y_train)

# 训练集和测试集的性能
print("\n[Ridge_alpha = 1]")
print("Training set score: {:.2f}".format(ridge.score(X_train, y_train)))
print("Test set score: {:.2f}".format(ridge.score(X_test, y_test)))

########## Ridge_alpha = 10

ridge10 = Ridge(alpha=10).fit(X_train, y_train)

# 训练集和测试集的性能
print("\n[Ridge_alpha = 10]")
print("Training set score: {:.2f}".format(ridge10.score(X_train, y_train)))
print("Test set score: {:.2f}".format(ridge10.score(X_test, y_test)))

########## Ridge_alpha = 0.1

ridge01 = Ridge(alpha=0.1).fit(X_train, y_train)

# 训练集和测试集的性能
print("\n[Ridge_alpha = 0.1]")
print("Training set score: {:.2f}".format(ridge01.score(X_train, y_train)))
print("Test set score: {:.2f}".format(ridge01.score(X_test, y_test)))

#################### Lasso

########## Lasso_alpha = 1

lasso = Lasso().fit(X_train, y_train)

# 训练集和测试集的性能
print("\n[Lasso_alpha = 1]")
print("Training set score: {:.2f}".format(lasso.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lasso.score(X_test, y_test)))
print("Number of feature used: {}".format(np.sum(lasso.coef_ != 0)))

########## Lasso_alpha = 0.01

lasso001 = Lasso(alpha=0.01, max_iter=100000).fit(X_train, y_train)

# 训练集和测试集的性能
print("\n[Lasso_alpha = 0.01]")
print("Training set score: {:.2f}".format(lasso001.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lasso001.score(X_test, y_test)))
print("Number of feature used: {}".format(np.sum(lasso001.coef_ != 0)))

########## Lasso_alpha = 0.0001

lasso00001 = Lasso(alpha=0.0001, max_iter=100000).fit(X_train, y_train)

# 训练集和测试集的性能
print("\n[Lasso_alpha = 0.0001]")
print("Training set score: {:.2f}".format(lasso00001.score(X_train, y_train)))
print("Test set score: {:.2f}".format(lasso00001.score(X_test, y_test)))
print("Number of feature used: {}".format(np.sum(lasso00001.coef_ != 0)))

# #################### 制图
# plt.plot(ridge.coef_, 's', label="Ridge_alpha = 1")
# plt.plot(ridge10.coef_, '^', label="Ridge_alpha = 10")
# plt.plot(ridge01.coef_, 'v', label="Ridge_alpha = 0.1")
# plt.plot(lr.coef_, 'o', label="LinearRegression")
#
# plt.xlabel("Coefficient_index")
# plt.ylabel("Coefficient_magnitude")
# plt.hlines(0, 0, len(lr.coef_))
# plt.ylim(-25, 25)
# plt.legend()
#
# mglearn.plots.plot_ridge_n_samples()
# plt.show()

plt.plot(lasso.coef_, 's', label="Lasso_alpha = 1")
plt.plot(lasso001.coef_, '^', label="Lasso001_alpha = 0.01")
plt.plot(lasso00001.coef_, 'v', label="Lasso00001_alpha = 0.0001")
plt.plot(ridge01.coef_, 'o', label="Ridge_alpha = 0.1")

plt.xlabel("Coefficient_index")
plt.ylabel("Coefficient_magnitude")
plt.ylim(-25, 25)
plt.legend(ncol=2, loc=(0, 1.05))

plt.show()

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43651049/article/details/122672048

智能推荐

Scala程序设计—基础篇 学习笔记_qq467215628的博客-程序员宅基地

目录 前言:1,环境准备:2,repl(read evaluation print loop)互动式3,reference transparency(引用透明)与纯函数4,变量:变量类型体系:隐式类型转换nothing 函数运行异常时返回nothing函数前言:为了学习spark,先熟悉下scala基础语法.课程链接慕课网,这里是课程学习笔记1,...

Hadoop HA --- 网络原因/NN Full GC造成集群故障_Miracle_Sylvain的博客-程序员宅基地

Hadoop HA — 网络原因/NN Full GC造成集群故障1 问题描述简单描述一下问题,集群为Hadoop HDFS HA模式,三个节点104、105、106,由于三个节点的时间不同,以105时间为标准。2017-07-08 01:45分左右,集群出现故障。2 日志信息105 NN 日志如下: 105 DN日志如下: 104 JN日志如下: 105 JN日志如下: 106 JN日志如

sql access mysql数据库_MySQL_mysql数据复制到access数据库,mysql数据库表sqltable 字段id,nam - phpStudy..._Chevy Shan的博客-程序员宅基地

mysql数据复制到access数据库mysql数据库表sqltable字段id,name,sex,emailaccess数据库表accesstableid,name,sex,email$connect = mysql_connect("localhost","","");mysql_select_db("mydatabase");$sql = "select * from sqltable;$r...

UML 总结 类图的构成: Rational Rose:描述软件_任亚兵的博客-程序员宅基地

类图的构成:描述系统静态部分类图深入讨论:可见性:公用public “+”私有 private “-”可保护 protected “#”包 package “~”范围:抽象类:不能实例化多重性:定义操作:类图的应用:静态呈现包图:以包为测试单位 对一个程序进行模块划分对象图;描述具体时刻静态结构Rational Rose:描述软件Use CASE 视图:描述存在的actors.usecase以及它们的关系 交互图:逻辑设计对象以及其间关系逻辑视图:类图 状态图组

Spark 性能优化和故障处理_马本不想再等了的博客-程序员宅基地

Spark 性能优化和故障处理一、Spark 性能优化1.1 常规性能优化生产环境 Spark submit 脚本/usr/local/spark/bin/spark-submit \--class com.atguigu.spark.WordCount \--num-executors 80 \--driver-memory 6g \--executor-memory 6g \...

Windows IIS 集成PHP时修改PHP.ini 配置后不生效问题_aohuofeng9952的博客-程序员宅基地

iis下修改c://windows/php.ini 重启iis的网站不生效。需要重启应用程序池即可生效。转载于:https://www.cnblogs.com/SXLBlog/p/10406859.html

随便推点

java图片透明浮水印_PHP 为图片加上浮水印 (含浮水印透明背景处理)_weixin_39947396的博客-程序员宅基地

PHP 要为图片加上浮水印: 就是要将两张图合并在一起, 浮水印的图片要盖在上面.现实状况还会遇到原图要缩略图后, 浮水印的图片可能也要跟着缩略图, 这些部分再此就不写了, 此部份缩略图可见此篇:此篇只写如何用 PHP GD 来合并图片, 做浮水印功能.PHP 为图片加上浮水印 (含浮水印透明背景处理)PHP 要为图片加上浮水印 (两张图合并), 可用下述 Function:imagecopyme...

nginx反向代理服务器的工作原理_ywltoread的博客-程序员宅基地_nginx反向代理的工作原理

最近有打算研读nginx源代码,看到网上介绍nginx可以作为一个反向代理服务器完成负载均衡。所以搜罗了一些关于反向代理服务器的内容,整理综合。       一  概述                         反向代理(Reverse Proxy)方式是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器;并将从服务器上得到的结果返回给Int

如何修正因Windows和Linux或者Mac双系统引起的系统时间错误_leihelloworld的博客-程序员宅基地

如何修正因Windows和Linux或者Mac双系统引起的系统时间错误 曾经装过Windows和Linux或OS X双系统的人肯定都遇到过这样的情况:在Linux或OS X系统中设置好时区(+8)和系统时间以后,当再次重启返回Windows系统中后,会发现Windows系统的时间会错误,而误差刚好是在Linux或 OS X系统中设置的时区数。出现这种情况的原因是由于两种系统在设定时

mysql between和in_MySQL的WHERE语句中BETWEEN与IN的用法和他们的区别_13142ads的博客-程序员宅基地

MySQL BETWEEN 用法not可以对between...and取反。1.数值型BETWEEN 运算符用于 WHERE 表达式中,选取介于两个值之间的数据范围。BETWEEN 同 AND 一起搭配使用,语法如下:WHERE column BETWEEN value1 ANDvalue2WHERE column NOT BETWEEN value1 AND value2通常 value1 应该...

树的应用——使用并查集解决动态连通性问题(含C++代码实现)(中篇:快速合并)_scnu-xyc的博客-程序员宅基地

上篇:树的应用——使用并查集解决动态连通性问题(含C++代码实现)(上篇:快速查找)第二种设计:快速合并 Quick-union在这种设计中,数据结构id[]还是一个整数类型的数组,其索引的含义与之前(上篇:快速查找)相同。但与之前有所不同的是,我们用树来表示连通分量,相互连通的对象之间存在双亲与孩子的关系。id[]中存储的值是其索引对应的对象的双亲对象的索引 (值=双亲的索引)。例如:对应于id[5]:index01234value12224“0号对象

醍醐灌顶学习RTMP,从总体介绍到各个细节_linux地平线的博客-程序员宅基地

RTMP协议是Real Time Message Protocol(实时信息传输协议)的缩写,它是由Adobe公司提出的一种应用层的协议,用来解决多媒体数据传输流的多路复用(Multiplexing)和分包(packetizing)的问题。随着VR技术的发展,视频直播等领域逐渐活跃起来,RTMP作为业内广泛使用的协议也重新被相关开发者重视起来。正好最近在从事这方面的工作,在此记录下自己对RTMP的理解,文章内容多翻译自英文版RTMP文档,按照本人的理解重新整理,希望可以帮助想要了解RTMP协议的朋友,也方面

推荐文章

热门文章

相关标签