机器学习(七): Bias、Error和Variance的区别与联系

全文共9000余字,预计阅读时间约18~30分钟 | 满满干货,建议收藏!

在这里插入图片描述

一、 引言

在机器学习领域,误差(Error)、偏差(Bias)和方差(Variance)是我们常常要面对的三个核心概念。简单来说:

  1. 误差是模型预测结果与实际值之间的差异。在模型训练过程中,目标通常是尽可能地减少这种误差。

  2. 偏差是模型预测的平均误差,或者说是模型对真实数据的预测值与实际值的差异的期望值。一个高偏差的模型可能会忽略数据中的某些重要细节,导致模型过于简单,这种情况我们通常称之为欠拟合。

  3. 方差是模型预测值的变化范围或者说离散程度,它反映了模型对输入微小改变的敏感度。高方差可能导致模型对数据中的随机噪声过于敏感,导致模型过于复杂,我们通常称之为过拟合。

理解误差、偏差和方差的区别和联系对于构建和优化机器学习模型至关重要。理想的模型应该在偏差和方差之间达到平衡,以最小化总误差。这就是我们所说的偏差-方差权衡(Bias-Variance Tradeoff)。接下来,我们深入讨论这三个概念,以及如何在实践中处理它们。

二、 基础定义

2.1 什么是偏差(Bias)

2.1.1 偏差(Bias)定义

偏差(Bias)在统计和机器学习中是预测值的期望(平均预测值)和真实值之间的差异。在这个定义中,"期望"或"平均预测值"是指如果我们反复从同一分布中取样并训练模型,然后对相同的输入做预测,所有这些预测的平均值。所以,就可以把偏差看作是模型预测的平均误差。

为了更好地理解这个概念,你可以想象我们有一个真实的函数(或者数据生成过程),但是我们没有完全了解它,我们只能通过有限的数据样本来估计它。如果我们的模型(比如一个线性回归模型)对这个真实函数的假设偏离了实际,那么模型的预测就会系统性地偏离真实值,这种偏离就是偏差。如果一个模型的偏差高,就说明它的预测平均上偏离了真实值。

在数学上,我们可以用以下公式来定义偏差:

Bias ( f ^ ( x ) ) = E [ f ^ ( x ) ] − f ( x ) (1) \text{Bias}(\hat{f}(x)) = E[\hat{f}(x)] - f(x) \tag{1} Bias(f^(x))=E[f^(x)]f(x)(1)

其中, E [ ⋅ ] E[\cdot] E[] 表示期望(即平均值)的符号, f ( x ) f(x) f(x) 是真实的函数值, f ^ ( x ) \hat{f}(x) f^(x) 是模型对给定输入 x x x 的预测。

偏差衡量了模型预测的平均误差。高偏差可能意味着模型过于简单(即模型欠拟合),无法捕获数据中的所有相关性,导致预测结果偏离真实值。

2.1.2 偏差(Bias)解析

我们通过一个简单的线性回归模型的例子来理解并计算偏差。

偏差(Bias)度量了模型预测的平均值和真实值之间的差距。在理论上,偏差是所有可能训练数据集上模型预测的平均值与真实值之间的差异。这个“平均”是指在所有可能的训练集上进行平均。

因为我们无法获得所有可能的训练集,所以在实际操作中,我们通常用单个训练集的模型预测结果来近似。接下来,我们就通过一个实例来具体展示这一过程。直接上代码:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# 设置随机种子以保证结果的可复现性
np.random.seed(0)

# 生成输入数据
x = np.linspace(-10, 10, 10)

print("Input: ", y)

# 定义真实函数
def f(x):
    return 2 * x + 3

# 生成带噪声的目标数据
y = f(x) + np.random.normal(0, 2, size=len(x))  # 添加噪声

# 拟合线性模型
model = LinearRegression()
model.fit(x.reshape(-1, 1), y)

# 得到模型预测
y_pred = model.predict(x.reshape(-1, 1))

# 计算偏差
bias = np.mean(y_pred - f(x))


