机器学习 | 掌握线性回归的实战技巧

news2024/11/15 8:57:58

目录

初识线性回归

损失和优化

欠拟合与过拟合

正则化线性模型

模型的保存与加载


初识线性回归

线性回归(Linearregression)是利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式。特点是:有一个自变量的情况称为单变量回归,多于一个自变量情况的叫做多元回归。以下是其通用公式的介绍:

线性回归如果用矩阵进行举例的话,可以看如下方式:

比如我们想计算期末成绩,我们可以通过 0.7*考试成绩 + 0.3*平时成绩 进行,通过特征值与目标值建立一个关系,这种关系可以理解为线性模型。

线性回归的特征:线性回归当中主要有两种模型,一种是线性关系,另一种是非线性关系。在这里我们只能画一个平面更好去理解,所以都用单个特征或两个特征举例子。

单变量线性关系
多变量线性关系
非线性关系

通过下面这段代码使用了sklearn库中的 LinearRegression 类来进行线性回归模型的训练和预测。

from sklearn.linear_model import LinearRegression
# 获取数据
x = [
    [80, 86],
    [82, 80],
    [85, 78],
    [90, 90],
    [86, 82],
    [82, 90],
    [78, 80],
    [92, 94]
]
y = [84.2, 80.6, 80.1, 90, 83.3, 87.6, 79.4, 93.5]

# 模型训练
estimator = LinearRegression() # 实例化一个估计器
estimator.fit(x, y) # 使用fit方法进行训练

# 打印对应的系数
print("线性回归的系数是: \n", estimator.coef_)
# 打印的预测结果是
print("输出的预测结果是: \n", estimator.predict([[100, 80]]))

在这段代码中,首先我们定义了输入特征 x 和对应的目标值 y。然后,我们实例化了一个 LinearRegression 对象作为线性回归模型的估计器。接下来,通过调用 fit 方法,我们使用输入特征 x 和目标值 y 对模型进行训练。在训练完成后,我们可以使用 coef_ 属性打印出模型的系数,即特征的权重。最后,我们使用 predict 方法对新的输入数据 [[100, 80]] 进行预测,并打印出预测结果。

损失和优化

在线性回归中,我们使用损失函数和优化算法来训练模型并找到最佳的参数。

损失函数:损失函数用于度量模型预测值与实际目标值之间的差异。在线性回归中,最常用的损失函数是均方误差(Mean Squared Error,MSE)。均方误差计算了预测值与实际值之间的平方差,并求取平均值。公式如下:

1)yi为第i个训练样本的真实值

2)h(xi)为第i个训练样本特征值组合预测函数

如何去减少这个损失,使我们预测的更加准确些?既然存在了这个损失,我们一直说机器学习有自动学习的功能,在线性回归这里更是能够体现。这里可以通过一些优化方法去优化(其实是数学当中的求导功能)回归的总损失!!!

优化算法:优化算法用于调整模型的参数,使得损失函数最小化。在线性回归中,最常用的两种优化算法是:正规方程、梯度下降法。接下来对这两种优化算法作一个简单的介绍:

正规方程:一种通过解析方法来求解最优参数的方法。具体来说,正规方程是通过对损失函数进行求导,并令导数为0,得到最优参数的解析表达式。以下是其使用公式:

理解:x为特征值矩阵,y为目标值矩阵。直接求到最好的结果

缺点:当特征过多过复杂时,求解速度太慢并且得不到结果

接下来以正规方程求解进行举例:

关于正规方程的推导可以参考以下的推导公式:

接下来对所得结果进行求导:

接下来通过下面这段代码实现了一个简单的线性回归模型来预测手写数字数据集中的目标值。下面是对每个步骤的解释:

from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

def liner_model():
    # 获取数据
    digits = load_digits()
    # 数据基本处理
    x_train, x_test, y_train, y_test = train_test_split(digits.data, digits.target, test_size=0.2) # 分割数据
    # 特征过程——标准化
    transfer = StandardScaler()
    transfer.fit_transform(x_train)
    x_test = transfer.fit_transform(x_test)
    # 线性回归——正规方程
    estimator = LinearRegression()
    estimator.fit(x_train, y_train)
    print("这个模型的偏置是: \n", estimator.intercept_)
    print("这个模型的系数是: \n", estimator.coef_)
    # 模型评估
    y_pre = estimator.predict(x_test)
    print("预测值是: \n", y_pre)
    ret = mean_squared_error(y_test, y_pre)
    print("均方误差: \n", ret)

