《机器学习实战》学习记录-ch4

news2025/1/11 10:08:23

4.1 线性回归

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
X = 2 * np.random.rand(100,1) # 生成 [0,1) 之间的数据
y = 4 + 3 * X + np.random.randn(100,1) # 生成一组正态分布的数据, 高斯噪声
X_b = np.c_[np.ones((100,1)), X]
X_b[:5]
array([[1.        , 0.74847244],
       [1.        , 1.03567501],
       [1.        , 0.92533857],
       [1.        , 1.15770818],
       [1.        , 0.46673679]])
theta_best =  np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y) # 公式法求最小loss
theta_best 
array([[4.07095749],
       [2.83726643]])
# 预测
X_new = np.array([[0], [2]])
X_new_b = np.c_[np.ones((2, 1)), X_new] # add x0 = 1 to each instance
y_predict = X_new_b.dot(theta_best)
y_predict
array([[4.07095749],
       [9.74549035]])
plt.plot(X_new, y_predict, "r-")
plt.plot(X, y, "b.")
plt.axis([-1, 3, 0, 15])
plt.show()

在这里插入图片描述

# 用 sklearn 的 LinearRegression
from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(X, y)
lin_reg.intercept_, lin_reg.coef_ # 截距 系数

(array([4.07095749]), array([[2.83726643]]))
lin_reg.predict(X_new)
array([[4.07095749],
       [9.74549035]])
# LinearRegression 基于linalg.lstsq
theta_best_svd, residuals, rank, s = np.linalg.lstsq(X_b, y, rcond=1e-6)
theta_best_svd
array([[4.07095749],
       [2.83726643]])

4.2 梯度下降

通过测量参数向量θ相关的误差函数的局部梯度,并不断沿着降低梯度的方向调整,直到梯度降为0,到达最小值!(降低时间复杂度,不用求逆矩阵)

首先使用一个随机的θ值(这被称为随机初始化),然后逐步改进,每次踏出一步,每一步都尝试降低一点成本函数(如MSE),直到算法收敛出一个最小值
梯度下降中一个重要参数是每一步的步长,这取决于超参数学习率。如果学习率太低,算法需要经过大量迭代才能收敛。反过来说,如果学习率太高,那你可能会越过山谷直接到达另一边,甚至有可能比之前的起点还要高。
线性回归模型的MSE成本函数恰好是个凸函数,这意味着连接曲线上任意两点的线段永远不会跟曲线相交。也就是说,不存在局部最小值,只有一个全局最小值。它同时也是一个连续函数,所以斜率不会产生陡峭的变化[1]
成本函数虽然是碗状的,但如果不同特征的尺寸差别巨大,那它可能是一个非常细长的碗。如图4-7所示的梯度下降,左边的训练集上特征1和特征2具有相同的数值规模,而右边的训练集上,特征1的值则比特征2要小得多(注:因为特征1的值较小,所以θ1需要更大的变化来影响成本函数,这就是为什么碗形会沿着θ1轴拉长。)。

# (全)批量梯度下降
eta = 0.1  # learning rate
n_iterations = 1000
m = 100

theta = np.random.randn(2,1)  # random initialization

for iteration in range(n_iterations):
    gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y)
    theta = theta - eta * gradients
theta
array([[4.07095749],
       [2.83726643]])

请注意,在计算梯度下降的每一步时,都是基于完整的训练集X的。这就是为什么该算法会被称为批量梯度下降:每一步都使用整批训练数据(实际上,全梯度下降可能是个更好的名字)。因此,面对非常庞大的训练集时,算法会变得极慢(不过我们即将看到快得多的梯度下降算法)。但是,梯度下降算法随特征数量扩展的表现比较好。如果要训练的线性模型拥有几十万个特征,

使用梯度下降比标准方程或者SVD要快得多。

4.2.2 随机梯度下降

批量梯度下降的主要问题是它要用整个训练集来计算每一步的梯度,所以训练集很大时,算法会特别慢。与之相反的极端是随机梯度下降,每一步在训练集中随机选择一个实例,并且仅基于该单个实例来计算梯度。显然,这让算法变得快多了,因为每次迭代都只需要操作少量的数据。它也可以被用来训练海量的数据集,因为每次迭代只需要在内存中运行一个实例即可(SGD可以作为核外算法实现,见第1章)。另一方面,由于算法的随机性质,它比批量梯度下降要不规则得多。成本函数将不再是缓缓降低直到抵达最小值,而是不断上上下下,但是从整体来看,还是在慢慢下降。随着时间的推移,最终会非常接近最小值,但是即使它到达了最小值,依旧还会持续反弹,永远不会停止(见图4-9)。所以算法停下来的参数值肯定是足够好的,但不是最优的。

  • 好处:逃离局部最优;训练步骤块
  • 坏处:得不到最优解。
    解决方案:逐步降低学习率。

