机器学习03-线性回归

线性回归

线性回归介绍

学习目标:

1.理解线性回归是什么?

2.知道一元线性回归和多元线性回归的区别

3.知道线性回归的应用场景

[理解]举个例子

假若有了身高和体重数据,来了播仔的身高,你能预测播仔体重吗?

这是一个回归问题,该如何求解呢?
思路 :先从已知身高X和体重Y中找规律,再预测

• 数学问题:用一条线来拟合身高和体重之间的关系,再对新数据进行预测

方程 Y = kX + b

k160 + b = 56.3 ---- (1)

k166 + b = 60.6 ---- (2)

...

k: 斜率 b:截距

若:y = 0.9 x + (-93)

​ 0.9*176 +(-93)= ?

【理解】线性回归

线性回归(Linear regression)是利用 回归方程(函数)一个或多个自变量(特征值)和因变量(目标值)之间 关系进行建模的一种分析方式。

注意事项:

1 为什么叫线性模型?因为求解的w,都是w的零次幂(常数项)所以叫成线性模型

2 在线性回归中,从数据中获取的规律其实就是学习权重系数w

3 某一个权重值w越大,说明这个权重的数据对房子价格影响越大

【知道】线性回归分类

  • 一元线性回归

y = kx +b

目标值只与一个因变量有关系

  • 多元线性回归

目标值只与多个因变量有关系

【知道】应用场景

线性回归问题的求解

学习目标:

1.知道线性回归API的使用

2.知道损失函数是什么

3.复习导数和矩阵的相关内容

4.理解正规方程法

5.掌握梯度下降算法的内容

【实操】线性回归API的应用

预测播仔身高

已知数据:

需求:播仔身高是176,请预测体重?

通过线性回归API可快速的找到一条红色直线,是怎么求解的呢?

【掌握】损失函数

需要设置一个评判标准

误差概念:用 (预测值y -- 真实值y) 就是误差

损失函数 :衡量每个样本预测值与真实值效果的函数,"红色直线能更好的拟合所有点"也就是误差最小,误差和最小。损失函数数学如何表达呢?又如何求损失函数的最小值呢?

当损失函数取最小值时,得到k就是最优解

想求一条直线更好的拟合所有点 y = kx + b

  • 引入损失函数(衡量预测值和真实值效果) Loss(k, b)
  • 通过一个优化方法,求损失函数最小值,得到K最优解

回归的损失函数:

  • 均方误差 (Mean-Square Error, MSE)
  • 平均绝对误差 (Mean Absolute Error , MAE)
  • 最小二乘法 : 误差平方和


【复习】导数和矩阵

【知道】常见的数据表述
  • 为什么要学习标量、向量、矩阵、张量?
    • 因机器学习、深度学习中经常用,不要因是数学就害怕
    • 宗旨:用到就学什么,不要盲目的展开、大篇幅学数学
  • 标量scalar :一个独立存在的数,只有大小没有方向
  • 向量vector :向量指一列顺序排列的元素。默认是列向量
  • 矩阵matrix :二维数组
  • 张量Tensor :多维数组,张量是基于向量和矩阵的推广
【知道】导数

当函数y=f(x)的自变量x在一点 x 0 x_0 x0上产生一个增量Δx时,函数输出值的增量Δy与自变量增量Δx的比值在Δx趋于0时的极限a如果存在,a即为在 x 0 x_0 x0处的导数,记作 f ′ ( x 0 ) f^\prime(x_0) f′(x0)或df( x 0 x_0 x0)/dx。

导数是函数的局部性质。一个函数在某一点的导数描述了这个函数在这一点附近的变化率。函数在某一点的导数就是该函数所代表的曲线在这一点上的切线斜率。常见函数的导数:

导数的四则运算:

复合函数求导:g(h)是外函数 h(x)是内函数。先对外函数求导,再对内函数求导

导数求极值:导数为0的位置是函数的极值点


【知道】向量

向量运算:

【知道】矩阵




【了解】一元线性回归的解析解



【了解】多元线性回归的解析解-正规方程法

多元线性回归-正规方程法



梯度下降算法

【掌握】梯度下降算法思想

什么是梯度下降法

• 求解函数极值还有更通用的方法就是梯度下降法。顾名思义:沿着梯度下降的方向求解极小值 • 举个例子:坡度最陡下山法

  • 输入:初始化位置S;每步距离为a 。输出:从位置S到达山底
  • 步骤1:令初始化位置为山的任意位置S
  • 步骤2:在当前位置环顾四周,如果四周都比S高返回S;否则执行步骤3
  • 步骤3: 在当前位置环顾四周,寻找坡度最陡的方向,令其为x方向
  • 步骤4:沿着x方向往下走,长度为a,到达新的位置S'
  • 步骤5:在S'位置环顾四周,如果四周都比S'高,则返回S'。否则转到步骤3

小结:通过循环迭代的方法不断更新位置S (相当于不断更新权重参数w)

最终找到最优解 这个方法可用来求损失函数最优解, 比正规方程更通用

复制代码
梯度下降过程就和下山场景类似
可微分的损失函数,代表着一座山
寻找的函数的最小值,也就是山底





【理解】银行信贷案例




【了解】梯度下降算法分类





全梯度下降(FGD)

复制代码
全梯度下降算法(Full Gradient Descent, FGD):也常被称为批量梯度下降(Batch Gradient Descent, BGD),是梯度下降算法最基础的形式。
它的核心思想是在每次更新模型参数时,都使用训练集中的全部样本来计算损失函数的梯度。
核心原理

全梯度下降算法的目标是通过迭代,找到一组最优的模型参数(如权重 θ),使得模型在训练数据上的预测误差(即损失函数 J(θ))最小。在每次迭代中,算法会:

1.使用所有 m 个训练样本计算损失函数关于参数的梯度。

2.沿着梯度的反方向更新参数,因为梯度方向是函数增长最快的方向,反方向则是下降最快的方向。其参数更新公式为:

复制代码
θ = θ - η ⋅ ∇J(θ)
其中:
θ 代表模型参数。
η (eta) 是学习率,一个超参数,用于控制每次更新的步长大小。
∇J(θ) 是损失函数 J(θ) 关于参数 θ 的梯度。对于包含 m 个样本的数据集,这个梯度是所有样本梯度的平均值。
场景设定

假设我们有一个非常简单的线性回归任务,目标是拟合一个模型 y = w * x + b。