liner_model()

通过线性回归模型对手写数字数据集进行了拟合和预测,并计算了均方误差作为模型评估指标。 

梯度下降法:用于求解线性回归等机器学习模型的参数。其基本思想是通过迭代的方式,根据损失函数关于参数的梯度方向进行更新,直到达到最小化损失函数的参数值。

假设这样一个场景:

一个人被困在山上,需要从山上下来(i.e.找到山的最低点,也就是山谷)。但此时山上的浓雾很大,导致可视度很低。

因此,下山的路径就无法确定,他必须利用自己周围的信息去找到下山的路径。这个时候,他就可以利用梯度下降算法来帮助自己下山。

具体来说就是,以他当前的所处的位置为基准,寻找这个位置最陡峭的地方,然后朝着山的高度下降的地方走,(同理,如果我们的目标是上山,也就是爬到山顶,那么此时应该是朝着最陡峭的方向往上走)。然后每走一段距离,都反复采用同一个方法,最后就能成功的抵达山谷。

梯度下降的基本过程就和下山的场景很类似。

首先,我们有一个可微分的函数。这个函数就代表着一座山。

我们的目标就是找到这个函数的最小值,也就是山底。

根据之前的场景假设,最快的下山的方式就是找到当前位置最陡峭的方向,然后沿着此方向向下走,对应到函数中,就是找到给定点的梯度,然后朝着梯度相反的方向,就能让函数值下降的最快!因为梯度的方向就是函数值变化最快的方向。所以,我们重复利用这个方法,反复求取梯度,最后就能到达局部的最小值,这就类似于我们下山的过程。而求取梯度就确定了最陡峭的方向,也就是场景中测量方向的手段。

梯度的概念

梯度是微积分中一个很重要的概念。

在单变量的函数中,梯度其实就是函数的微分,代表着函数在某个给定点的切线的斜率。

在多变量函数中,梯度是一个向量,向量有方向,梯度的方向就指出了函数在给定点的上升最快的方向。

这也就说明了为什么我们需要千方百计的求取梯度!我们需要到达山底,就需要在每一步观测到此时最陡峭的地方,梯度就恰巧告诉了我们这个方向。梯度的方向是函数在给定点上升最快的方向,那梯度的反方向就是函数在给定点下降最快的方向,这正是我们所需要的。所以我们只要沿着梯度的反方向一直走,就能走到局部的最低点

接下来我们对单变量函数的梯度下降进行举例:

如图,经过四次的运算,也就是走了四步,基本就抵达了函数的最低点,也就是山底:

接下来我们对多变量函数的梯度下降进行举例: 

我们发现已经基本靠近函数的最小值点:

梯度下降公式:

a在梯度下降算法中被称作为学习率或者步长,意味着我们可以通过a来控制每一步走的距离,以保证不要步子跨的太大扯着蛋,哈哈,其实就是不要走太快,错过了最低点。同时也要保证不要走的太慢,导致太阳下山了,还没有走到山下。所以a的选择在梯度下降法中往往是很重要的!a不能太大也不能太小,太小的话,可能导致迟迟走不到最低点,太大的话,会导致错过最低点!

梯度前加一个负号,就意味着朝着梯度相反的方向前进!我们在前文提到,梯度的方向实际就是函数在此点上升最快的方向!而我们需要朝着下降最快的方向走,自然就是负的梯度的方向,所以此处需要加上负号。我们通过两个图更好理解梯度下降的过程:

接下来通过下面这段代码实现了一个使用随机梯度下降(SGD)算法进行线性回归的模型,并对手写数字数据集进行预测和评估:

from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import SGDRegressor
from sklearn.metrics import mean_squared_error

def liner_model():
    # 获取数据
    digits = load_digits()
    # 数据基本处理
    x_train, x_test, y_train, y_test = train_test_split(digits.data, digits.target, test_size=0.2) # 分割数据
    # 特征过程——标准化
    transfer = StandardScaler()
    transfer.fit_transform(x_train)
    x_test = transfer.fit_transform(x_test)
    # 线性回归——梯度下降
    estimator = SGDRegressor()
    estimator.fit(x_train, y_train)
    print("这个模型的偏置是: \n", estimator.intercept_)
    print("这个模型的系数是: \n", estimator.coef_)
    # 模型评估
    y_pre = estimator.predict(x_test)
    print("预测值是: \n", y_pre)
    ret = mean_squared_error(y_test, y_pre)
    print("均方误差: \n", ret)

