07- 梯度下降优化(Lasso/Ridge/ElasticNet) (数据处理+算法)

article/2025/9/16 22:22:34
  • 归一化: 减少数据不同数量级对预测的影响, 主要是将数据不同属性的数据都降到一个数量级
    • 最大值最小值归一化:优点是可以把所有数值归一到 0~1 之间,缺点受离群值影响较大
    • 0-均值标准化: 经过处理的数据符合标准正态分布,即均值为0,标准差为1, 有正有负。
from sklearn.preprocessing import MinMaxScaler    # 最大值最小值归一化
min_max_scaler = MinMaxScaler()
x_ = min_max_scaler.fit_transform(x) from sklearn.preprocessing import StandardScaler  # 0-均值标准化
standard_scaler = StandardScaler()
x_ = standard_scaler.fit_transform(x)
  • 正则化:  防止数据过拟合, 增强模型的泛化能力, 常用方式为增加L1 L2干扰项。
  • Lasso 回归:  把多元线性回归损失函数加上 L1 正则,
# 套索回归: Lasso回归
from sklearn.linear_model import Lasso
lasso = Lasso(alpha= 0.5)
lasso.fit(X, y)
print('套索回归求解的斜率:',lasso.coef_)
print('套索回归求解的截距:',lasso.intercept_)
  • Ridge 岭回归:  多元线性回归损失函数加上 L2 正则的时候
from sklearn.linear_model import Ridge
ridge = Ridge(alpha= 1, solver='sag')
ridge.fit(X, y)
print('岭回归求解的斜率:',ridge.coef_)
print('岭回归求解的截距:',ridge.intercept_)
  • Elastic-Net算法 很多特征互相联系的情况下是非常有用的, 融合了L1正则化L2正则化。
from sklearn.linear_model import ElasticNet
model = ElasticNet(alpha= 1, l1_ratio = 0.7)
model.fit(X, y)
print('弹性网络回归求解的斜率:',model.coef_)
print('弹性网络回归求解的截距:',model.intercept_)
  • 多项式回归的目的: 数据不够时防止欠拟合, 通常是使用现有参数相乘, 或者自身平方达到增加数据量的目的


二、梯度下降优化

1、归一化 (Normalization)

归一化的目的: 减少数据不同数量级对数据预测的影响, 主要是将数据不同属性的数据都降到一个数量级
由于不同方向的陡峭度是不一样的,即不同维度的数值大小是不同。也就是说梯度下降的快慢是不同的,归一化的一个目的是,使得梯度下降在不同维度 \small \theta 参数(不同数量级)上,可以步调一致协同的进行梯度下降。归一化的本质就要把各个特征维度 \bg_white \small x_1, x_2, ...... , x_n 的数量级统一,来做到无量纲化。

1.1、最大值最小值归一化

也称为离差标准化,是对原始数据的线性变换,使结果值映射到[0 - 1]之间。转换函数如下:
        .X^* = \frac{X - X\_min}{X\_max -X\_min}

通过公式可以发现,该方式受离群值的影响比较大.
使用scikit-learn函数演示:

import numpy as np
from sklearn.preprocessing import MinMaxScaler
x_1 = np.random.randint(1,10,size = 10)
x_2 = np.random.randint(100,300,size = 10)
x = np.c_[x_1,x_2]    # 将数组放到一起
print('归一化之前的数据:')
min_max_scaler = MinMaxScaler()
x_ = min_max_scaler.fit_transform(x)
print('归一化之后的数据:')
display(x_)

1.2、0-均值标准化

这种方法给予原始数据的均值(mean)标准差(standard deviation)进行数据的标准化,也叫做Z-score标准化经过处理的数据符合标准正态分布,即均值为0,标准差为1,转化函数为:

        X^* = \frac{X - \mu}{\sigma}