开始的步长比较大(这有助于快速进展和逃离局部最小值),然后越来越小,让算法尽量靠近全局最小值。这个过程叫作模拟退火,因为它类似于冶金时熔化的金属慢慢冷却的退火过程。

n_epochs = 50
t0, t1 = 5, 50  # learning schedule hyperparameters

def learning_schedule(t):
    return t0 / (t + t1)

theta = np.random.randn(2,1)  # random initialization

for epoch in range(n_epochs): # 退火温度
    for i in range(m): # 每个温度下取 m 次样本
        random_index = np.random.randint(m) # 随机选取一个样本
        xi = X_b[random_index:random_index+1]
        yi = y[random_index:random_index+1]
        gradients = 2 * xi.T.dot(xi.dot(theta) - yi)
        eta = learning_schedule(epoch * m + i)
        theta = theta - eta * gradients
theta
array([[4.06399722],
       [2.793174  ]])

要使用带有Scikit-Learn的随机梯度下降执行线性回归,可以使用SGDRegressor类,该类默认优化平方误差成本函数。以下代码最多可运行1000个轮次,或者直到一个轮次期间损失下降小于0.001为止(max_iter=1000,tol=1e-3)。它使用默认的学习调度(与前一个学习调度不同)以0.1(eta0=0.1)的学习率开始。最后,它不使用任何正则化(penalty=None,稍后将对此进行详细介绍):

# 调用 sklearn的 SGD
from sklearn.linear_model import SGDRegressor
sgd_reg = SGDRegressor(max_iter=1000, tol=1e-3, penalty=None, eta0=0.1)
sgd_reg.fit(X, y.ravel()) # ravel方法将y拉成一维数组
sgd_reg.intercept_, sgd_reg.coef_  # 截距,系数
(array([4.04727747]), array([2.84108153]))

4.2.3 小批量梯度下降

我们要研究的最后一个梯度下降算法称为小批量梯度下降。只要你了解了批量和随机梯度下降,就很容易理解它:在每一步中,不是根据完整的训练集(如批量梯度下降)或仅基于一个实例(如随机梯度下降)来计算梯度,小批量梯度下降在称为小型批量的随机实例集上计算梯度。小批量梯度下降优于随机梯度下降的主要优点是,你可以通过矩阵操作的硬件优化来提高性能,特别是在使用GPU时。

4.3 多项式回归

  • 一元多项式

如果你的数据比直线更复杂怎么办?令人惊讶的是,你可以使用线性模型来拟合非线性数据。一个简单的方法就是将每个特征的幂次方添加为一个新特征,然后在此扩展特征集上训练一个线性模型。这种技术称为多项式回归。

# 生成一些非线性数据
m = 100
X = 6 * np.random.rand(m,1) - 3
y = 0.5 * X **2 + X + 2 + np.random.randn(m,1)
plt.plot(X,y,'b.')
[<matplotlib.lines.Line2D at 0x17cbe209580>]


在这里插入图片描述

from sklearn.preprocessing import PolynomialFeatures
poly_features = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly_features.fit_transform(X)
X[0]
array([-2.81222103])
X_poly[0]
array([-2.81222103,  7.90858713])
lin_reg = LinearRegression()
lin_reg.fit(X_poly, y)
lin_reg.intercept_, lin_reg.coef_
(array([1.85755943]), array([[1.04877191, 0.52580038]]))

在这里插入图片描述

请注意,当存在多个特征时,多项式回归能够找到特征之间的关系(这是普通线性回归模型无法做到的)。PolynomialFeatures还可以将特征的所有组合添加到给定的多项式阶数。例如,如果有两个特征a和b,则degree=3的PolynomialFeatures不仅会添加特征a2、a3、b2和b3,还会添加组合ab、a2b和ab2。
https://blog.csdn.net/qq_45797116/article/details/112787290

4.4 学习曲线

高阶多项式回归可能会出现过拟合(交叉验证,泛化判定)
所以怎么确定多项式次数?-> 观察学习曲线

这个曲线绘制的是模型在训练集和验证集上关于训练集大小(或训练迭代)的性能函数。要生成这个曲线,只需要在不同大小的训练子集上多次训练模型即可。