liner_model()

这段代码通过随机梯度下降算法对手写数字数据集进行了线性回归的拟合和预测,并计算了均方误差作为模型评估指标:

梯度下降和正规方程的对比:

梯度下降正规方程
需要选择学习率不需要
需要迭代求解一次运算得出
特征数量较大可以使用需要计算方程,时间复杂度高O(n3)

欠拟合与过拟合

欠拟合:一个假设在训练数据上不能获得更好的拟合,并且在测试数据集上也不能很好地拟合数据,此时认为这个假设出现了欠拟合的现象。(模型过于简单)

过拟合:一个假设在训练数据上能够获得比其他假设更好的拟合,但是在测试数据集上却不能很好地拟合数据,此时认为这个假设出现了过拟合的现象。 (模型过于复杂)

欠拟合与过拟合的原因及解决办法

在解决回归过拟合中,我们选择正则化。但是对于其他机器学习算法如分类算法来说也会出现这样的问题,除了一些算法本身作用之外(决策树、神经网络),我们更多的也是去自己做特征选择,包括之前说的删除、合并一些特征 

在学习的时候,数据提供的特征有些影响模型复杂度或者这个特征的数据点异常较多,所以算法在学习的时候尽量减少这个特征的影响(甚至删除某个特征的影响),这就是正则化。

正则化线性模型

正则化线性模型是一种通过在损失函数中添加正则化项(L1、L2 或它们的组合)来减少过拟合的线性模型。正则化项在优化过程中对模型的系数进行惩罚,并使得模型更加倾向于选择较小的系数。这样做可以避免模型过度拟合训练数据,从而提高模型在测试集上的泛化能力。

常见的正则化线性模型有:

Lasso Regression(L1 正则化):

在损失函数中添加 L1 正则化项。当系数趋近于零时,Lasso Regression 可以自动地将某些系数设为零,从而实现特征筛选的作用。

Ridge Regression(L2 正则化):

在损失函数中添加 L2 正则化项。Ridge Regression 可以将所有系数缩小到接近于零的水平,但不会将任何系数设为零。

Elastic Net Regression(L1 和 L2 的混合正则化):

在损失函数中同时添加 L1 和 L2 正则化项。Elastic Net Regression 综合了 L1 和 L2 正则化的优点,既可以进行特征筛选,又可以缩小所有系数。

Lasso Regression(Lasso 回归):Lasso回归是线性回归的另一种正则化版本,正则项为权值向量的&1范数:

Ridge Regression(岭回归):岭回归是线性回归的正则化版本,即在原来的线性回归的costfunction中添加正则项(regularizationterm):

以达到在拟合数据的同时,使模型权重尽可能小的目的,岭回归代价函数:

接下来通过下面这段代码实现了一个使用岭回归(Ridge Regression)进行线性回归任务的模型,并对手写数字数据集进行预测和评估:

from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import RidgeCV, Ridge
from sklearn.metrics import mean_squared_error

def liner_model():
    # 获取数据
    digits = load_digits()
    # 数据基本处理
    x_train, x_test, y_train, y_test = train_test_split(digits.data, digits.target, test_size=0.2) # 分割数据
    # 特征过程——标准化
    transfer = StandardScaler()
    transfer.fit_transform(x_train)
    x_test = transfer.fit_transform(x_test)
    # 线性回归——岭回归
    # estimator = Ridge(alpha=1.0)
    estimator = RidgeCV(alphas=(0.001, 0.01, 0.1, 1, 10, 100))
    estimator.fit(x_train, y_train)
    print("这个模型的偏置是: \n", estimator.intercept_)
    print("这个模型的系数是: \n", estimator.coef_)
    # 模型评估
    y_pre = estimator.predict(x_test)
    print("预测值是: \n", y_pre)
    ret = mean_squared_error(y_test, y_pre)
    print("均方误差: \n", ret)

liner_model()

这段代码通过岭回归模型对手写数字数据集进行了线性回归的拟合和预测,并计算了均方误差作为模型评估指标。其中,岭回归通过正则化项控制模型的复杂度,防止过拟合。

Elastic Net Regression(弹性网络)

模型的保存与加载