训练数据:我们只有3个样本点。

x = [1, 2, 3]

y = [2, 4, 6]

损失函数:我们使用均方误差(MSE)来衡量模型的预测误差。

J(w, b) = (1/2m) * Σ(w*xᵢ + b - yᵢ)²

其中 m 是样本数量,这里是3。

初始参数:我们随机初始化参数 w = 0, b = 0。

超参数:设定学习率 η = 0.1。

手动计算第一步迭代

全梯度下降的关键在于,每一次参数更新都需要使用全部3个样本来计算梯度。

1.计算预测值

使用初始参数 w=0, b=0 对所有样本进行预测:

ŷ₁ = 0 * 1 + 0 = 0

ŷ₂ = 0 * 2 + 0 = 0

ŷ₃ = 0 * 3 + 0 = 0

2.计算梯度

我们需要分别计算损失函数对 w 和 b 的偏导数(即梯度)。梯度的计算需要对所有样本的误差求和。

计算 w 的梯度 ∇w:

∇w = (1/m) * Σ(ŷᵢ - yᵢ) * xᵢ

∇w = (1/3) * [ (0-2)*1 + (0-4)*2 + (0-6)*3 ]

∇w = (1/3) * [ -2 - 8 - 18 ]

∇w = -28 / 3 ≈ -9.33

计算 b 的梯度 ∇b:

∇b = (1/m) * Σ(ŷᵢ - yᵢ)

∇b = (1/3) * [ (0-2) + (0-4) + (0-6) ]

∇b = (1/3) * [ -2 - 4 - 6 ]

∇b = -12 / 3 = -4

3.更新参数

使用计算出的梯度和学习率来更新 w 和 b。

更新 w:

w_new = w_old - η * ∇w

w_new = 0 - 0.1 * (-9.33) = 0.933

更新 b:

b_new = b_old - η * ∇b

b_new = 0 - 0.1 * (-4) = 0.4

经过第一轮迭代,我们的模型参数从 [w=0, b=0] 更新为了 [w=0.933, b=0.4]。

后续迭代与收敛

接下来,算法会重复上述过程:

1.使用新的参数 w=0.933, b=0.4 重新计算所有样本的预测值。

2.基于新的预测值和真实值,再次计算 w 和 b 的梯度。

3.再次更新参数。

这个过程会不断循环,直到参数变化非常小或达到预设的迭代次数。最终,w 和 b 的值会越来越接近真实值(在这个例子中,真实关系是 y = 2x,所以理想的 w 应该接近2,b 应该接近0)。

小批量梯度下降(MBGD)

复制代码
小批量梯度下降(Mini-batch Gradient Descent, MBGD)是目前深度学习领域最主流、最标准的优化算法。
简单来说,它是"全梯度下降"(每次看全部数据)和"随机梯度下降"(每次只看一个数据)的折中方案。
它在每次更新参数时,只使用一小部分数据(即一个"小批量"或"Mini-batch")来计算梯度。

为了更直观地理解,可以用一个生动的比喻:

复制代码
想象你在下山(寻找最低点/最优解):
全梯度下降 (BGD):每走一步,你都要停下来,测量整座山上所有点的坡度,算出最准确的方向再走。虽然方向准,但太累太慢。
随机梯度下降 (SGD):你闭着眼睛,随便抓一个路人问"哪边是下坡",然后就走。速度很快,但容易被个别路人误导,走得跌跌撞撞。
小批量梯度下降 (MBGD):你每次找一小群人(比如32个人)商量一下,取他们意见的平均值来决定方向。既比问整座山的人快,又比只听一个人的更靠谱、更稳当。

核心原理

假设你有 1000 条训练数据:

1.切分数据:你不会一次性把 1000 条都塞进模型,也不会一次只喂 1 条。你会把它们分成若干个小批次(Batch),比如每个批次包含 32 条数据(Batch Size = 32)。

2.计算梯度:模型只看这 32 条数据,计算损失函数的梯度。

3.更新参数:根据计算出的梯度更新一次模型参数。

4.循环:接着看下一批 32 条数据,重复上述过程,直到遍历完所有数据。

数学公式:

参数更新公式与全梯度下降类似,只是求和的范围变了:
θ = θ - η ⋅ (1/b) * Σ ∇J(θ)

其中 b 是小批量的大小(例如 32),而不是总样本数 m。

场景设定

假设我们有一个简单的线性回归任务,目标是拟合模型 y = w * x + b。

训练数据:我们有 6 个样本点,真实关系是 y = 2x。

x = [1, 2, 3, 4, 5, 6]

y = [2, 4, 6, 8, 10, 12]

损失函数:使用均方误差(MSE)。

J(w, b) = (1/2b) * Σ(w*xᵢ + b - yᵢ)²

注意:这里的 b 指的是小批量(batch)的大小,而不是偏置项。

初始参数:随机初始化 w = 0, b = 0。

超参数:

学习率 η = 0.1,小批量大小 (Batch Size) = 2

手动计算第一轮迭代 (Epoch 1)

与全梯度下降不同,小批量梯度下降在每一轮(Epoch)中会进行多次参数更新。我们将数据分成 3 个小批量(6个样本 / 批量大小2 = 3个批次)。

第1步:处理第一个小批量 (样本1, 2)

1.取数据:x_batch = [1, 2], y_batch = [2, 4]

2.计算预测值 (使用 w=0, b=0):

ŷ₁ = 0 * 1 + 0 = 0

ŷ₂ = 0 * 2 + 0 = 0

3.计算梯度 (仅对这2个样本求和):

∇w = (1/2) * [ (0-2)*1 + (0-4)*2 ] = (1/2) * [-2 - 8] = -5

∇b = (1/2) * [ (0-2) + (0-4) ] = (1/2) * [-6] = -3

4.更新参数:

w = 0 - 0.1 * (-5) = 0.5

b = 0 - 0.1 * (-3) = 0.3

参数已经更新了一次!

第2步:处理第二个小批量 (样本3, 4)

注意:现在我们使用的是刚刚更新过的参数 w=0.5, b=0.3。

1.取数据:x_batch = [3, 4], y_batch = [6, 8]

2.计算预测值:

ŷ₃ = 0.5 * 3 + 0.3 = 1.8

ŷ₄ = 0.5 * 4 + 0.3 = 2.3

3.计算梯度:

∇w = (1/2) * [ (1.8-6)*3 + (2.3-8)*4 ] = (1/2) * [-12.6 - 22.8] = -17.7

∇b = (1/2) * [ (1.8-6) + (2.3-8) ] = (1/2) * [-9.9] = -4.95

4.更新参数:

w = 0.5 - 0.1 * (-17.7) = 2.27

b = 0.3 - 0.1 * (-4.95) = 0.795

参数再次更新,并且变化很大,因为模型正在快速学习。

第3步:处理第三个小批量 (样本5, 6)

使用最新的参数 w=2.27, b=0.795。

1.取数据:x_batch = [5, 6], y_batch = [10, 12]

2.计算预测值:

ŷ₅ = 2.27 * 5 + 0.795 = 12.145

ŷ₆ = 2.27 * 6 + 0.795 = 14.415

3.计算梯度:

∇w = (1/2) * [ (12.145-10)*5 + (14.415-12)*6 ] = (1/2) * [10.725 + 14.49] = 12.6075

∇b = (1/2) * [ (12.145-10) + (14.415-12) ] = (1/2) * [4.56] = 2.28

4.更新参数:

w = 2.27 - 0.1 * (12.6075) = 1.00925

b = 0.795 - 0.1 * (2.28) = 0.567

第一轮迭代结束! 我们可以看到,仅仅一轮,参数就经过了3次更新,从 [0, 0] 变成了 [1.009, 0.567],正在向真实值 [2, 0] 靠近。

随机梯度下降(SGD)

复制代码
随机梯度下降(Stochastic Gradient Descent, SGD)是机器学习中一种基础且核心的优化算法。
它的核心思想非常直接:在每次更新模型参数时,只随机抽取一个训练样本来计算梯度并更新参数。
核心原理与公式

SGD 的目标是找到一组模型参数(用 θ 表示,比如权重和偏置),使得模型的预测误差(即损失函数 J(θ))最小。在每次迭代中,SGD 会:

1.从数据集中随机抽取一个样本 (xᵢ, yᵢ)。

2.只根据这个样本计算损失函数的梯度。

3.沿着梯度的反方向更新参数,因为梯度方向是函数值增长最快的方向,反方向则是下降最快的方向。

其参数更新公式为:
θ = θ - η ⋅ ∇J(θ; xᵢ, yᵢ)

其中:

θ 代表模型参数。

η (eta) 是学习率,一个超参数,控制每次更新的步长大小。

∇J(θ; xᵢ, yᵢ) 是损失函数在单个样本 (xᵢ, yᵢ) 上的梯度。

场景设定

为了便于比较,我们沿用之前的线性回归任务,目标是拟合模型 y = w * x + b。

训练数据:我们有 6 个样本点,真实关系是 y = 2x。

x = [1, 2, 3, 4, 5, 6]

y = [2, 4, 6, 8, 10, 12]

损失函数:使用均方误差(MSE)。对于单个样本 (xᵢ, yᵢ),损失为 J = (1/2) * (w*xᵢ + b - yᵢ)²。

初始参数:随机初始化 w = 0, b = 0。

超参数:学习率 η = 0.1。

手动计算前几步迭代

随机梯度下降的核心在于"随机"和"频繁更新"。在每一轮(Epoch)中,我们会遍历所有样本,但顺序是随机的,并且每看到一个样本就立即更新一次参数。

第1步:随机抽取一个样本

假设我们随机抽取到的第一个样本是 x=4, y=8。

1.计算预测值 (使用当前参数 w=0, b=0):

ŷ = 0 * 4 + 0 = 0

2.计算误差:

error = ŷ - y = 0 - 8 = -8

3.计算梯度 (仅针对这一个样本):

∇w = error * x = -8 * 4 = -32

∇b = error = -8

4.更新参数:

w = 0 - 0.1 * (-32) = 3.2

b = 0 - 0.1 * (-8) = 0.8

看,仅仅处理了一个样本,参数就立刻从 [0, 0] 变成了 [3.2, 0.8]。 这个更新非常剧烈,因为单个样本的梯度噪声很大。

第2步:再随机抽取下一个样本

假设我们随机抽取到的第二个样本是 x=2, y=4。注意,我们现在使用的是刚刚更新过的参数 w=3.2, b=0.8。

1.计算预测值:

ŷ = 3.2 * 2 + 0.8 = 7.2

2.计算误差:

error = 7.2 - 4 = 3.2

3.计算梯度:

∇w = 3.2 * 2 = 6.4

∇b = 3.2

4.更新参数:

w = 3.2 - 0.1 * (6.4) = 2.56

b = 0.8 - 0.1 * (3.2) = 0.48

参数再次被更新。你会发现,SGD 的路径非常"曲折",因为它完全被当前这一个样本"牵着鼻子走"。

后续迭代与收敛特点

这个过程会不断重复:随机选一个样本 -> 计算梯度 -> 立即更新参数。

优点:更新频率极高,收敛速度非常快,尤其是在处理海量数据时。

缺点:由于每次更新都基于单个样本,梯度估计非常不准确(噪声大),导致损失函数值会剧烈震荡,收敛路径不稳定。它可能在全局最优解附近来回"跳动",而难以精确收敛。

随机平均梯度下降

复制代码
随机平均梯度下降(Stochastic Average Gradient, SAG)是一种旨在结合随机梯度下降(SGD)
速度和批量梯度下降(BGD)稳定性的优化算法。
核心思想

维护一个所有样本历史梯度的"缓存",每次只随机更新其中一个,然后使用所有历史梯度的平均值来指导参数更新。这就像是SGD和BGD的"混血儿":

复制代码
像 SGD 一样,每次只随机看一个样本,计算速度快。
像 BGD 一样,使用所有样本梯度的平均值来更新参数,收敛路径更平滑。
场景设定

我们依然使用之前的线性回归任务,目标是拟合模型 y = w * x + b。

训练数据:我们有3个样本点,真实关系是 y = 2x。

x = [1, 2, 3]

y = [2, 4, 6]

损失函数:均方误差(MSE)。对于单个样本 (xᵢ, yᵢ),损失为 J = (1/2) * (w*xᵢ + b - yᵢ)²。

初始参数:w = 0, b = 0。

超参数:学习率 η = 0.1。

手动计算前两步迭代

SAG的关键在于维护一个与样本数量相同的"梯度表"。

第0步:初始化

参数:w = 0, b = 0。

梯度表:我们需要一个表格来存储每个样本的梯度。初始时,所有样本的梯度都设为0。