其中μ为所有样本数据的均值,σ为所有样本数据的标准差。
相对于最大值最小值归一化来说,因为标准归一化除以了标准差,而标准差的计算会考虑到所有样本数据,所以受到离群值的影响会小一些,这就是除以方差的好处!但是,0-均值标准化不一定会把数据缩放到 0 ~ 1 之间了。既然是0均值,也就意味着,有正有负
使用scikit-learn函数

import numpy as np
from sklearn.preprocessing import StandardScaler
x_1 = np.random.randint(1,10,size = 10)
x_2 = np.random.randint(100,300,size = 10)
x = np.c_[x_1,x_2]
print('归一化之前的数据:')
standard_scaler = StandardScaler()
x_ = standard_scaler.fit_transform(x)
print('归一化之后的数据:')
display(x_)

注意:

  • 我们在做特征工程的时候,很多时候如果对训练集的数据进行了预处理,比如这里讲的归一化,那么未来对测试集的时候,和模型上线来新的数据的时候,都要进行相同的数据预处理流程,而且所使用的均值和方差是来自当时训练集的均值和方差!
  • 通过把 scaler 对象持久化, 回头模型上线的时候再加载进来去对新来的数据进行处理。
import joblib
joblib.dump(standard_scaler,'scale')     # 持久化
standard_scaler = joblib.load('scale')   # 加载
standard_scaler.transform(x)    # 使用

2、正则化 Regularization

正则化的目的: 防止数据过拟合, 增强模型的泛化能力, 常用方式为增加L1 L2干扰项。

2.1、过拟合欠拟合

        正则化就是防止过拟合,增加模型的鲁棒性,鲁棒是 Robust 的音译,也就是强壮的意思。正则化(鲁棒性调优)的本质就是牺牲模型在训练集上的正确率来提高推广、泛化能力, W 在数值上越小越好,这样能抵抗数值的扰动。同时为了保证模型的正确率 W 又不能极小。
        常用的惩罚项L1 正则项或者 L2 正则项,分别对应曼哈顿距离(x+y),和欧式距离(平方再开方), 当我们把多元线性回归损失函数加上 L2 正则的时候,就诞生了 Ridge 岭回归。当我们把多元线性回归损失函数加上 L1 正则的时候,就孕育出来了 Lasso 回归

  • 欠拟合(under fit)还没有拟合到位,训练集和测试集的准确率都还没有到达最高,学的还不到位。
  • 过拟合(over fit)拟合过度,训练集的准确率升高的同时,测试集的准确率反而降低。学的过度了(走火入魔),做过的卷子都能再次答对(死记硬背),考试碰到新的没见过的题就考不好(不会举一反三)。
  • 恰到好处(just right):过拟合前,训练集和测试集准确率都达到巅峰。好比,学习并不需要花费很多时间,理解的很好,考试的时候可以很好的把知识举一反三。

2.2、套索回归(Lasso)

先从线性回归开始,其损失函数如下:

J(\theta) = \frac{1}{2}\sum\limits_{i = 1}^n(h_{\theta}(x^{(i)}) - y^{(i)})^2

L1正则化的损失函数,令 ​J_0 = J(\theta)

J = J_0 + \alpha * \sum\limits_{i = 1}^n|w_i|

令 ​L_1 = \alpha * \sum\limits_{i = 1}^n|w_i|

J = J_0 + L_1

其中 J_0 是原始的损失函数,加号后面的一项是L1正则化项, \alpha 是正则化系数。注意到 L1正则化是权值的绝对值之和。 J 是带有绝对值符号的函数,因此 J 是不完全可微的。机器学习的任务就是要通过一些方法(比如梯度下降)求出损失函数的最小值。当我们在原始损失函数 J_0​ 后面添加L1正则项时,相当于对 J_0​ 做了一个约束。令 L_1 = \alpha * \sum\limits_{i = 1}^n|w_i| ,则 J = J_0 + L_1,此时我们的任务变成在 L_1​ 约束下求出 J_0​ 取最小值的解。考虑二维的情况,即只有两个权值 w_1, w_2  ,此时 L_1 = |w_1| + |w_2|。对于梯度下降法,求解 J_0 过程可以画出等值线,同时 L1 正则化的函数 ​ 也可以在 w_1, w_2 ​所在的平面上画出来:

 
用 \lambda 表示L1正则化系数

 \theta_j^{n + 1} = \theta_j^{n} -\eta\sum\limits_{i = 1}^{n} (h_{\theta}(x^{(i)}) - y^{(i)} )x_j^{(i)} - \eta*\alpha * sgn(w_i)

