手写算法-python代码实现Ridge(L2正则项)回归

article/2025/9/16 21:52:19

手写算法-python代码实现Ridge回归

  • Ridge简介
  • Ridge回归分析与python代码实现
    • 方法一:梯度下降法求解Ridge回归参数
    • 方法二:标准方程法实现Ridge回归
    • 调用sklearn对比

Ridge简介

前面2篇文章,我们介绍了过拟合与正则化,比较全面的讲了L1、L2正则化的原理与特点;
链接: 原理解析-过拟合与正则化

以及python代码实现Lasso回归;
链接: 手写算法-python代码实现Lasso回归

今天,我们在这基础上,讲一讲Ridge回归,就比较简单了,
本文主要实现python代码的Ridge回归(带L2正则项),并用实例佐证原理。

Ridge回归分析与python代码实现

引用上篇文章的生成的数据集:

import numpy as np
from matplotlib import pyplot as plt
import sklearn.datasets#生成100个一元回归数据集
x,y = sklearn.datasets.make_regression(n_features=1,noise=5,random_state=2020)
plt.scatter(x,y)
plt.show()#加5个异常数据,为什么这么加,大家自己看一下生成的x,y的样子
a = np.linspace(1,2,5).reshape(-1,1)
b = np.array([350,380,410,430,480])#生成加入异常数据后新的数据集
x_1 = np.r_[x,a]
y_1 = np.r_[y,b]plt.scatter(x_1,y_1)
plt.show()

在这里插入图片描述
在这里插入图片描述
以上分别是正常数据集和加入了5个异常数据的图像,如果直接用线性回归拟合:

class normal():def __init__(self):passdef fit(self,x,y):m=x.shape[0]X = np.concatenate((np.ones((m,1)),x),axis=1)xMat=np.mat(X)yMat =np.mat(y.reshape(-1,1))xTx=xMat.T*xMat#xTx.I为xTx的逆矩阵ws=xTx.I*xMat.T*yMat#返回参数return wsplt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
clf1 =normal()
#拟合原始数据
w1 = clf1.fit(x,y)
#预测数据
y_pred = x * w1[1] + w1[0]#拟合新数据
w2 = clf1.fit(x_1,y_1)
#预测数据
y_1_pred = x_1 * w2[1] + w2[0]print('原始样本拟合参数:\n',w1)
print('\n')
print('新样本拟合参数:\n',w2)ax1= plt.subplot()
ax1.scatter(x_1,y_1,label='样本分布')
ax1.plot(x,y_pred,c='y',label='原始样本拟合')
ax1.plot(x_1,y_1_pred,c='r',label='新样本拟合')
ax1.legend(prop = {'size':15}) #此参数改变标签字号的大小
plt.show()

在这里插入图片描述
因为几个异常点数据,新的拟合回归线参数变大了很多,从19点多变成了47点多;脱离了实际数据的分布,模型性能下降。

我们加入L2正则项,来调优模型。下面是L2正则化的损失函数;
在这里插入图片描述

方法一:梯度下降法求解Ridge回归参数

前面文章我们都推导过线性回归的梯度和L2正则项的梯度,这个的梯度就是两者相加,算了,还是写一下:
在这里插入图片描述
编写python代码如下(就是在原来的线性回归梯度上,加上L2的梯度):

class ridge():def __init__(self):pass#梯度下降法迭代训练模型参数,x为特征数据,y为标签数据,a为学习率,epochs为迭代次数,Lambda为正则项参数def fit(self,x,y,a,epochs,Lambda):  #计算总数据量m=x.shape[0]#给x添加偏置项X = np.concatenate((np.ones((m,1)),x),axis=1)#计算总特征数n = X.shape[1]#初始化W的值,要变成矩阵形式W=np.mat(np.ones((n,1)))#X转为矩阵形式xMat = np.mat(X)#y转为矩阵形式,这步非常重要,且要是m x 1的维度格式yMat =np.mat(y.reshape(-1,1))#循环epochs次for i in range(epochs):gradient = xMat.T*(xMat*W-yMat)/m + Lambda * WW=W-a * gradientreturn Wdef predict(self,x,w):  #这里的x也要加偏置,训练时x是什么维度的数据,预测也应该保持一样return np.dot(x,w)