梯度表 = [ (∇w₁, ∇b₁), (∇w₂, ∇b₂), (∇w₃, ∇b₃) ] = [ (0, 0), (0, 0), (0, 0) ]

梯度总和:梯度总和 = (0, 0)。

第1步:处理第一个随机样本

假设我们随机选择第一个样本 x=1, y=2(索引为0)。

1.计算新梯度:使用当前参数 w=0, b=0 计算该样本的梯度。

预测值 ŷ = 0 * 1 + 0 = 0

误差 error = ŷ - y = 0 - 2 = -2

新梯度 ∇w_new = error * x = -2 * 1 = -2

新梯度 ∇b_new = error = -2

2.更新梯度表:用新计算的梯度替换掉梯度表中对应位置的旧梯度。

旧梯度是 (0, 0)。

梯度表 更新为 [ (-2, -2), (0, 0), (0, 0) ]

3.更新梯度总和:新总和 = 旧总和 + 新梯度 - 旧梯度。

梯度总和 = (0, 0) + (-2, -2) - (0, 0) = (-2, -2)

4.计算平均梯度:平均梯度 = 梯度总和 / 样本总数。

平均梯度 = (-2, -2) / 3 ≈ (-0.67, -0.67)

5.更新参数:使用平均梯度来更新参数。

w = 0 - 0.1 * (-0.67) = 0.067

b = 0 - 0.1 * (-0.67) = 0.067

关键区别:虽然只看了一个样本,但我们是基于所有样本的平均梯度(尽管目前只有一个非零)来更新的,这比SGD的更新要平滑得多。

第2步:处理第二个随机样本

假设我们随机选择第二个样本 x=2, y=4(索引为1)。使用当前参数 w=0.067, b=0.067。

1.计算新梯度:

预测值 ŷ = 0.067 * 2 + 0.067 = 0.201

误差 error = 0.201 - 4 = -3.799

新梯度 ∇w_new = -3.799 * 2 = -7.598

新梯度 ∇b_new = -3.799

2.更新梯度表:替换索引为1的旧梯度 (0, 0)。

梯度表 更新为 [ (-2, -2), (-7.598, -3.799), (0, 0) ]

3.更新梯度总和:

梯度总和 = (-2, -2) + (-7.598, -3.799) - (0, 0) = (-9.598, -5.799)

4.计算平均梯度:

平均梯度 = (-9.598, -5.799) / 3 ≈ (-3.20, -1.93)

5.更新参数:

w = 0.067 - 0.1 * (-3.20) = 0.387

b = 0.067 - 0.1 * (-1.93) = 0.26

随着迭代的进行,梯度表中的值会越来越接近真实的梯度。SAG的平均梯度会越来越精确地逼近全梯度下降的梯度,因此它最终能像BGD一样稳定地收敛到最优解,同时又保留了SGD每次只处理一个样本的计算效率。

【理解】正规方程和梯度下降算法的对比

回归评估方法

学习目标:

1.掌握常用的回归评估方法

2.了解不同评估方法的特点

为什么要进行线性回归模型的评估

我们希望衡量预测值和真实值之间的差距,

会用到MAE、MSE、RMSE多种测评函数进行评价

【知道】平均绝对误差

Mean Absolute Error (MAE)

  • 上面的公式中:n 为样本数量, y 为实际值, y ^ \hat{y} y^ 为预测值
  • MAE 越小模型预测越准确

Sklearn 中MAE的API

复制代码
from sklearn.metrics import mean_absolute_error
mean_absolute_error(y_test,y_predict)

【知道】均方误差

Mean Squared Error (MSE)

  • 上面的公式中:n 为样本数量, y 为实际值, y ^ \hat{y} y^ 为预测值
  • MSE 越小模型预测约准确

Sklearn 中MSE的API

复制代码
from sklearn.metrics import mean_squared_error
mean_squared_error(y_test,y_predict)

【知道】 均方根误差

Root Mean Squared Error (RMSE)

  • 上面的公式中:n 为样本数量, y 为实际值, y ^ \hat{y} y^ 为预测值
  • RMSE 越小模型预测约准确

【了解】 三种指标的比较

我们绘制了一条直线 y = 2x +5 用来拟合 y = 2x + 5 + e. 这些数据点,其中e为噪声

从上图中我们发现 MAE 和 RMSE 非常接近,都表明模型的误差很低(MAE 或 RMSE 越小,误差越小!)。 但是MAE 和 RMSE 有什么区别?为什么MAE较低?

  • 对比MAE 和 RMSE的公式,RMSE的计算公式中有一个平方项,因此:大的误差将被平方,因此会增加 RMSE 的值

  • 可以得出结论,RMSE 会放大预测误差较大的样本对结果的影响,而 MAE 只是给出了平均误差

  • 由于 RMSE 对误差的 平方和求平均 再开根号,大多数情况下RMSE>MAE

    举例 (1+3)/2 = 2 ( 1 2 + 3 2 ) / 2 = 10 / 2 = 5 = 2.236 \sqrt{(1^2+3^2)/2 }= \sqrt{10/2} = \sqrt{5} = 2.236 (12+32)/2 =10/2 =5 =2.236

我们再看下一个例子

橙色线与第一张图中的直线一样:y = 2x +5

蓝色的点为: y = y + sin(x)*exp(x/20) + e 其中 exp() 表示指数函数

我们看到对比第一张图,所有的指标都变大了,RMSE 几乎是 MAE 值的两倍,因为它对预测误差较大的点比较敏感

我们是否可以得出结论: RMSE是更好的指标? 某些情况下MAE更有优势,例如:

  • 假设数据中有少数异常点偏差很大,如果此时根据 RMSE 选择线性回归模型,可能会选出过拟合的模型来
  • 在这种情况下,由于数据中的异常点极少,选择具有最低 MAE 的回归模型可能更合适
  • 除此之外,当两个模型计算RMSE时数据量不一致,也不适合在一起比较

【实操】波士顿房价预测案例

【知道】线性回归API

sklearn.linear_model.LinearRegression(fit_intercept=True)

  • 通过正规方程优化
  • 参数:fit_intercept,是否计算偏置
  • 属性:LinearRegression.coef_ (回归系数) LinearRegression.intercept_(偏置)

