Lasso模型原理及代码实现-python3
发布日期:2021-05-15 21:32:20 浏览次数:47 分类:技术文章

本文共 6254 字,大约阅读时间需要 20 分钟。

一、引言

1.1 高维数据

何谓高维数据?高维数据指数据的维度很高,甚至远大于样本量的个数。高维数据的明显的表现是:在空间中数据是非常稀疏的,与空间的维数相比样本量总是显得非常少。

在分析高维数据过程中碰到最大的问题就是维数的膨胀,也就是通常所说的“维数灾难”问题。研究表明,随着维数的增长,分析所需的空间样本数会呈指数增长。
如下所示,当数据空间维度由1增加为3,最明显的变化是其所需样本增加;换言之,当样本量确定时,样本密度将会降低,从而样本呈稀疏状态。假设样本量n=12,单个维度宽度为3,那在一维空间下,样本密度为12/3=4,在二维空间下,样本分布空间大小为3*3,则样本密度为12/9=1.33,在三维空间下样本密度为12/27=0.44。
设想一下,当数据空间为更高维时,X=[x1x1,x2x2,….,xnxn]会怎么样?
在这里插入图片描述

需要更多的样本,样本随着数据维度的增加呈指数型增长; 数据变得更稀疏,导致数据灾难; 在高维数据空间,预测将变得不再容易; 导致模型过拟合。

1.2 数据降维

对于高维数据,维数灾难所带来的过拟合问题,其解决思路是:1)增加样本量;2)减少样本特征,而对于现实情况,会存在所能获取到的样本数据量有限的情况,甚至远小于数据维度,即:d>>n。如证券市场交易数据、多媒体图形图像视频数据、航天航空采集数据、生物特征数据等。

主成分分析作为一种数据降维方法,其出发点是通过整合原本的单一变量来得到一组新的综合变量,综合变量所代表的意义丰富且变量间互不相关,综合变量包含了原变量大部分的信息,这些综合变量称为主成分。主成分分析是在保留所有原变量的基础上,通过原变量的线性组合得到主成分,选取少数主成分就可保留原变量的绝大部分信息,这样就可用这几个主成分来代替原变量,从而达到降维的目的。
但是,主成分分析法只适用于数据空间维度小于样本量的情况,当数据空间维度很高时,将不再适用
Lasso是另一种数据降维方法,该方法不仅适用于线性情况,也适用于非线性情况。Lasso是基于惩罚方法对样本数据进行变量选择,通过对原本的系数进行压缩,将原本很小的系数直接压缩至0,从而将这部分系数所对应的变量视为非显著性变量,将不显著的变量直接舍弃。

1.3 过拟合与欠拟合

在这里插入图片描述

1.3.1 过拟合(over-fitting)

其实就是所建的机器学习模型或者是深度学习模型在训练样本中表现得过于优越,导致在验证数据集以及测试数据集中表现不佳。打个比喻就是当我需要建立好一个模型之后,比如是识别一只狗狗的模型,我需要对这个模型进行训练。恰好,我训练样本中的所有训练图片都是二哈,那么经过多次迭代训练之后,模型训练好了,并且在训练集中表现得很好。基本上二哈身上的所有特点都涵括进去,那么问题来了!假如我的测试样本是一只金毛呢?将一只金毛的测试样本放进这个识别狗狗的模型中,很有可能模型最后输出的结果就是金毛不是一条狗(因为这个模型基本上是按照二哈的特征去打造的)。所以这样就造成了模型过拟合,虽然在训练集上表现得很好,但是在测试集中表现得恰好相反,在性能的角度上讲就是协方差过大(variance is large),同样在测试集上的损失函数(cost function)会表现得很大。

1.3.2 欠拟合

相对过拟合欠拟合还是比较容易理解。还是拿刚才的模型来说,可能二哈被提取的特征比较少,导致训练出来的模型不能很好地匹配,表现得很差,甚至二哈都无法识别。

1.3.3 如何解决过拟合问题?

(1)尽量减少选取变量的数量

可以人工检查每一项变量,并以此来确定哪些变量更为重要,保留那些更为重要的特征变量。这种做法非常有效,但是其缺点是当舍弃一部分特征变量时,也舍弃了问题中的一些信息。例如,所有的特征变量对于预测房价都是有用的,实际上并不想舍弃一些信息或者说舍弃这些特征变量。
(2)正则化
在正则化中将保留所有的特征变量,但是会减小特征变量的数量级。 当有很多特征变量时,其中每一个变量都能对预测产生一点影响。假设在房价预测的例子中,可以有很多特征变量,其中每一个变量都是有用的,因此不希望把任何一个变量删掉,这就导致了正则化概念的发生。

1.3.4 如何应用正则化去解决实际问题?