ridge()函数来实现我们的Ridge回归,示例(以下的参数都是我经过调试,确认可以使模型收敛,继续加大迭代次数或者改变学习率,最终的模型系数也不改变):

当Lambda参数为0时,也就是不加L2正则项时,就是普通的线性回归,参数输出都是一样的,也是47点多

#Lambda=0时;
clf = ridge()
w = clf.fit(x_1,y_1,a = 0.001,epochs = 10000,Lambda=0)
print(w)#计算新的拟合值
y_1_pred = x_1 * w[1] + w[0]ax1= plt.subplot()
ax1.scatter(x_1,y_1,label='样本分布')
ax1.plot(x,y_pred,c='y',label='原始样本拟合')
ax1.plot(x_1,y_1_pred,c='r',label='新样本拟合')
ax1.legend(prop = {'size':15}) #此参数改变标签字号的大小
plt.show()

在这里插入图片描述

当Lambda =0.5时,参数变为31点多;

#Lambda=0.5时;
clf = ridge()
w = clf.fit(x_1,y_1,a = 0.001,epochs = 10000,Lambda=0.5)
print(w)#计算新的拟合值
y_1_pred = x_1 * w[1] + w[0]ax1= plt.subplot()
ax1.scatter(x_1,y_1,label='样本分布')
ax1.plot(x,y_pred,c='y',label='原始样本拟合')
ax1.plot(x_1,y_1_pred,c='r',label='新样本拟合')
ax1.legend(prop = {'size':15}) #此参数改变标签字号的大小
plt.show()

在这里插入图片描述

当Lambda =1.5时,参数变为18点多,基本上已经和没添加异常值的参数是一样的了;

#Lambda=1.5时;
clf = ridge()
w = clf.fit(x_1,y_1,a = 0.001,epochs = 10000,Lambda=1.5)
print(w)#计算新的拟合值
y_1_pred = x_1 * w[1] + w[0]ax1= plt.subplot()
ax1.scatter(x_1,y_1,label='样本分布')
ax1.plot(x,y_pred,c='y',label='原始样本拟合')
ax1.plot(x_1,y_1_pred,c='r',label='新样本拟合')
ax1.legend(prop = {'size':15}) #此参数改变标签字号的大小
plt.show()

在这里插入图片描述

当Lambda =20时,参数是2点多,拟合线差不多就是一条水平线了,此时严重欠拟合,损失函数值很大,模型完全没有收敛;

#Lambda=20时;
clf = ridge()
w = clf.fit(x_1,y_1,a = 0.001,epochs = 10000,Lambda=20)
print(w)#计算新的拟合值
y_1_pred = x_1 * w[1] + w[0]ax1= plt.subplot()
ax1.scatter(x_1,y_1,label='样本分布')
ax1.plot(x,y_pred,c='y',label='原始样本拟合')
ax1.plot(x_1,y_1_pred,c='r',label='新样本拟合')
ax1.legend(prop = {'size':15}) #此参数改变标签字号的大小
plt.show()

在这里插入图片描述
可以发现,合适的L2正则项参数,可以防止过拟合;
当Lambda参数一越来越大时,模型参数也越来越小,慢慢接近于0。

方法二:标准方程法实现Ridge回归

接下来,我们用标准方程法实现Ridge回归,推导公式如下:
在这里插入图片描述python代码实现如下:

class standard_ridge():def __init__(self):passdef fit(self,x,y,Lambda):m = x.shape[0]X = np.concatenate((np.ones((m,1)),x),axis=1)xMat= np.mat(X)yMat = np.mat(y.reshape(-1,1))xTx = xMat.T * xMat#生成单位矩阵,2个矩阵行列相等才可以相加#前面的梯度下降法代码中,我们没有省掉m,因此,我们化简时,也不省掉m,最后形式就是在正则项梯度这里乘以m,其实不会造成本质影响rxTx = xTx + np.eye(xMat.shape[1]) * Lambda * m#rxTx.I为rxTx的逆矩阵w = rxTx.I * xMat.T * yMatreturn w