from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split

def plot_learning_curves(model, X, y):
    X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2)
    train_errors, val_errors = [], []
    for m in range(1, len(X_train)):
        model.fit(X_train[:m], y_train[:m])
        y_train_predict = model.predict(X_train[:m]) # 训练集预测
        y_val_predict = model.predict(X_val)         # 验证集预测
        train_errors.append(mean_squared_error(y_train[:m], y_train_predict))
        val_errors.append(mean_squared_error(y_val, y_val_predict))
    plt.plot(np.sqrt(train_errors), "r-+", linewidth=2, label="train")
    plt.plot(np.sqrt(val_errors), "b-", linewidth=3, label="val")
lin_reg = LinearRegression()
plot_learning_curves(lin_reg, X, y)
plt.legend()
<matplotlib.legend.Legend at 0x17cbe29ebe0>

在这里插入图片描述

首先,让我们看一下在训练数据上的性能:当训练集中只有一个或两个实例时,模型可以很好地拟合它们,这就是曲线从零开始的原因。但是,随着将新实例添加到训练集中,模型就不可能完美地拟合训练数据,这既因为数据有噪声,又因为它根本不是线性的。因此,训练数据上的误差会一直上升,直到达到平稳状态,此时在训练集中添加新实例并不会使平均误差变好或变差。现在让我们看一下模型在验证数据上的性能。当在很少的训练实例上训练模型时,它无法正确泛化,这就是验证误差最初很大的原因。然后,随着模型经历更多的训练示例,它开始学习,因此验证错误逐渐降低。但是,直线不能很好地对数据进行建模,因此误差最终达到一个平稳的状态,非常接近另外一条曲线。这些学习曲线是典型的欠拟合模型。两条曲线都达到了平稳状态。它们很接近而且很高。

  • 如果你的模型欠拟合训练数据,添加更多训练示例将无济于事。你需要使用更复杂的模型或提供更好的特征。
from sklearn.pipeline import Pipeline

polynomial_regression = Pipeline([
        ("poly_features", PolynomialFeatures(degree=10, include_bias=False)),
        ("lin_reg", LinearRegression()),
    ])

plot_learning_curves(polynomial_regression, X, y)
plt.legend()
<matplotlib.legend.Legend at 0x17cbead9550>

在这里插入图片描述

其实后面没有重合的,因为y变化太大被稀释了

  • 改善过拟合模型的一种方法是向其提供更多的训练数据,直到验证误差达到训练误差为止。

模型的泛化误差

  1. 偏差:这部分泛化误差的原因在于错误的假设,比如假设数据是线性的,而实际上是二次的。高偏差模型最有可能欠拟合训练数据。
  2. 方差:这部分是由于模型对训练数据的细微变化过于敏感。具有许多自由度的模型(例如高阶多项式模型)可能具有较高的方差,因此可能过拟合训练数据。
  3. 不可避免的误差。(数据本身的噪声)

4.5 正则化线性模型

减少过拟合的一个好方法是对模型进行正则化(即约束模型):它拥有的自由度越少,则过拟合数据的难度就越大。正则化多项式模型的一种简单方法是减少多项式的次数。对于线性模型,正则化通常是通过约束模型的权重来实现的。

4.5.1 岭回归

岭回归(也称为Tikhonov正则化)是线性回归的正则化版本
在这里插入图片描述

超参数α控制要对模型进行正则化的程度。如果α=0,则岭回归仅是线性回归。如果α非常大,则所有权重最终都非常接近于零,结果是一条经过数据均值的平线

在执行岭回归之前缩放数据(例如使用StandardScaler)很重要,因为它对输入特征的缩放敏感。大多数正则化模型都需要如此。

请注意,α的增加会导致更平坦(即不极端,更合理)的预测,从而减少了模型的方差,但增加了其偏差。(alpha越大,惩罚越大,斜率(权重)不会高)

from sklearn.linear_model import Ridge
ridge_reg = Ridge(alpha=1, solver="cholesky")
ridge_reg.fit(X, y)
ridge_reg.predict([[1.5]])
array([[5.250856]])
# 12 范数 梯度下降
sgd_reg = SGDRegressor(penalty="l2")
sgd_reg.fit(X, y.ravel())
sgd_reg.predict([[1.5]])
array([5.22860513])

4.5.2 Lasso回归

线性回归的另一种正则化叫作最小绝对收缩和选择算子回归,与岭回归一样,它也是向成本函数添加一个正则项,但是它增加的是权重向量的L1范数