在机器学习中,模型的保存是指将训练好的机器学习模型以某种格式保存到磁盘上,以便于后续的部署和使用。模型的加载则是指将保存在磁盘上的模型读取到内存中,以便于对新数据进行预测或者进一步的修改和训练。

模型的保存和加载可以提高开发效率,并减少重复训练模型的时间。训练机器学习模型往往需要耗费大量的时间和计算资源,而如果每次需要使用该模型都重新训练一遍,就会非常低效。因此,将训练好的模型保存到磁盘上,在需要使用时直接加载到内存中,可以极大地提高开发效率。此外,保存和加载模型还可以提高模型的可移植性,使得训练好的模型可以轻松地在不同的环境中部署和使用。

模型的保存:我们在进行模型训练完之后,如果想将模型进行保存,导入joblib,然后调用dump传入相应模型以及保存路径即可保存:

打开我们保存好的模型,可见是一堆乱码:

模型的加载:如果要加载模型,这里我们可以不需要再进行模型的训练,直接引入我们加载好的模型进行使用即可:

最终也能得到相应的结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1423031.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux实验记录:使用firewalld

前言: 本文是一篇关于Linux系统初学者的实验记录。 参考书籍:《Linux就该这么学》 实验环境: VmwareWorkStation 17——虚拟机软件 RedHatEnterpriseLinux[RHEL]8——红帽操作系统 备注: RHEL8系统中集成了多款防火墙管理工具&#xf…

【百度Apollo】循迹自动驾驶:探索基于视觉感知的路径规划与控制技术

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《linux深造日志》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! ⛳️ 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下…

牛啊!能透视大模型内部结构的可视化工具!

哈喽,大家好。 今天给大家分享一个非常牛逼的可视化工具,可以清晰了解 GPT 大模型内部的结构。 哦,对了!给大家准备了国内用的 ChatGPT key,见评论区。 这个工具可以支持查看 GPT2 和 GPT3 的网络架构。 但能进行交互…

区间时间检索