L1正则化和普通线性回归系数对比:

和没有正则项约束线性回归对比,可知L1正则化,将方程系数进行了缩减,部分系数为0,产生稀疏模型

\alpha 越大,模型稀疏性越强,越多的参数为0

Lasso回归源码解析:

  • alpha:正则项系数
  • fit_intercept:是否计算 w 0 w_0 w0​ 截距项
  • normalize:是否做归一化
  • precompute:bool 类型,默认值为False,决定是否提前计算Gram矩阵来加速计算
  • max_iter:最大迭代次数
  • tol:结果的精确度
  • warm_start:bool类型,默认值为False。如果为True,那么使⽤用前⼀次训练结果继续训练。否则从头开始训练
import numpy as np
from sklearn.linear_model import Lasso
from sklearn.linear_model import SGDRegressor# 1、创建数据集X,y
X = 2*np.random.rand(100, 20)
w = np.random.randn(20,1)
b = np.random.randint(1,10,size = 1)
y = X.dot(w) + b + np.random.randn(100, 1)print('原始方程的斜率:',w.ravel())
print('原始方程的截距:',b)lasso = Lasso(alpha= 0.5)
lasso.fit(X, y)
print('套索回归求解的斜率:',lasso.coef_)
print('套索回归求解的截距:',lasso.intercept_)# 线性回归梯度下降方法
sgd = SGDRegressor(penalty='l2',alpha=0, l1_ratio=0)
sgd.fit(X, y.reshape(-1,))
print('随机梯度下降求解的斜率是:',sgd.coef_)
print('随机梯度下降求解的截距是:',sgd.intercept_)

2.3、岭回归(Ridge)

也是先从线性回归开始,其损失函数如下:

J(\theta) = \frac{1}{2}\sum\limits_{i = 1}^n(h_{\theta}(x^{(i)}) - y^{(i)})^2
L2正则化的损失函数(对L2范数,进行了平方运算),令 J_0 = J(\theta)

J = J_0 + \alpha * \sum\limits_{i = 1}^n(w_i)^2
L_2 = \alpha * \sum\limits_{i = 1}^n(w_i)^2

{\color{DarkGreen} J = J_0 + L_2}
二维平面下 L2 正则化的函数图形是个圆(绝对值的平方和,是个圆),与方形相比,被磨去了棱角。因此 J_0 与 L_2 相交时使得 w_1, w_2​ 等于零的机率小了许多(这个也是一个很直观的想象),这就是为什么L2正则化不具有稀疏性的原因,因为不太可能出现多数 w 都为0的情况(这种情况就叫稀疏性)

用 \lambda 表示L2正则化系数:

 \theta_j^{n + 1} = \theta_j^{n}(1-\eta * \lambda) -\eta *\sum\limits_{i = 1}^{n} (h_{\theta}(x^{(i)}) - y^{(i)} )x_j^{(i)}

L2正则化和普通线性回归系数对比:

和没有正则项约束线性回归对比,可知L2正则化,将方程系数进行了缩小
\alpha 增大求解出来的方程斜率变小
Ridge回归源码解析:

  • alpha:正则项系数
  • fit_intercept:是否计算 w_0​ 截距项
  • normalize:是否做归一化
  • max_iter:最大迭代次数
  • tol:结果的精确度
  • solver:优化算法的选择