在上图中,可以看出最右边的是过拟合的,但是不想抛弃变量θ¹θ²自带的信息,因此加上惩罚项,使得θ³θ⁴足够小

优化目标为:
在这里插入图片描述
在优化目标的基础上,添加一些项(惩罚项),如下:
在这里插入图片描述
1000 只是随便写的一个表示很大的数字。现在,如果想要最小化这个函数,那么为了最小化这个新的损失函数,就要让θ³和θ⁴尽可能小。因为,如果在原有代价函数的基础上加上 1000θ³+1000θ⁴这一项 ,那么这个新的代价函数将变得很大,所以,当最小化这个新的代价函数时, θ³和θ⁴尽可能小或者接近于0,就像我们忽略了这两个值一样。如果做到这一点(θ³和θ⁴接近于0),那么我们将得到一个近似的二次函数,并且h0中并没有丢失θ³和θ⁴的信息(虽然θ³和θ⁴接近于0,但是还是存在的)

但是在真实问题中,一个预测问题可能有上百种特征,并不知道哪一些是高阶多项式的项,就像不知道θ³和θ⁴是高阶的项。所以,如果假设有一百个特征,并不知道如何选择关联度更好的参数,如何缩小参数的数目等等。 因此在正则化里,要做的事情,就是减小损失函数中所有的参数值,(因为并不知道是哪一个或哪几个是要去缩小的)。

因此,我们需要修改代价函数,变成如下形式:
在这里插入图片描述
其中在这里插入图片描述

就是正则化项; λ称为正则化参数,作用是控平衡拟合训练的目标和保持参数值较小。

二、初识Lasso

Lasso(Least absolute shrinkage and selection operator)方法是以缩小变量集(降阶)为思想的压缩估计方法。它通过构造一个惩罚函数,可以将变量的系数进行压缩并使某些回归系数变为0,进而达到变量选择的目的。

lasso回归的特色就是在建立广义线型模型的时候,这里广义线型模型包含一维连续因变量、多维连续因变量、非负次数因变量、二元离散因变量、多元离散因变,除此之外,无论因变量是连续的还是离散的,lasso都能处理,总的来说,lasso对于数据的要求是极其低的,所以应用程度较广;除此之外,lasso还能够对变量进行筛选和对模型的复杂程度进行降低。这里的变量筛选是指不把所有的变量都放入模型中进行拟合,而是有选择的把变量放入模型从而得到更好的性能参数。 复杂度调整是指通过一系列参数控制模型的复杂度,从而避免过度拟合(Overfitting)。 对于线性模型来说,复杂度与模型的变量数有直接关系,变量数越多,模型复杂度就越高。 更多的变量在拟合时往往可以给出一个看似更好的模型,但是同时也面临过度拟合的危险。

Lasso回归是在损失函数后,加L1正则化,如下所示:

在这里插入图片描述

m为样本个数,k为参数个数,其中

正则化。

此外:还有L2正则化:

在这里插入图片描述
加了这种正则化的损失函数模型为:脊(岭)回归(Ridge Regression)。

2.1 惩罚函数

这边这个惩罚函数有多种形式,比较常用的有l1,l2,大概有如下几种:

在这里插入图片描述
讲一下比较常用的两种情况,q=1和q=2的情况:

q=1,也就是今天想讲的lasso回归,为什么lasso可以控制过拟合呢,因为在数据训练的过程中,可能有几百个,或者几千个变量,再过多的变量衡量目标函数的因变量的时候,可能造成结果的过度解释,而通过q=1下的惩罚函数来限制变量个数的情况,可以优先筛选掉一些不是特别重要的变量,见下图:

在这里插入图片描述
以二维数据空间为例,说明Lasso和Ridge两种方法的差异,左图对应于Lasso方法,右图对应于Ridge方法。
如上图所示,两个图是对应于两种方法的等高线与约束域。红色的椭圆代表的是随着λ的变化所得到的残差平方和,βˆ为椭圆的中心点,为对应普通线性模型的最小二乘估计。左右两个图的区别在于约束域,即对应的蓝色区域。

等高线和约束域的切点就是目标函数的最优解,Ridge方法对应的约束域是圆,其切点只会存在于圆周上,不会与坐标轴相切,则在任一维度上的取值都不为0,因此没有稀疏;对于Lasso方法,其约束域是正方形,会存在与坐标轴的切点,使得部分维度特征权重为0,因此很容易产生稀疏的结果。

所以,Lasso方法可以达到变量选择的效果,将不显著的变量系数压缩至0,而Ridge方法虽然也对原本的系数进行了一定程度的压缩,但是任一系数都不会压缩至0,最终模型保留了所有的变量。

以二维空间为例,约束域在L1中,为在这里插入图片描述

,对应左图蓝色。约束域在L2中,为
在这里插入图片描述
,对应左图蓝色。