print("True value: ", y)
print("Predicted value: ", y_pred)
print("Bias: ", bias)

# 可视化
plt.scatter(x, y, color='blue', label='True value')
plt.plot(x, y_pred, color='red', label='Predicted value')
plt.legend()
plt.show()

上述代码首先创建了一个真实函数f(x) = 2x + 3,然后生成了一些带噪声的目标数据。然后,用这些数据拟合了一个线性回归模型,并得到了模型的预测值y_pred。之后,我们计算了偏差,即预测值y_pred和真实函数值f(x)之间的差的平均值。最后,我们将真实值和预测值在图中进行了可视化,可以看出预测值与真实值之间的差距。

image-20230616101911472

我们把数据整理一下:

InputTrue ValuePredicted ValueDifference
-10-13.47-13.990.52
-7.8-11.76-9.89-1.87
-5.6-6.15-5.78-0.37
-3.30.82-1.68-2.5
-1.14.512.42-2.09
1.13.276.533.26
3.311.5710.63-0.94
5.613.8114.740.93
7.818.3518.840.49
1023.8222.94-0.88

此处四舍五入了数据以便阅读,Difference的计算方式为Predicted Value - True Value,因此当Predicted Value大于True Value时,Difference为正,反之为负。

通过观察可视化图形,可以看到,虽然预测值(红线)大体上遵循了真实值(蓝点)的趋势,但在某些点上,预测值与真实值之间存在一些差距。这些差距就是偏差(Bias)的来源。在这个示例中,我们计算的偏差值为 1.476,表示我们的模型在预测时会有一定程度的偏离真实值。

在理想情况下,如果一个模型的偏差小,那么表示该模型的预测结果较接近真实值。反之,如果一个模型的偏差大,那么表示该模型的预测结果与真实值相差较大。这也是我们在建模时需要关注并尽可能降低模型偏差的原因。

接下来我们再看一下高偏差的 情况,通过使用一个模型,如常数模型或者简单的线性模型,来预测非线性的数据。下面的代码生成了一个具有较高偏差的模型来拟合非线性的数据:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# 设置随机种子以保证结果的可复现性
np.random.seed(0)

# 生成输入数据
x = np.linspace(-10, 10, 10)

print("Input: ", y)

# 定义真实函数,非线性函数
def f(x):
    return x**2 + 2*x + 3

# 生成带噪声的目标数据
y = f(x) + np.random.normal(0, 10, size=len(x))  # 添加噪声

# 拟合线性模型,线性模型可能不能很好地拟合这种非线性数据
model = LinearRegression()
model.fit(x.reshape(-1, 1), y)

# 得到模型预测
y_pred = model.predict(x.reshape(-1, 1))

# 计算偏差
bias = np.mean(y_pred - f(x))

print("True value: ", y)
print("Predicted value: ", y_pred)
print("Bias: ", bias)

# 可视化
plt.scatter(x, y, color='blue', label='True value')
plt.plot(x, y_pred, color='red', label='Predicted value')
plt.legend()
plt.show()

这个代码中,真实函数是一个二次函数,而我们使用了线性模型去拟合,所以偏差会比较大,这样就能清楚地展示高偏差的情况。

image-20230616102515949

最后来对比一下

101

2.2 什么是方差(Variance)

2.2.1 方差(Variance)定义

在统计和机器学习中,方差是一个衡量预测值分散程度的量。如果我们有一组预测值,我们可以首先计算这组预测值的均值,然后计算每个预测值与这个均值的差的平方,最后计算这些平方差的平均值,得到的就是这组预测值的方差。更高的方差意味着预测值在其均值附近的分散程度更高。

在机器学习中,通常将方差定义为使用不同的训练数据集训练出的模型对相同的输入值 x 的预测的差异。方差的数学定义是:

Variance = E [ ( f ^ ( x ) − E [ f ^ ( x ) ] ) 2 ] (2) \text{Variance} = E[(\hat{f}(x) - E[\hat{f}(x)])^2] \tag{2} Variance=E[(f^(x)E[f^(x)])2](2)