import numpy as np
from sklearn.linear_model import Ridge
from sklearn.linear_model import SGDRegressor# 1、创建数据集X,y
X = 2*np.random.rand(100, 5)
w = np.random.randint(1,10,size = (5,1))
b = np.random.randint(1,10,size = 1)
y = X.dot(w) + b + np.random.randn(100, 1)print('原始方程的斜率:',w.ravel())
print('原始方程的截距:',b)ridge = Ridge(alpha= 1, solver='sag')
ridge.fit(X, y)
print('岭回归求解的斜率:',ridge.coef_)
print('岭回归求解的截距:',ridge.intercept_)# 线性回归梯度下降方法
sgd = SGDRegressor(penalty='l2',alpha=0,l1_ratio=0)
sgd.fit(X, y.reshape(-1,))
print('随机梯度下降求解的斜率是:',sgd.coef_)
print('随机梯度下降求解的截距是:',sgd.intercept_)

2.4、Elastic-Net算法使用

        Elastic-Net 回归,即岭回归和Lasso技术的混合。弹性网络是一种使用 L1, L2 范数作为先验正则项训练的线性回归模型。 这种组合允许学习到一个只有少量参数是非零稀疏的模型,就像 Lasso 一样,但是它仍然保持一些像 Ridge 的正则性质。我们可利用 l1_ratio 参数控制 L1 和 L2 的凸组合。
        弹性网络在很多特征互相联系(相关性,比如身高和体重就很有关系)的情况下是非常有用的。Lasso 很可能只随机考虑这些特征中的一个,而弹性网络更倾向于选择两个。在实践中, Lasso 和 Ridge 之间权衡的一个优势是它允许在迭代过程中继承 Ridge 的稳定性。

弹性网络回归和普通线性回归系数对比:

import numpy as np
from sklearn.linear_model import ElasticNet
from sklearn.linear_model import SGDRegressor# 1、创建数据集X,y
X = 2*np.random.rand(100, 20)
w = np.random.randn(20,1)
b = np.random.randint(1,10,size = 1)
y = X.dot(w) + b + np.random.randn(100, 1)print('原始方程的斜率:',w.ravel())
print('原始方程的截距:',b)model = ElasticNet(alpha= 1, l1_ratio = 0.7)
model.fit(X, y)
print('弹性网络回归求解的斜率:',model.coef_)
print('弹性网络回归求解的截距:',model.intercept_)# 线性回归梯度下降方法
sgd = SGDRegressor(penalty='l2',alpha=0, l1_ratio=0)
sgd.fit(X, y.reshape(-1,))
print('随机梯度下降求解的斜率是:',sgd.coef_)
print('随机梯度下降求解的截距是:',sgd.intercept_)

3、多项式回归

多项式回归的目的: 数据不够时防止欠拟合, 通常是使用现有参数相乘, 或者自身平方达到增加数据量的目的。

3.1、多项式回归基本概念

升维的目的是为了去解决欠拟合的问题的,也就是为了提高模型的准确率为目的的,因为当维度不够时,说白了就是对于预测结果考虑的因素少的话,肯定不能准确的计算出模型。
在做升维的时候,最常见的手段就是将已知维度进行相乘(或者自乘)来构建新的维度,如下图所示。普通线性方程,无法拟合规律,必须是多项式,才可以完美拟合曲线规律,图中是二次多项式。
对于多项式回归来说主要是为了扩展线性回归算法来适应更广泛的数据集,比如我们数据集有两个维度 x_1, x_2​,那么用多元线性回归公式就是: \hat{y} = w_0 + w_1x_1 + w_2x_2,当我们使用二阶多项式升维的时候,数据集就从原来的 x_1, x_2 扩展成了 x_1, x_2, x_1^2, x_2^2, x_1x_2 。因此多元线性回归就得去多计算三个维度所对应的w值:\hat{y} = w_0 + w_1x_1 + w_2x_2 + w_3x_1^2 + w_4x_2^2 + w_5x_1x_2
此时拟合出来的方程就是曲线,可以解决一些线性回归的欠拟合问题!

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression# 1、创建数据,并进行可视化
X = np.linspace(-1,11,num = 100)
y = (X - 5)**2 + 3*X -12 + np.random.randn(100)
X = X.reshape(-1,1)
plt.scatter(X,y)# 2、创建预测数据
X_test = np.linspace(-2,12,num = 200).reshape(-1,1)# 3、不进行升维 + 普通线性回归
model_1 = LinearRegression()
model_1.fit(X,y)
y_test_1 = model_1.predict(X_test)
plt.plot(X_test,y_test_1,color = 'red')# 4、多项式升维 + 普通线性回归
X = np.concatenate([X,X**2],axis = 1)
model_2 = LinearRegression()
model_2.fit(X,y)
# 5、测试数据处理,并预测
X_test = np.concatenate([X_test,X_test**2],axis = 1)
y_test_2 = model_2.predict(X_test)# 6、数据可视化,切片操作
plt.plot(X_test[:,0],y_test_2,color = 'green')