以下是运行结果:
在这里插入图片描述
基本上结果一样,但是这种形式,更简洁方便一些。

调用sklearn对比

from sklearn.linear_model import Ridge
lr=Ridge(alpha=0)
lr.fit(x_1,y_1)
print('alpha=0时',lr.coef_,'\n')lr=Ridge(alpha=40)
lr.fit(x_1,y_1)
print('alpha=40时',lr.coef_,'\n')lr=Ridge(alpha=150)
lr.fit(x_1,y_1)
print('alpha=150时',lr.coef_,'\n')lr=Ridge(alpha=2000)
lr.fit(x_1,y_1)
print('alpha=2000时',lr.coef_)

在这里插入图片描述

sklearn展示Ridge:

1、随着alpha值的增大,也就是正则项系数增大,系数变得越来越接近于0,但是没有等于0的。

#用波士顿房价回归数据集展示
data =  sklearn.datasets.load_boston()
x =data['data']
y= data['target']lr=Ridge(alpha=0)
lr.fit(x,y)
print('alpha=0时',lr.coef_,'\n')lr=Ridge(alpha=10)
lr.fit(x,y)
print('alpha=10时',lr.coef_,'\n')lr=Ridge(alpha=100)
lr.fit(x,y)
print('alpha=100时',lr.coef_,'\n')lr=Ridge(alpha=1000)
lr.fit(x,y)
print('alpha=1000时',lr.coef_)

在这里插入图片描述
总结:线性回归系列我们就介绍到这里了,因为很多概念都是第一次讲,所以写的很细致,辅以数据实例展示,保证读者可以看得懂,同时手动复现,这些基础概念讲清楚了,也方便后面讲解复杂算法。

接下来介绍逻辑回归。


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

相关文章

线性模型-Ridge-Lasso-回归

目录 1 基本库导入2 线性回归2.1 线性模型性能2.2 使用更高维的数据集 3 岭回归-Ridge3.1 Ridge原理及应用3.2 Ridge调参3.3 为什么要用Ridge 4 Lasso4.1 基本原理及应用4.2 Lasso调参4.3 为什么要用Lasso4.4 Lasso和Ridge的区别(L1,L2区别) …

利用python实现Ridge岭回归和Lasso回归

正则化 regularization 在介绍Ridge和Lasso回归之前,我们先了解一下正则化 过拟合和欠拟合 (1) under fit:还没有拟合到位,训练集和测试集的准确率都还没有到达最高。学的还不 到位。 (2) over fit:拟合过度,训练…

数学推导+纯Python实现机器学习算法14:Ridge岭回归

点击上方“小白学视觉”,选择加"星标"或“置顶” 重磅干货,第一时间送达 上一节我们讲到预防过拟合方法的Lasso回归模型,也就是基于L1正则化的线性回归。本讲我们继续来看基于L2正则化的线性回归模型。 L2正则化 相较于L0和L1&…

【机器学习】多项式回归案例五:正则惩罚解决过拟合(Ridge回归和Lasso回归)

正则惩罚解决过拟合(Ridge回归和Lasso回归) 案例五: 正则惩罚解决过拟合(Ridge回归和Lasso回归)3.2.1 模块加载与数据读入3.2.2 特征工程3.2.3 模型搭建与应用 手动反爬虫,禁止转载: 原博地址 …

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

归一化: 减少数据不同数量级对预测的影响, 主要是将数据不同属性的数据都降到一个数量级。 最大值最小值归一化:优点是可以把所有数值归一到 0~1 之间,缺点受离群值影响较大。0-均值标准化: 经过处理的数据符合标准正态分布,即均值为0,标准差…

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 对应着一个地址。 读取…