在这个公式中, f ^ ( x ) \hat{f}(x) f^(x)是模型对输入 x x x的预测, E [ f ^ ( x ) ] E[\hat{f}(x)] E[f^(x)]是所有可能模型预测值的期望(平均值)。这个公式表示的是模型预测的期望值和每一个模型预测值之间的平方差异的期望值,衡量了模型预测的变化程度。

2.2.2 方差(Variance)解析

同样,我们模拟一个低方差的情况。低方差意味着不同模型的预测结果非常接近,即使在输入数据中加入了一些噪声。直接上代码:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# 设置随机种子以保证结果的可复现性
np.random.seed(0)

# 生成输入数据
x = np.linspace(-10, 10, 10)


# 定义真实函数
def f(x):
    return 2 * x + 3

# 生成真实目标数据
y_true = f(x)

# 创建模型并进行多次拟合
predictions = []

for _ in range(100):
    # 为目标数据添加噪声
    y = y_true + np.random.normal(0, 1, size=len(x))  # 增大噪声的标准差

    # 拟合线性模型
    model = LinearRegression()
    model.fit(x.reshape(-1, 1), y)

    # 得到模型预测
    y_pred = model.predict(x.reshape(-1, 1))
    predictions.append(y_pred)

# 计算方差
variance = np.var(predictions, axis=0)
print("Variance: ", variance)

# 可视化
plt.figure(figsize=(10, 6))
plt.plot(x, y_true, color='black', label='True function')
for i, y_pred in enumerate(predictions):
    plt.plot(x, y_pred, color='blue', alpha=0.1)
plt.legend()
plt.show()

在实际情况中,由于通常只有一个数据集,因此无法生成不同的数据集以显示方差。但我们可以通过生成不同的数据子集(例如,通过引入噪声或采样)来模拟这种情况。

在上述代码中,生成10个线性模型,每个模型都用相同的数据集训练,但在数据中添加了不同的噪声。然后,画出所有模型的预测以显示预测结果的分散情况。

image-20230616111134953

看到的蓝色线其实是由10条线叠加在一起形成的。因为在这个例子中,我们使用的是线性模型来拟合线性数据,所以所有的模型都可以很好地拟合出真实的模式,因此预测结果的差异很小,看上去就像一条线。这就是低方差的表现:不同模型的预测结果非常接近。

但如果我们使用复杂的模型(如深度神经网络)或者在数据中添加更多的噪声,就会看到预测结果之间的差异会变大,这时候就会体现出高方差的特性。

要想让预测结果的差异在图中更加明显,可以尝试增大噪声的标准差。例如,可以将噪声的标准差从1增大到5,你就可以看到更大的预测差异。

# 修改这一行代码,将1改为5,再次运行
y = y_true + np.random.normal(0, 5, size=len(x))  # 增大噪声的标准差

image-20230616111433548

最后对比看一下:

102

2.3 什么是误差(Error)

2.3.1 误差(Error)定义

在统计学和机器学习中,误差通常被定义为预测值和真实值之间的差异。误差衡量了模型预测的准确性。对于单个数据点,误差可以通过以下公式计算:误差 = 真实值 - 预测值

在一个完美的预测模型中,所有预测值都将与真实值完全匹配,因此误差将为零。然而,在实际应用中,由于多种因素(例如数据噪声、模型复杂性、过度拟合或欠拟合等)的影响,预测误差通常不会为零。

对于一组数据点,通常使用平均误差(Mean Error)或均方误差(Mean Squared Error, MSE)来衡量模型的总体预测准确性。均方误差是最常用的误差度量,它是每个预测误差平方的平均值。均方误差的公式为:

M S E = 1 n ∑ i = 1 n ( y i − y i ′ ) 2 (3) MSE = \frac{1}{n} \sum_{i=1}^{n}(y_i - y'_i)^2 \tag{3} MSE=n1i=1n(yiyi)2(3)

其中:

  • n 是数据点的总数
  • y i y_i yi 是真实值
  • y i ′ y'_i yi 是预测值
  • Σ 表示对所有数据点进行求和

  这个概念比较容易理解,就不举例说明了。

三、Bias,Variance以及Error的关系

  误差、偏差和方差虽然有关联,但是它们衡量的是不同的概念。偏差和方差都是误差的组成部分,它们分别描述了模型预测的系统性偏离(Bias)和不稳定性(Variance)。模型的总误差可以视为偏差、方差和噪声的总和。

3.1 偏差-方差权衡(bias-variance tradeoff)

举个例子:

在一个学习任务中,假设有一个真实的函数 f f f(也被称为目标函数),我们希望从训练数据(包含n个样本的集合D)中学习到一个函数 f ^ \hat f f^,使其尽可能接近 f f f。这个过程可以被视为一个回归问题,其中通常使用最小化均方误差(MSE)的方式来进行学习。

然而,我们的最终目标不仅仅是在训练数据上表现好,而是希望学习到的函数$ \hat f$ 能够很好地泛化到没有见过的样本上。也就是说,我们希望无论如何抽样训练样本,$ \hat f$ 都能对未见过的样本有良好的表现。为了衡量这一点,我们考虑了期望的损失(也就是真实值 y y y 和预测值$ \hat f(x) $之间的差的平方的期望值)。

然后可以把这个期望的损失分解为三个部分:偏差,方差以及噪声。这三部分分别反映了不同的信息:

  • 偏差:反映模型与真实模型之间的误差。如果偏差较大,那说明模型系统性地预测不准,也就是说模型可能过于简单,没有学习到数据的真实结构。
  • 方差:反映了模型对训练数据的变化敏感度。如果方差较大,说明模型过于复杂,以至于对训练数据中的随机噪声都进行了学习,从而导致在新的数据上表现不佳。
  • 噪声:这是数据本身的问题,是不可避免的误差。

3.2 数学推导

目标是从采样的数据集 D = { ( x 1 , y 1 ) , … , ( x n , y n ) } D = \{(x_1, y_1), \ldots, (x_n, y_n)\} D={(x1,y1),,(xn,yn)} 学习到一个函数 f ^ \hat{f} f^,使其尽可能接近真实的函数 f f f。在这个过程中,目标值 y y y 是由真实函数 f f f 产生的结果加上一个噪音 ϵ \epsilon ϵ,即
y = f ( x ) + ϵ (4) y = f(x) + \epsilon \tag{4} y=f(x)+ϵ(4)

我们希望优化的是期望的损失(expected loss),也就是真实值 y y y 和预测值 f ^ ( x ) \hat{f}(x) f^(x) 之间的差的平方的期望值。所以:

  1. 首先,考虑总的预测误差的期望值,也就是平均误差的平方:

    E D [ ( y − f ^ D ( x ) ) 2 ] (5) ED [(y - \hat{f}_D(x))^2] \tag{5} ED[(yf^D(x))2](5)

  2. 接下来,将 y y y 替换为 f ( x ) + ϵ f(x) + \epsilon f(x)+ϵ,同时将预测值 f ^ D ( x ) \hat{f}_D(x) f^D(x) 拆分为两部分:真实函数 f ( x ) f(x) f(x) 与预测函数期望值 E D [ f ^ D ] ED[\hat{f}_D] ED[f^D] 的差,以及预测函数 f ^ D ( x ) \hat{f}_D(x) f^D(x) 与它的期望 E D [ f ^ D ] ED[\hat{f}_D] ED[f^D] 的差。这样得到:

    E D [ ( f − E D [ f ^ D ] + f ^ D − E D [ f ^ D ] + ϵ ) 2 ] (6) ED [(f - ED[\hat{f}_D] + \hat{f}_D - ED[\hat{f}_D] + \epsilon)^2] \tag{6} ED[(fED[f^D]+f^DED[f^D]+ϵ)2](6)

  3. 在上一步的基础上,将公式进一步展开为三部分:真实函数与预测函数期望值的差的平方,预测函数与预测函数期望值的差的平方,以及噪声的平方:

    E D [ ( f − E D [ f ^ D ] ) 2 + ( f ^ D − E D [ f ^ D ] ) 2 + ϵ 2 ] (7) ED [(f - ED[\hat{f}_D])^2 + (\hat{f}_D - ED[\hat{f}_D])^2 + \epsilon^2] \tag{7} ED[(fED[f^D])2+(f^DED[f^D])2+ϵ2](7)

  4. 最后,可以看出,这三部分分别对应偏差的平方 B i a s [ f ^ D ] 2 Bias[\hat{f}_D]^2 Bias[f^D]2,方差 V a r [ f ^ D ] Var[\hat{f}_D] Var[f^D],以及噪声的平方 ϵ 2 \epsilon^2 ϵ2。所以,得到了偏差-方差分解的公式:

    B i a s [ f ^ D ] 2 + V a r [ f ^ D ] + ϵ 2 (8) Bias[\hat{f}_D]^2 + Var[\hat{f}_D] + \epsilon^2 \tag{8} Bias[f^D]2+Var[f^D]+ϵ2(8)

这就完成了偏差-方差分解的过程,它揭示了模型误差的三个来源:偏差、方差和噪声。偏差反映了模型的预测平均值与真实值之间的差异,方差反映了模型预测值的波动性或离散程度,噪声则反映了数据本身的随机性。在实际的模型训练过程中,我们往往需要在偏差和方差之间寻找一个适当的平衡,以达到最低的预测误差。

所以说,总的泛化误差就是偏差、方差以及噪声的总和。理想的情况是,我们希望偏差和方差都尽可能地小,但实际上这两者往往是相互矛盾的,这就导致了偏差-方差权衡(bias-variance tradeoff)的问题。

3.3 解析

image-20230616125433543

来看下具体情况,描述从坐到右分别如下:

低偏差,低方差 (Low Bias, Low Variance):在这种情况下,模型的预测结果(蓝色的点)大部分都非常接近真实模型(中间的加号),而且每次训练得到的模型之间的差别也非常小。这意味着,模型既能准确地学习到数据的真实规律,也对数据的微小变化不敏感,因此模型的预测效果非常好。

高偏差,低方差 (High Bias, Low Variance):在这种情况下,虽然每次训练得到的模型之间的差别很小(蓝色的点非常集中),但是它们离真实模型(中间的加号)很远,这意味着模型并没有很好地学习到数据的真实规律,即模型的偏差较大。但是,由于模型简单,对数据的微小变化不敏感,因此模型的方差较小。

低偏差,高方差 (Low Bias, High Variance):在这种情况下,虽然模型的预测结果(蓝色的点)大部分都非常接近真实模型(中间的加号),但是每次训练得到的模型之间的差别较大。这意味着,模型能准确地学习到数据的真实规律,但对数据的微小变化过于敏感,导致模型的稳定性较差,即模型的方差较大。

高偏差,高方差 (High Bias, High Variance):在这种情况下,模型的预测结果(蓝色的点)既远离真实模型(中间的加号),同时每次训练得到的模型之间的差别也很大。这意味着,模型既没有很好地学习到数据的真实规律,又对数据的微小变化过于敏感,这种情况是我们最不希望看到的。

我们的目标是让模型既有低偏差,又有低方差,这样的模型预测效果才会最好。当遇到其他三种情况时,就需要通过调整模型复杂度、增加训练数据量、使用正则化等方法,来尽可能地降低模型的偏差和方差。

最后,感谢您阅读这篇文章!如果您觉得有所收获,别忘了点赞、收藏并关注我,这是我持续创作的动力。您有任何问题或建议,都可以在评论区留言,我会尽力回答并接受您的反馈。如果您希望了解某个特定主题,也欢迎告诉我,我会乐于创作与之相关的文章。谢谢您的支持,期待与您共同成长!

期待与您在未来的学习中共同成长。

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法小陈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值