http://chatgpt.dhexx.cn/article/UjaXLLDK.shtml

相关文章

Linear Regression:Ridge regression

Ridge regression:岭回归 与least-squares method (最小二乘法)相似,只是加了一个对输入数据权重的惩罚值, 这个惩罚参数称为regularization (正则化)。正则化降低模型的复杂度,防止模型的过度拟合。 Ridge regression 利用L2 regularizatio…

对Lasso可以做特征选择,而Ridge却不行的详细解释

为了限制模型参数的数值大小,就在模型原来的目标函数上加上一个惩罚项,这个过程叫做正则化(Regularization)。 如果惩罚项是参数的 l 2 l_2 l2​范数,就是岭回归(Ridge Regression)如果惩罚项是参数的 l 1 l_1 l1​范…

Kernel Ridge Regression 详解过程

Kernel Ridge Regression(KRR,核脊回归) 是Ridge Regression(RR,脊回归)的kernel版本,与Support Vector Regression(SVR,支持向量回归)类似。所以,在这里,我们先大致了解RR的来源,由此引入KRR&a…

sklearn-1.1.2.Ridge Regression

1.1.2 Ridge Regression Ridge回归通过对系数的惩罚值来解决最小二乘法的系数问题。岭系数的最小化惩罚残差平方和的公式: 这里,是用来控制收缩量的复杂参数:参数值越大,收缩量也越大,因此系数对共线性变得更加稳健。 …

Ridge回归

岭回归(英文名:ridge regression, Tikhonov regularization)是一种专用于共线性数据分析的有偏估计回归方法,自变量之间线性相关-correlation很高,实质上是一种改良的最小二乘估计法,通过放弃最小二乘法的无偏性,以损失…

Lasso 和 Ridge回归中的超参数调整技巧

在这篇文章中,我们将首先看看Lasso和Ridge回归中一些常见的错误,然后我将描述我通常采取的步骤来优化超参数。代码是用Python编写的,我们主要依赖scikit-learn。本文章主要关注Lasso的例子,但其基本理论与Ridge非常相似。 起初&a…

Ridge和Lasso回归

上周看了看回归方面的知识,顺便复(xue)习一下Ridge(岭回归)和Lasso回归(套索回归)。瞅到了一篇英文博客讲得不错,翻译一下 本文翻译自 Ridge and Lasso Regression 本文是一篇Josh …

Ridge回归*

线性回归稍微总结一下: 常见有普通线性回归(没有正则项,目标是最小化均方误差)、LASSO(均方误差项l-1正则项)、Ridge回归(均方误差l-2正则项) 加上正则项可以降低过拟合风险。 Ridge…

【机器学习原理实战01】Ridge回归模型

Ridge回归模型 最近做项目用到岭回归模型,特地来记录一下整个岭回归模型的原理和代码。 以后会将用到的机器学习模型算法都记录下来。1、Ridge 回归原理 多元线性回归计算回归系数的时候回归系数的计算如下: 学过线性代数的都知道,以上式子…