。换句话说,Lasso回归会自动执行特征选择并输出一个稀疏模型(即只有很少的特征有非零权重)。

4.5.3 弹性网络

弹性网络是介于岭回归和Lasso回归之间的中间地带。正则项是岭和Lasso正则项的简单混合,你可以控制混合比r。当r=0时,弹性网络等效于岭回归,而当r=1时,弹性网络等效于Lasso回归。

4.5.4 提前停止

使用随机和小批量梯度下降时,曲线不是那么平滑,可能很难知道你是否达到了最小值。一种解决方案是仅在验证错误超过最小值一段时间后停止(当你确信模型不会做得更好时),然后回滚模型参数到验证误差最小的位置。

from sklearn.base import clone

# prepare the data
poly_scaler = Pipeline([
        ("poly_features", PolynomialFeatures(degree=90, include_bias=False)),
        ("std_scaler", StandardScaler())
    ])
X_train_poly_scaled = poly_scaler.fit_transform(X_train)
X_val_poly_scaled = poly_scaler.transform(X_val)

sgd_reg = SGDRegressor(max_iter=1, tol=-np.infty, warm_start=True,
                       penalty=None, learning_rate="constant", eta0=0.0005)

minimum_val_error = float("inf")
best_epoch = None
best_model = None
for epoch in range(1000):
    sgd_reg.fit(X_train_poly_scaled, y_train)  # continues where it left off
    y_val_predict = sgd_reg.predict(X_val_poly_scaled)
    val_error = mean_squared_error(y_val, y_val_predict)
    if val_error < minimum_val_error:
        minimum_val_error = val_error
        best_epoch = epoch
        best_model = clone(sgd_reg)

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

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

相关文章

h265格式怎么转换mp4?一分钟教会你!

H265是一种视频编码标准&#xff0c;也被称为HEVC&#xff08;High Efficiency Video Coding&#xff09;。由联合视频组&#xff08;JVET&#xff09;开发的&#xff0c;是一种专为高清视频设计的压缩标准。播放H265文件&#xff0c;通常需要使用支持H265解码的播放器&#xf…

Docker 网络与Cgroup资源限制

目录 一、Docker 网络实现原理&#xff1a; 二、Docker 的网络模式&#xff1a; 三、网络模式详解&#xff1a; 1. host模式&#xff1a; 2. container模式&#xff1a; 3. none模式: 4&#xff0e;bridge模式: 5&#xff0e;自定义网络: 四、Cgroup资源控制&#xff1a; …

仿真调试stm32汇编代码

软件准备 ubuntu交叉编译链工具&#xff1a;arm-none-eabi-gcc, arm-none-eabi-as, arm-none-eabi-ldqemu仿真软件&#xff1a;支持stm32版本调试工具&#xff1a;gdb-multiarch 启动仿真实验 汇编代码 .thumb .syntax unified.equ STACKINIT, 0x20005000.section .text .o…

玩具玩偶经营小程序商城的作用是什么

对品牌商而言&#xff0c;传统的批发商模式&#xff0c;不利于品牌传播及构建自有私域流量池&#xff0c;无法与消费者面对面交流&#xff0c;一旦销售量不好&#xff0c;只能受限于下游的以销定产。无论销售商还是品牌商即使入驻第三方平台&#xff0c;也会面临佣金、广告位问…

开发习惯养成系列

1 开发习惯养成系列 2

【趣味Javascript】前端开发中不为人知的LHS和RHS查询,你真的弄明白了吗? 《1024程序员节特别篇》

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&#x1…

你知道AI数字人可以用在哪些行业吗?

引言&#xff1a; 随着科技的不断进步&#xff0c;人工智能&#xff08;AI&#xff09;已经渗透到各个领域&#xff0c;其中包括宣传营销。AI数字人是宣传营销领域的一项革命性技术&#xff0c;它们为企业提供了全新的机会&#xff0c;从客户互动到市场分析&#xff0c;再到销…

jenkins实践篇(1)——基于分支的自动发布

问题背景 想起初来公司时&#xff0c;我们还是在发布机上直接执行发布脚本来运行和部署服务&#xff0c;并且正式环境和测试环境的脚本都在一起&#xff0c;直接手动操作脚本时存在比较大的风险就是将环境部署错误&#xff0c;并且当时脚本部署逻辑还没有检测机制&#xff0c;…

初学编程入门基础教学视频,初学编程学什么语言