sklearn.linear_model.SGDRegressor(loss="squared_loss", fit_intercept=True, learning_rate ='constant', eta0=0.01)

  • 参数:loss(损失函数类型),fit_intercept(是否计算偏置)learning_rate (学习率)
  • 属性:SGDRegressor.coef_ (回归系数)SGDRegressor.intercept_ (偏置)

【实操】波士顿房价预测

案例背景介绍

数据介绍

复制代码
给定的这些特征,是专家们得出的影响房价的结果属性。我们此阶段不需要自己去探究特征是否有用,
只需要使用这些特征。到后面量化很多特征需要我们自己去寻找
案例分析

回归当中的数据大小不一致,是否会导致结果影响较大。所以需要做标准化处理。

  • 数据分割与标准化处理
  • 回归预测
  • 线性回归的算法效果评估
回归性能评估

均方误差(Mean Squared Error, MSE)评价机制:

M S E = 1 m ∑ i = 1 m ( y i − y ^ ) 2 \Large MSE = \frac{1}{m}\sum_{i=1}^{m}(y^i-\hat{y})^2 MSE=m1∑i=1m(yi−y^)2

sklearn中的API:sklearn.metrics.mean_squared_error(y_true, y_pred)

  • 均方误差回归损失
  • y_true:真实值
  • y_pred:预测值
  • return:浮点数结果
代码实现
python 复制代码
# 0.导包
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression,SGDRegressor
from sklearn.metrics import mean_squared_error

# 1.加载数据
boston = load_boston()
# print(boston)

# 2.数据集划分
x_train,x_test,y_train,y_test =train_test_split(boston.data,boston.target,test_size=0.2,random_state=22)

# 3.标准化
process=StandardScaler()
x_train=process.fit_transform(x_train)
x_test=process.transform(x_test)

# 4.模型训练
# 4.1 实例化(正规方程)
# model =LinearRegression(fit_intercept=True)
model = SGDRegressor(learning_rate='constant',eta0=0.01)
# 4.2 fit
model.fit(x_train,y_train)

# print(model.coef_)
# print(model.intercept_)
# 5.预测
y_predict=model.predict(x_test)

print(y_predict)

# 6.模型评估

print(mean_squared_error(y_test,y_predict))

1.2.0 以上版本实现

python 复制代码
# 0.导包
# from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression,SGDRegressor
from sklearn.metrics import mean_squared_error

# 1.加载数据
# boston = load_boston()
# print(boston)
import pandas as pd
import numpy as np


data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]

# 2.数据集划分
# x_train,x_test,y_train,y_test =train_test_split(boston.data,boston.target,test_size=0.2,random_state=22)
x_train,x_test,y_train,y_test =train_test_split(data,target,test_size=0.2,random_state=22)

# 3.标准化
process=StandardScaler()
x_train=process.fit_transform(x_train)
x_test=process.transform(x_test)

# 4.模型训练
# 4.1 实例化(正规方程)
# model =LinearRegression(fit_intercept=True)
model = SGDRegressor(learning_rate='constant',eta0=0.01)
# 4.2 fit
model.fit(x_train,y_train)

# print(model.coef_)
# print(model.intercept_)
# 5.预测
y_predict=model.predict(x_test)

print(y_predict)

# 6.模型评估

print(mean_squared_error(y_test,y_predict))

正则化

学习目标:

1.掌握过拟合、欠拟合的概念

2.掌握过拟合、欠拟合产生的原因

3.知道什么是正则化,以及正则化的方法

【理解】 欠拟合与过拟合

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

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

过拟合和欠拟合的区别:

欠拟合在训练集和测试集上的误差都较大

过拟合在训练集上误差较小,而测试集上误差较大

【实践】通过代码认识过拟合和欠拟合

绘制数据

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error  # 计算均方误差
from sklearn.model_selection import train_test_split


def dm01_欠拟合():
    # 1. 准备x, y数据, 增加上噪声.
    # 用于设置随机数生成器的种子(seed), 种子一样, 每次生成相同序列.
    np.random.seed(666)
    # x: 随机数, 范围为 (-3, 3), 100个.
    x = np.random.uniform(-3, 3, size=100)
    # loc: 均值, scale: 标准差, normal: 正态分布.
    y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
    # 2. 实例化 线性回归模型.
    estimator = LinearRegression()
    # 3. 训练模型
    X = x.reshape(-1, 1)
    estimator.fit(X, y)

    # 4. 模型预测.
    y_predict = estimator.predict(X)
    print("预测值:", y_predict)

    # 5. 计算均方误差 => 模型评估
    print(f'均方误差: {mean_squared_error(y, y_predict)}')
    # 6. 画图
    plt.scatter(x, y)           # 散点图
    plt.plot(x, y_predict, color='r')   # 折线图(预测值, 拟合回归线)
    plt.show()                  # 具体的绘图



if __name__ == '__main__':
    dm01_欠拟合()
复制代码
#计算均方误差
from sklearn.metrics import mean_squared_error
mean_squared_error(y,y_predict)

#3.0750025765636577

添加二次项,绘制图像

python 复制代码
def dm02_模型ok():
    # 1. 准备x, y数据, 增加上噪声.
    # 用于设置随机数生成器的种子(seed), 种子一样, 每次生成相同序列.
    np.random.seed(666)
    # x: 随机数, 范围为 (-3, 3), 100个.
    x = np.random.uniform(-3, 3, size=100)
    # loc: 均值, scale: 标准差, normal: 正态分布.
    y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
    # 2. 实例化 线性回归模型.
    estimator = LinearRegression()
    # 3. 训练模型
    X = x.reshape(-1, 1)
    X2 = np.hstack([X, X ** 2])
    estimator.fit(X2, y)

    # 4. 模型预测.
    y_predict = estimator.predict(X2)
    print("预测值:", y_predict)

    # 5. 计算均方误差 => 模型评估
    print(f'均方误差: {mean_squared_error(y, y_predict)}')
    # 6. 画图
    plt.scatter(x, y)  # 散点图
    # sort()  该函数直接返回一个排序后的新数组。
    # numpy.argsort()   该函数返回的是数组值从小到大排序时对应的索引值
    plt.plot(np.sort(x), y_predict[np.argsort(x)], color='r')  # 折线图(预测值, 拟合回归线)
    # plt.plot(x, y_predict)
    plt.show()  # 具体的绘图
复制代码
#计算均方误差和准确率

from sklearn.metrics import mean_squared_error
mean_squared_error(y,y_predict2)

#1.0987392142417858