岭回归(Ridge)和Lasso 回归(笔记)

最近在自学图灵教材《Python机器学习基础教程》,在csdn以博客的形式做些笔记。 对于回归问题,线性模型预测的一般公式如下: ŷ w[0] * x[0] w[1] * x[1] … w[p] * x[p] b 这里 x[0] 到 x[p] 表示单个数据点的特征(本例中特…

【机器学习】一文读懂正则化与LASSO回归,Ridge回归

该文已经收录到专题机器学习进阶之路当中,欢迎大家关注。 1.过拟合 当样本特征很多,样本数相对较少时,模型容易陷入过拟合。为了缓解过拟合问题,有两种方法: 方法一:减少特征数量(人工选择重要…

地址总线之寻址原理

译码器将地址总线的数据经过译码后锁定相应的位置,译码器有两种方结构,一种是单译码器,另外一种是双译码器。单译码器适用于存储容量小的应用环境中。双译码器结构将译码器分为两部分一部分是行译码器,另一部分是列译码器。行和列…

[组原]初识-地址总线,地址寄存器,存储单元,存储字长

文章目录 知识点机器字长指令寻址方式按字寻址按字节寻址 存储单元存储字存储字长 💟前记:由一道做错的题总结结果 ⏲ 05.09 知识点 机器字长 计算机进行一次整数运算所能处理的二进制数据的位数;通常也是CPU内部数据通路的宽度;…

地址总线/数据总线/控制总线的作用

数据总线 (1) 是CPU与内存或其他器件之间的数据传送的通道。 (2)数据总线的宽度决定了CPU和外界的数据传送速度。 (3)每条传输线一次只能传输1位二进制数据。eg: 8根数据线一次可传送一个8位二进制数据(…

内存结构、地址总线、数据总线详解

下图为内存的结构图 DB为一个bit,一行DB对应着一个存储单元。 数据总线个数对应着存储单元的位数 数据总线个数 存储单元位数 寄存器位数 如上图所示,内存的结构就是从上到下依次给存储单元编号。 按字节编址 就是每8个bit 对应着一个地址。 读取…

1.8地址总线

现在我们知道,CPU是通过地址总线来指定存储器单元的。可见地址总线上能传送多少个不同的信息,CPU就可以对多少个存储单元进行寻址。 现假设,一个CPU有10根地址总线,让我们来看一下它的寻址情况。我们知道,在电子计算机…

ARM数据/地址总线架构简析

ARM架构简析 1,ARM概述 现在大家讲的ARM的概念实际上是很模糊的,他可能指的是一类芯片,或者指的是ARM公司,亦或者是精简指令集,还是千万人手中的饭碗。下面引用一段关于百度百科关于ARM的准确描述 ARM架构&#xff0…

什么是前端总线,后端总线,内部总线、系统总线,外部总线,地址总线,数据总线,控制总线

文章 部分内容来自于 电子发烧友 内部总线、系统总线和外部总线汇总 部分内容来自于 知乎 前端总线,系统总线,内部总线,外部总线 本文是在两篇文章的基础上进行了二次加工,对两篇文章的精华内容进行了提炼,删掉了对理解…

地址总线是单向还是双向_「计算机组成原理」:总线、地址总线、数据总线和控制总线...

总线(Bus):是计算机各种功能部件之间传送信息的公共通信干线. 总线(Bus):是计算机各种功能部件之间传送信息的公共通信干线,它是由导线组成的传输线束, 按照计算机所传输的信息种类,计算机的总线可以划分为数据总线、地址总线和控制总线,分别用来传输数据、数据地址和控制…

计算机控制总线传输的是,总线,地址总线,数据总线和控制总线

总线(Bus): 这是一条通用的通信干线,可以在计算机的各种功能组件之间传输信息. 它是由电线组成的变速箱线束. 根据计算机传输的信息类型,计算机的总线可以分为数据总线和地址. 总线和控制总线分别用于传输数据,数据地址和控制信号. 总线是一种…