由图也可以看出,Lasso的复杂程度由λ来控制,λ越大对变量较多的线性模型的惩罚力度就越大,从而最终获得一个变量较少的模型。

2.2 LassoCV

ridge是l2正则化的线性回归,lasso则是带l1正则化的线性回归。进一步说,他们都同样的比线性回归多一个超参数需要调,alpha。所以有了RidgeCV,LassoCV的说法。也就是说我们必须找到合理的alpha,那么这个线性模型我们才能说是找好了。所以建议在用这两个模型时,尽量都用CV形式的,而不是用Lasso与Ridge

2.2.1 Lasso参数介绍

Lasso(alpha=1.0, fit_intercept=True, normalize=False, precompute=False,       copy_X=True, max_iter=1000, tol=0.0001, warm_start=False,       positive=False, random_state=None, selection=‘cyclic’)• alphas:指定λ\lambdaλ值,默认为1。• fit_intercept:bool类型,是否需要拟合截距项,默认为True。• normalize:bool类型,建模时是否对数据集做标准化处理,默认为False。• precompute:bool类型,是否在建模前计算Gram矩阵提升运算速度,默认为False。• copy_X:bool类型,是否复制自变量X的数值,默认为True。• max_iter:指定模型的最大迭代次数。• tol:指定模型收敛的阈值,默认为0.0001。• warm_start:bool类型,是否将前一次训练结果用作后一次的训练,默认为False。• positive:bool类型,是否将回归系数强制为正数,默认为False。• random_state:指定随机生成器的种子。• selection:指定每次迭代选择的回归系数,如果为’random’,表示每次迭代中将随机更新回归系数;如果为’cyclic’,则每次迭代时回归系数的更新都基于上一次运算。

2.2.2 LassoCV参数介绍

LassoCV(eps=0.001, n_alphas=100, alphas=None, fit_intercept=True,         normalize=False, precompute=‘auto’, max_iter=1000, tol=0.0001,         copy_X=True, cv=None, verbose=False, n_jobs=1, positive=False,         random_state=None, selection=‘cyclic’)• eps:指代λ 最小值与最大值的商,默认为0.001。• n_alphas:指定λ的个数,默认为100个。• alphas:指定具体的λ列表用于模型的运算。• fit_intercept:bool类型,是否需要拟合截距项,默认为True。• normalize:bool类型,建模时是否对数据集做标准化处理,默认为False。• precompute:bool类型,是否在建模前计算Gram矩阵提升运算速度,默认为False。• max_iter:指定模型的最大迭代次数。• tol:指定模型收敛的阈值,默认为0.0001。• copy_X:bool类型,是否复制自变量X的数值,默认为True。• cv:指定交叉验证的重数。• verbose:bool类型,是否返回模型运行的详细信息,默认为False。• n_jobs:指定使用的CPU数量,默认为1,如果为-1表示所有CPU用于交叉验证的运算。• positive:bool类型,是否将回归系数强制为正数,默认为False。• random_state:指定随机生成器的种子。• selection:指定每次迭代选择的回归系数,如果为’random’,表示每次迭代中将随机更新回归系数;如果为’cyclic’,则每次迭代时回归系数的更新都基于上一次运算。

示例代码

import pandas as pdimport numpy as npfrom sklearn import model_selectionfrom sklearn.linear_model import Lasso,LassoCVfrom sklearn.metrics import mean_squared_error data=pd.read_excel(r'C:\Users\Administrator\Desktop\diabetes.xlsx')data=data.drop(['AGE','SEX'],axis=1)#拆分为训练集和测试集predictors=data.columns[:-1]x_train,x_test,y_train,y_test=model_selection.train_test_split(data[predictors],data.Y,                                                               test_size=0.2,random_state=1234)#构造不同的lambda值Lambdas=np.logspace(-5,2,200)#设置交叉验证的参数,使用均方误差评估lasso_cv=LassoCV(alphas=Lambdas,normalize=True,cv=10,max_iter=10000)lasso_cv.fit(x_train,y_train) #基于最佳lambda值建模lasso=Lasso(alpha=lasso_cv.alpha_,normalize=True,max_iter=10000)lasso.fit(x_train,y_train)#打印回归系数print(pd.Series(index=['Intercept']+x_train.columns.tolist(),                data=[lasso.intercept_]+lasso.coef_.tolist())) #模型评估lasso_pred=lasso.predict(x_test)#均方误差MSE=mean_squared_error(y_test,lasso_pred)print(MSE)

结果

在这里插入图片描述

转载地址:https://blog.csdn.net/qq_30868737/article/details/108365854 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:XGBoost学习(四):实战-python3
下一篇:LinearRegression,RidgeCV,LassoCV,ElasticNetCV各自使用场景

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年04月06日 02时21分26秒