再次加入高次项,绘制图像,观察均方误差结果

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error  # 计算均方误差
from sklearn.model_selection import train_test_split


def dm01_欠拟合():
    # 1. 准备x, y数据, 增加上噪声.
    # 用于设置随机数生成器的种子(seed), 种子一样, 每次生成相同序列.
    np.random.seed(666)
    # x: 随机数, 范围为 (-3, 3), 100个.
    x = np.random.uniform(-3, 3, size=100)
    # loc: 均值, scale: 标准差, normal: 正态分布.
    y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
    # 2. 实例化 线性回归模型.
    estimator = LinearRegression()
    # 3. 训练模型
    X = x.reshape(-1, 1)
    estimator.fit(X, y)

    # 4. 模型预测.
    y_predict = estimator.predict(X)
    print("预测值:", y_predict)

    # 5. 计算均方误差 => 模型评估
    print(f'均方误差: {mean_squared_error(y, y_predict)}')
    # 6. 画图
    plt.scatter(x, y)           # 散点图
    plt.plot(x, y_predict, color='r')   # 折线图(预测值, 拟合回归线)
    plt.show()                  # 具体的绘图

def dm02_模型ok():
    # 1. 准备x, y数据, 增加上噪声.
    # 用于设置随机数生成器的种子(seed), 种子一样, 每次生成相同序列.
    np.random.seed(666)
    # x: 随机数, 范围为 (-3, 3), 100个.
    x = np.random.uniform(-3, 3, size=100)
    # loc: 均值, scale: 标准差, normal: 正态分布.
    y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
    # 2. 实例化 线性回归模型.
    estimator = LinearRegression()
    # 3. 训练模型
    X = x.reshape(-1, 1)
    X2 = np.hstack([X, X ** 2])
    estimator.fit(X2, y)

    # 4. 模型预测.
    y_predict = estimator.predict(X2)
    print("预测值:", y_predict)

    # 5. 计算均方误差 => 模型评估
    print(f'均方误差: {mean_squared_error(y, y_predict)}')
    # 6. 画图
    plt.scatter(x, y)  # 散点图
    # sort()  该函数直接返回一个排序后的新数组。
    # numpy.argsort()   该函数返回的是数组值从小到大排序时对应的索引值
    plt.plot(np.sort(x), y_predict[np.argsort(x)], color='r')  # 折线图(预测值, 拟合回归线)
    # plt.plot(x, y_predict)
    plt.show()  # 具体的绘图


def dm03_过拟合():
    # 1. 准备x, y数据, 增加上噪声.
    # 用于设置随机数生成器的种子(seed), 种子一样, 每次生成相同序列.
    np.random.seed(666)
    # x: 随机数, 范围为 (-3, 3), 100个.
    x = np.random.uniform(-3, 3, size=100)
    # loc: 均值, scale: 标准差, normal: 正态分布.
    y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
    # 2. 实例化 线性回归模型.
    estimator = LinearRegression()
    # 3. 训练模型
    X = x.reshape(-1, 1)
    # hstack() 函数用于将多个数组在行上堆叠起来, 即: 数据增加高次项.
    X3 = np.hstack([X, X**2, X**3, X**4, X**5, X**6, X**7, X**8, X**9, X**10])
    estimator.fit(X3, y)

    # 4. 模型预测.
    y_predict = estimator.predict(X3)
    print("预测值:", y_predict)

    # 5. 计算均方误差 => 模型评估
    print(f'均方误差: {mean_squared_error(y, y_predict)}')
    # 6. 画图
    plt.scatter(x, y)  # 散点图
    # sort()  该函数直接返回一个排序后的新数组。
    # numpy.argsort()   该函数返回的是数组值从小到大排序时对应的索引值
    plt.plot(np.sort(x), y_predict[np.argsort(x)], color='r')  # 折线图(预测值, 拟合回归线)
    plt.show()  # 具体的绘图

if __name__ == '__main__':
    # dm01_欠拟合()
    # dm02_模型ok()
    dm03_过拟合()

通过上述观察发现,随着加入的高次项越来越多,拟合程度越来越高,均方误差也随着加入越来越小。说明已经不再欠拟合了。

问题:如何判断出现过拟合呢?

将数据集进行划分:对比X、X2、X5的测试集的均方误差

X的测试集均方误差

复制代码
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state = 5)
estimator = LinearRegression()
estimator.fit(X_train,y_train)
y_predict = estimator.predict(X_test)

mean_squared_error(y_test,y_predict)
#3.153139806483088

X2的测试集均方误差

复制代码
X_train,X_test,y_train,y_test = train_test_split(X2,y,random_state = 5)
estimator = LinearRegression()
estimator.fit(X_train,y_train)
y_predict = estimator.predict(X_test)
mean_squared_error(y_test,y_predict)
#1.111873885731967

X5的测试集的均方误差

复制代码
X_train,X_test,y_train,y_test = train_test_split(X5,y,random_state = 5)
estimator = LinearRegression()
estimator.fit(X_train,y_train)
y_predict = estimator.predict(X_test)
mean_squared_error(y_test,y_predict)
#1.4145580542309835

【理解】 原因以及解决办法

欠拟合产生原因: 学习到数据的特征过少

解决办法:
1)添加其他特征项,有时出现欠拟合是因为特征项不够导致的,可以添加其他特征项来解决

2)添加多项式特征,模型过于简单时的常用套路,例如将线性模型通过添加二次项或三次项使模型泛化能力更强

过拟合产生原因: 原始特征过多,存在一些嘈杂特征, 模型过于复杂是因为模型尝试去兼顾所有测试样本

解决办法:

1)重新清洗数据,导致过拟合的一个原因有可能是数据不纯,如果出现了过拟合就需要重新清洗数据。

2)增大数据的训练量,还有一个原因就是我们用于训练的数据量太小导致的,训练数据占总数据的比例过小。

3)正则化

4)减少特征维度

【理解】正则化

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

如何解决?

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

注:调整时候,算法并不知道某个特征影响,而是去调整参数得出优化的结

L1正则化
  • 假设𝐿(𝑊)是未加正则项的损失,𝜆是一个超参,控制正则化项的大小。
  • 则最终的损失函数: 𝐿 = 𝐿 ( 𝑊 ) + λ ∗ ∑ i = 1 n ∣ w i ∣ 𝐿=𝐿(𝑊)+ \lambda*\sum_{i=1}^{n}\lvert w_i\rvert L=L(W)+λ∗∑i=1n∣wi∣