参数形式 sql <if test"params.beginOrderDate ! null and params.beginOrderDate ! "><!-- 开始时间检索 -->AND DATEDIFF(day,#{params.beginOrderDate},b.order_date) > 0</if><if test"params.endOrderDate ! null and params.endO…

ov通配符ssl证书申请时间长吗

通配符SSL证书是SSL数字证书的一种&#xff0c;可以同时保护主域名以及同一个域名下的所有子域名。用户在申请通配符SSL证书时需要CA认证机构对提交的信息进行审核&#xff0c;审核时间根据证书的品牌、类型而变化。今天就随SSL盾小编了解OV通配符SSL证书申请时间。 1.通配符S…

蓝桥杯 第 2 场 小白入门赛

目录 1.蓝桥小课堂-平方和 2.房顶漏水啦 3.质数王国 4.取余 5.数学尖子生 6.魔术师 比赛链接 1.蓝桥小课堂-平方和 简单签到直接按照题目处理即可注意开long long void solve(){LL x; cin>>x;LL ans x*(x1)*(2*x1)/6;cout<<ans<<endl; } 2.房顶漏水…

STM32——DMA

STM32——DMA 1.DMA介绍 什么是DMA&#xff1f; DMA(Direct Memory Access&#xff0c;直接存储器访问) 提供在外设与内存、存储器和存储器、外设与外设之间的高速数据传输使用。它允许不同速度的硬件装置来沟通&#xff0c;而不需要依赖于CPU&#xff0c;在这个时间中&…

C语言应用实例——贪吃蛇

&#xff08;图片由AI生成&#xff09; 0.贪吃蛇游戏背景 贪吃蛇游戏&#xff0c;最早可以追溯到1976年的“Blockade”游戏&#xff0c;是电子游戏历史上的一个经典。在这款游戏中&#xff0c;玩家操作一个不断增长的蛇&#xff0c;目标是吃掉出现在屏幕上的食物&#xff0c…

shell - 免交互

一.Here Document 免交互 1. 交互的概念 交互&#xff1a;当计算机播放某多媒体程序的时候&#xff0c;编程人员可以发出指令控制该程序的运行&#xff0c;而不是程序单方面执行下去&#xff0c;程序在接受到编程人员相应的指令后而相应地做出反应。 对于Linux操作系统中&…

【RT-DETR有效改进】Bi-FPN高效的双向特征金字塔网络(附yaml文件+完整代码)

👑欢迎大家订阅本专栏,一起学习RT-DETR👑 一、本文介绍 本文给大家带来的改进机制是BiFPN双向特征金字塔网络,其是一种特征融合层的结构,也就是我们本文改进RT-DETR模型中的Neck部分,它的主要思想是通过多层级的特征金字塔和双向信息传递来提高精度。本文给大家带…

零基础爬什么值得买的榜单——爬虫练习题目一(答一)

完蛋 蚌埠住了 引言日常吐槽言归正传 步骤一分析网页分析网络加载详细说说网络面板实际操作 测试代码测试结果知识点JS和Fetch/XHR是什么&#xff1f;有什么关联&#xff1f;网页数据的中文为什么是16进制数&#xff0c;以及如何判断&#xff1f; 结尾 引言 日常吐槽 今天剪辑…

力扣题目训练(5)

2024年1月29日力扣题目训练 2024年1月29日力扣题目训练345. 反转字符串中的元音字母349. 两个数组的交集350. 两个数组的交集 II96. 不同的二叉搜索树97. 交错字符串44. 通配符匹配 2024年1月29日力扣题目训练 2024年1月29日第五天编程训练&#xff0c;今天主要是进行一些题训…

回归预测 | Matlab基于OOA-LSSVM鱼鹰算法优化最小支持向量机的数据多输入单输出回归预测

回归预测 | Matlab基于OOA-LSSVM鱼鹰算法优化最小支持向量机的数据多输入单输出回归预测 目录 回归预测 | Matlab基于OOA-LSSVM鱼鹰算法优化最小支持向量机的数据多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab基于OOA-LSSVM鱼鹰算法优化最小…

Windows断开映射磁盘提示“此网络连接不存在”,并且该磁盘直在资源管理器中

1、打开注册表编辑器 快捷键winR 打开“运行”&#xff0c; 输入 regedit 2、 删除下列注册表中和无法移除的磁盘相关的选项 \HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2\ 3、打开“任务管理器”&#xff0c;重新启动“Windows资源…

C++指针比较

内存中各个数据的存放方式。 数组str1、str2、str3、str4都是在栈中分配的&#xff0c;内存中的内容都为“abc”加一个“\0”&#xff0c;但是他们的位置是不同的&#xff0c;因此代码第15行和第16行输出的都是0. 指针str5、str6、str7、str8也是在栈中分配的&#xff0c;他们…

Shell中的awk

一、awk 1.1.awk工作原理 逐行读取文本&#xff0c;默认以空格或tab键为分隔符进行分隔&#xff0c;将分隔所得的各个字段保存到内建变量中&#xff0c;并按模式或者条件执行编辑命令。 awk倾向于将一行分成多个"字段"然后再进行处理。 awk信息的读入也是逐行读取…

Apple Vision Pro 评测:这款顶尖头显仅是对未来的初步探索

原文&#xff1a;Apple Vision Pro Review: The Best Headset Yet Is Just a Glimpse of the Future 作者&#xff1a;Joanna Stern 戴上 Apple Vision Pro 混合现实头显整整近 24 小时后&#xff0c;有几件事让我颇感意外&#xff1a; 我居然没感到恶心。我竟然高效完成了大…

springboot---四大核心

四大核心 Starter简介总结 Autoconfigure简介示例原理自定义starter打包实践 总结 CLIActuator Starter 简介 springboot项目中几乎项目依赖中基本上全是各种各样的starter, 那么到底什么是starter? starter是一组方便的依赖描述符&#xff0c;当我们使用它时&#xff0c;可…

推荐系统|排序_多目标模型

文章目录 四大特征用户特征物品特征统计特征场景特征 训练过程中会遇到的问题 四大特征 ID相当于是人拥有的身份证&#xff0c;能够唯一确定出一个人 用户特征 主要指的是用户ID和用户画像 物品特征 主要是指物品ID和物品画像以及物品持有人。 统计特征 统计特征既包括对…

Java并发基础:CompletionService全面解析!

内容概要 CompletionService的优点在于能够解耦任务提交与结果获取&#xff0c;有效的整合线程池与阻塞队列&#xff0c;实现任务完成顺序的处理&#xff0c;提升系统吞吐量&#xff0c;它简化了多线程编程的复杂性&#xff0c;使开发者能够更专注于业务逻辑&#xff0c;而不必…