学习编程捷径&#xff1a;&#xff08;不论是正在学习编程的大学生&#xff0c;还是IT人士或者是编程爱好者&#xff0c;在学习编程的过程中用正确的学习方法可以达到事半功倍的效果。对于初学者&#xff0c;可以通过下面的方法学习编程&#xff0c;通过对成百上千个实例练习&a…

ilr normalize isometric log-ratio transformation

visium_heart/st_snRNAseq/05_colocalization/create_niches_ct.R at 5b30c7e497e06688a8448afd8d069d2fa70ebcd2 saezlab/visium_heart (github.com) 更多内容&#xff0c;关注微信&#xff1a;生信小博士 The ILR (Isometric Log-Ratio) transformation is used in the anal…

Spring Boot集成RESTful API

在Spring Boot中集成一个RESTful API是我们在实际开发中较为常见的一种开发任务&#xff0c;以下通过一个小的案例来展示在Spring Boot中创建RESTful API来编写一个单元测试。 本节使用到的注解&#xff1a; Controller&#xff1a;修饰class&#xff0c;用来创建处理http请求的…

让锅碗瓢盆变成我们生活的快乐插曲

&#x1f31f;现代生活中&#xff0c;厨房不再只是一个独立的烹饪区域&#xff0c;而是成为了家庭生活的核心。开放式厨房的设计概念已经成为越来越多家庭的选择&#xff0c;它不仅为我们带来了便利和舒适&#xff0c;还创造了一种与家人和朋友共享美食的愉悦体验。让我们一起探…

线程池常见面试题总结

线程池的工作原理和实现已经在之前的文章中介绍 本文主要总结面试中线程池常问题目。 1、有几种常见的线程池&#xff08;必知必会&#xff09;? 1&#xff09;定长线程池&#xff08;FixedThreadPool&#xff09; 2&#xff09;定时线程池&#xff08;ScheduledThreadPoo…

25.2 MySQL 运算符

1. 伪表 在MySQL中, DUAL是一个特殊的单行, 单列的虚拟表, 主要用于在SELECT语句中计算表达式或执行函数, 而不需要从实际的数据表中检索数据. 使用DUAL的原因主要有以下几点:* 1. 简化计算: 通过在SELECT语句中使用DUAL, 可以方便地计算表达式或执行函数, 而无需创建临时表或…

android点击全屏预览照片第三方库使用

android点击全屏预览照片第三方库使用-imgepreviewlibrary 移动端我们经常会遇到放大预览照片&#xff0c;如果是一张照片&#xff0c;那就全屏展示图片就好了&#xff0c;但是如果是一个列表&#xff0c;滑动查看&#xff0c;我们一般会借助viewpager进行实现&#xff0c;但是…

【鸿蒙软件开发】ArkTS通用事件

文章目录 前言一、点击事件1.1 基础介绍1.2 ClickEvent对象说明1.3 示例代码 二、触摸事件2.1 基础介绍2.2 ClickEvent对象说明2.3 示例代码 二、焦点事件2.2 基础介绍3.2 示例代码 总结 前言 在我们的ArkTS中有一些通用的事件&#xff0c;他们在所有的组件中都可以用&#xf…

号外!百度Comate代码助手全新上线SaaS服务 - 免费申请试用+深入教程解读!

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

全国高清影像数据导出TIF有多大?

全国数据导出为TIF文件之后有多大呢&#xff1f; 我们今天来分析探讨一下这个问题。 01背景 最近&#xff0c;有用户提出在交付数据时&#xff0c;需要交付TIF格式的数据&#xff0c;但我们的地图是基于自研的DAT格式分块存储。 我们在《毫不费力&#xff0c;让内网多一个…

外汇天眼:假冒违法平台害人害己,监管“铁拳”打击!

近年来&#xff0c;金融市场上的假冒违法平台问题日益严重&#xff0c;给投资者和监管机构带来了巨大的挑战。对此&#xff0c;英国FCA、意大利CONSOB和塞浦路斯CySEC等监管机构纷纷出手&#xff0c;打击假冒违法平台&#xff0c;以保护投资者的权益&#xff0c;整肃整个外汇市…

利用Windows自有工具,校验md5值

使用winr&#xff0c;打开cmd命令行窗口 去到对应目录中 对指定目录下的iso进行校验 具体命令行命令为&#xff1a; certutil -hashfile <文件名> <hash类型> md5 SHA1 SHA256都是可以校验的&#xff0c;但我工作中经常校验md5值&#xff0c;就先用了。 很久不写…