作用:用来进行特征选择,主要原因在于L1正则化会使得较多的参数为0,从而产生稀疏解,可以将0对应的特征遗弃,进而用来选择特征。一定程度上L1正则也可以防止模型过拟合。

L1正则为什么可以产生稀疏解(可以特征选择)

稀疏性:向量中很多维度值为0

  • 对其中的一个参数 w_i 计算梯度,其他参数同理,α是学习率,sign(wi)是符号函数。

L1的梯度:

𝐿 = 𝐿 ( 𝑊 ) + λ ∗ ∑ i = 1 n ∣ w i ∣ 𝐿=𝐿(𝑊)+ \lambda*\sum_{i=1}^{n}\lvert w_i\rvert L=L(W)+λ∗∑i=1n∣wi∣

∂ L ∂ w i = ∂ L ( W ) ∂ w i + λ s i g n ( w i ) \frac{\partial L}{\partial w_{i}} = \frac{\partial L(W)}{\partial w_{i}}+\lambda sign(w_{i}) ∂wi∂L=∂wi∂L(W)+λsign(wi)

LASSO回归: from sklearn.linear_model import Lasso

L2正则化
  • 假设𝐿(𝑊)是未加正则项的损失,𝜆是一个超参,控制正则化项的大小。
  • 则最终的损失函数: 𝐿 = 𝐿 ( 𝑊 ) + λ ∗ ∑ i = 1 n w i 2 𝐿=𝐿(𝑊)+ \lambda*\sum_{i=1}^{n}w_{i}^{2} L=L(W)+λ∗∑i=1nwi2

作用:主要用来防止模型过拟合,可以减小特征的权重

优点:越小的参数说明模型越简单,越简单的模型则越不容易产生过拟合现象

Ridge回归: from sklearn.linear_model import Ridge

正则化案例

复制代码
X10 = np.hstack([X2,X**3,X**4,X**5,X**6,X**7,X**8,X**9,X**10]) 
estimator3 = LinearRegression() 
estimator3.fit(X10,y) 
y_predict3 = estimator3.predict(X10) 

plt.scatter(x,y) 
plt.plot(np.sort(x),y_predict3[np.argsort(x)],color = 'r') 
plt.show()

estimator3.coef_

array([ 1.32292089e+00,  2.03952017e+00, -2.88731664e-01, -1.24760429e+00,
        8.06147066e-02,  3.72878513e-01, -7.75395040e-03, -4.64121137e-02,
        1.84873446e-04,  2.03845917e-03])
python 复制代码
from sklearn.linear_model import Lasso  # L1正则
from sklearn.linear_model import Ridge  # 岭回归 L2正则

def dm04_模型过拟合_L1正则化():
    # 1. 准备x, y数据, 增加上噪声.
    # 用于设置随机数生成器的种子(seed), 种子一样, 每次生成相同序列.
    np.random.seed(666)
    # x: 随机数, 范围为 (-3, 3), 100个.
    x = np.random.uniform(-3, 3, size=100)
    # loc: 均值, scale: 标准差, normal: 正态分布.
    y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
    # 2. 实例化L1正则化模型, 做实验: alpha惩罚力度越来越大, k值越来越小.
    estimator = Lasso(alpha=0.005)
    # 3. 训练模型
    X = x.reshape(-1, 1)
    # hstack() 函数用于将多个数组在行上堆叠起来, 即: 数据增加高次项.
    X3 = np.hstack([X, X**2, X**3, X**4, X**5, X**6, X**7, X**8, X**9, X**10])
    estimator.fit(X3, y)
    print(f'权重: {estimator.coef_}')

    # 4. 模型预测.
    y_predict = estimator.predict(X3)
    print("预测值:", y_predict)

    # 5. 计算均方误差 => 模型评估
    print(f'均方误差: {mean_squared_error(y, y_predict)}')
    # 6. 画图
    plt.scatter(x, y)  # 散点图
    # sort()  该函数直接返回一个排序后的新数组。
    # numpy.argsort()   该函数返回的是数组值从小到大排序时对应的索引值
    plt.plot(np.sort(x), y_predict[np.argsort(x)], color='r')  # 折线图(预测值, 拟合回归线)
    plt.show()  # 具体的绘图
python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression, Lasso, Ridge
from sklearn.metrics import mean_squared_error  # 计算均方误差
from sklearn.model_selection import train_test_split


def dm01_欠拟合():
    # 1. 准备x, y数据, 增加上噪声.
    # 用于设置随机数生成器的种子(seed), 种子一样, 每次生成相同序列.
    np.random.seed(666)
    # x: 随机数, 范围为 (-3, 3), 100个.
    x = np.random.uniform(-3, 3, size=100)
    # loc: 均值, scale: 标准差, normal: 正态分布.
    y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
    # 2. 实例化 线性回归模型.
    estimator = LinearRegression()
    # 3. 训练模型
    X = x.reshape(-1, 1)
    estimator.fit(X, y)

    # 4. 模型预测.
    y_predict = estimator.predict(X)
    print("预测值:", y_predict)

    # 5. 计算均方误差 => 模型评估
    print(f'均方误差: {mean_squared_error(y, y_predict)}')
    # 6. 画图
    plt.scatter(x, y)           # 散点图
    plt.plot(x, y_predict, color='r')   # 折线图(预测值, 拟合回归线)
    plt.show()                  # 具体的绘图

def dm02_模型ok():
    # 1. 准备x, y数据, 增加上噪声.
    # 用于设置随机数生成器的种子(seed), 种子一样, 每次生成相同序列.
    np.random.seed(666)
    # x: 随机数, 范围为 (-3, 3), 100个.
    x = np.random.uniform(-3, 3, size=100)
    # loc: 均值, scale: 标准差, normal: 正态分布.
    y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
    # 2. 实例化 线性回归模型.
    estimator = LinearRegression()
    # 3. 训练模型
    X = x.reshape(-1, 1)
    X2 = np.hstack([X, X ** 2])
    estimator.fit(X2, y)

    # 4. 模型预测.
    y_predict = estimator.predict(X2)
    print("预测值:", y_predict)

    # 5. 计算均方误差 => 模型评估
    print(f'均方误差: {mean_squared_error(y, y_predict)}')
    # 6. 画图
    plt.scatter(x, y)  # 散点图
    # sort()  该函数直接返回一个排序后的新数组。
    # numpy.argsort()   该函数返回的是数组值从小到大排序时对应的索引值
    plt.plot(np.sort(x), y_predict[np.argsort(x)], color='r')  # 折线图(预测值, 拟合回归线)
    # plt.plot(x, y_predict)
    plt.show()  # 具体的绘图

def dm03_过拟合():
    # 1. 准备x, y数据, 增加上噪声.
    # 用于设置随机数生成器的种子(seed), 种子一样, 每次生成相同序列.
    np.random.seed(666)
    # x: 随机数, 范围为 (-3, 3), 100个.
    x = np.random.uniform(-3, 3, size=100)
    # loc: 均值, scale: 标准差, normal: 正态分布.
    y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
    # 2. 实例化 线性回归模型.
    estimator = LinearRegression()
    # 3. 训练模型
    X = x.reshape(-1, 1)
    # hstack() 函数用于将多个数组在行上堆叠起来, 即: 数据增加高次项.
    X3 = np.hstack([X, X**2, X**3, X**4, X**5, X**6, X**7, X**8, X**9, X**10])
    estimator.fit(X3, y)

    # 4. 模型预测.
    y_predict = estimator.predict(X3)
    print("预测值:", y_predict)

    # 5. 计算均方误差 => 模型评估
    print(f'均方误差: {mean_squared_error(y, y_predict)}')
    # 6. 画图
    plt.scatter(x, y)  # 散点图
    # sort()  该函数直接返回一个排序后的新数组。
    # numpy.argsort()   该函数返回的是数组值从小到大排序时对应的索引值
    plt.plot(np.sort(x), y_predict[np.argsort(x)], color='r')  # 折线图(预测值, 拟合回归线)
    plt.show()  # 具体的绘图


def dm04_模型过拟合_L1正则化():
    # 1. 准备x, y数据, 增加上噪声.
    # 用于设置随机数生成器的种子(seed), 种子一样, 每次生成相同序列.
    np.random.seed(666)
    # x: 随机数, 范围为 (-3, 3), 100个.
    x = np.random.uniform(-3, 3, size=100)
    # loc: 均值, scale: 标准差, normal: 正态分布.
    y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
    # 2. 实例化L1正则化模型, 做实验: alpha惩罚力度越来越大, k值越来越小.
    estimator = Lasso(alpha=0.005)
    # 3. 训练模型
    X = x.reshape(-1, 1)
    # hstack() 函数用于将多个数组在行上堆叠起来, 即: 数据增加高次项.
    X3 = np.hstack([X, X**2, X**3, X**4, X**5, X**6, X**7, X**8, X**9, X**10])
    estimator.fit(X3, y)
    print(f'权重: {estimator.coef_}')

    # 4. 模型预测.
    y_predict = estimator.predict(X3)
    print("预测值:", y_predict)

    # 5. 计算均方误差 => 模型评估
    print(f'均方误差: {mean_squared_error(y, y_predict)}')
    # 6. 画图
    plt.scatter(x, y)  # 散点图
    # sort()  该函数直接返回一个排序后的新数组。
    # numpy.argsort()   该函数返回的是数组值从小到大排序时对应的索引值
    plt.plot(np.sort(x), y_predict[np.argsort(x)], color='r')  # 折线图(预测值, 拟合回归线)
    plt.show()  # 具体的绘图

def dm05_模型过拟合_L2正则化():
    # 1. 准备x, y数据, 增加上噪声.
    # 用于设置随机数生成器的种子(seed), 种子一样, 每次生成相同序列.
    np.random.seed(666)
    # x: 随机数, 范围为 (-3, 3), 100个.
    x = np.random.uniform(-3, 3, size=100)
    # loc: 均值, scale: 标准差, normal: 正态分布.
    y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
    # 2. 实例化L2正则化模型, 做实验: alpha惩罚力度越来越大, k值越来越小.
    estimator = Ridge(alpha=0.005)
    # 3. 训练模型
    X = x.reshape(-1, 1)
    # hstack() 函数用于将多个数组在行上堆叠起来, 即: 数据增加高次项.
    X3 = np.hstack([X, X**2, X**3, X**4, X**5, X**6, X**7, X**8, X**9, X**10])
    estimator.fit(X3, y)
    print(f'权重: {estimator.coef_}')

    # 4. 模型预测.
    y_predict = estimator.predict(X3)
    print("预测值:", y_predict)

    # 5. 计算均方误差 => 模型评估
    print(f'均方误差: {mean_squared_error(y, y_predict)}')
    # 6. 画图
    plt.scatter(x, y)  # 散点图
    # sort()  该函数直接返回一个排序后的新数组。
    # numpy.argsort()   该函数返回的是数组值从小到大排序时对应的索引值
    plt.plot(np.sort(x), y_predict[np.argsort(x)], color='r')  # 折线图(预测值, 拟合回归线)
    plt.show()  # 具体的绘图

if __name__ == '__main__':
    # dm01_欠拟合()
    # dm02_模型ok()
    dm03_过拟合()
    # dm04_模型过拟合_L1正则化()
    # dm05_模型过拟合_L2正则化()
相关推荐
skilllite作者6 小时前
Warp 终端效能与交互体验全景展示
人工智能·后端·架构·rust
穷人小水滴6 小时前
(AI) 编写简单 MCP 工具 (mcp-run)
人工智能·ai·node.js·agent·mcp
byte轻骑兵6 小时前
【LE Audio】BASS精讲[6]: SDP适配全流程,BR/EDR下的BASS服务互通
人工智能·实时音视频·le audio·低功耗音频·bass
qcx236 小时前
Warp源码深度解析(六):AI Agent的Context管理——从9种上下文到流水线组装
大数据·人工智能·elasticsearch
WHS-_-20226 小时前
Tensor Completion Network for Visual Data
人工智能·深度学习
杰克·Pyo6 小时前
AI 悄然而至 ERP 行业
人工智能·职场和发展
碧海银沙音频科技研究院7 小时前
如何彻底关闭360壁纸
人工智能·深度学习·算法
sali-tec7 小时前
C# 基于OpenCv的视觉工作流-章57-人脸识别
图像处理·人工智能·opencv·算法·计算机视觉
Deepoch7 小时前
Deepoc 边缘智能计算单元强化无人机群组野外场景自适应技术研究
人工智能·无人机·开发板·具身模型·deepoc