Skip to content

Latest commit

 

History

History
391 lines (218 loc) · 16.7 KB

linear-regression-in-depth-part-1-485f997fd611.md

File metadata and controls

391 lines (218 loc) · 16.7 KB

线性回归深入探讨(第一部分)

原文:towardsdatascience.com/linear-regression-in-depth-part-1-485f997fd611

深入探讨线性回归模型的理论和实现

Dr. Roi YehoshuaTowards Data Science Dr. Roi Yehoshua

·发表于Towards Data Science ·阅读时间 13 分钟·2023 年 4 月 18 日

--

Enayet Raheem拍摄于Unsplash

线性回归是最基础且最常用的预测模型之一。它可以追溯到 1805 年,当时勒让德和高斯使用线性回归来预测行星的运动。

回归问题的目标是根据其他变量的值预测一个变量的值。例如,我们可以使用回归预测股票价格,基于各种经济指标,或者根据广告支出的金额预测公司的总销售额。

在线性回归中,我们假设给定的输入特征与目标标签之间存在线性关系,并且我们试图找到这种关系的确切形式。

本文提供了关于线性回归模型理论和实现的全面指南。在文章的第一部分,我们将主要关注简单线性回归,其中数据集仅包含一个特征(即数据集由二维点组成)。在文章的第二部分,我们将讨论多重线性回归,其中数据集可能包含多个特征。

有许多与回归相关的术语,数据科学家经常将它们混用,但它们并不总是相同,例如:残差/误差,成本/损失/误差函数,多重/多变量回归,平方损失/均方误差/平方残差和等。

鉴于此,我在本文中尽力对所使用的定义和术语进行尽可能清晰的阐述。

正式定义和符号

回归问题

在回归问题中,我们得到一组 n 个标记示例:

D = {(x₁, y₁), (x₂, y₂), … , (xₙ, yₙ)},其中 x 表示示例 i特征yᵢ 表示该示例的标签

每个x 是一个包含 m 个特征的向量:x = (xᵢ₁, xᵢ₂, …, xᵢₘ),其中 表示转置。变量 xᵢⱼ 被称为独立变量解释变量

标签 y 是一个连续值变量 (yR),称为因变量响应变量

我们假设标签 y 和输入向量 x 之间存在某种相关性,这种相关性由某个函数 f(x) 和一个误差变量 ϵ 建模:

误差变量ϵ捕捉了所有未建模的因素,这些因素影响标签除了特征外,例如测量误差或一些随机噪声。

我们的目标是找到函数 f(x),因为知道这个函数将使我们能够预测任何新样本的标签。然而,由于我们只能从有限数量的训练样本中学习 f(x),因此我们只能获得这个函数的估计值。

我们的模型从给定数据中估算的函数称为模型的假设,通常表示为* h*(x)。

线性回归

线性回归中,我们假设特征和目标标签之间存在线性关系。因此,模型的假设具有以下形式:

线性回归模型

w₀, …, wₘ 称为模型的参数(或权重)。参数 w₀ 通常称为截距(或偏置),因为它表示 h(x) 的图与 *y-*轴(在二维情况下)的交点。

为了简化 h(x),我们添加了一个常数特征 x₀,总是等于 1。这样我们可以将 h(x) 写成特征向量 x = (x₀, …, xₘ) 和权重向量 w = (w₀, …, wₘ) 的点积:

线性回归模型的向量形式

普通最小二乘法(OLS)

在线性回归中,我们的目标是找到参数 w₀, …, wₘ,使得我们模型的预测 h(x) 尽可能接近真实标签 y。换句话说,我们希望找到最能拟合数据集的模型参数。

为此,我们定义了一个成本函数(有时也称为误差函数),该函数衡量我们模型的预测与真实标签之间的距离。

我们从定义残差开始,残差是给定数据点的标签与模型预测值之间的差异:

残差的定义

普通最小二乘(OLS)回归找到使平方残差和最小的最佳参数值:

最小二乘成本函数

注意,损失函数计算每个观察值的误差,在 OLS 中称为平方损失,而成本函数(通常用 J 表示)计算整个数据集的误差,在 OLS 中称为平方残差和(SSR)或平方误差和(SSE)。

尽管 OLS 是最常见的回归类型,但还有其他类型的回归,例如最小绝对偏差回归。我们将在本文的最后一部分解释为什么最小二乘函数是首选的成本函数。

幸运的是,除了某些特殊情况(稍后将讨论),最小二乘成本函数是凸函数。一个函数 f(x) 是凸的,如果图形上任意两点之间的线段都位于图形之上。简单来说,函数图形呈杯形 ∪。这意味着凸函数只有一个最小值,即全局最小值。

由于 J(w) 是凸的,使用一阶导数找到其最小值点可以保证得到唯一解,因此也是最优解。

简单线性回归

当数据集只有一个特征(即由二维点 (x, y) 组成)时,回归问题称为简单线性回归

从几何上讲,在简单线性回归中,我们尝试找到一条直线,使其尽可能接近所有数据点:

简单线性回归

在这种情况下,模型的假设只是直线的方程:

回归线的方程

其中 w₁ 是直线的斜率,w₀ 是直线与 y- 轴的交点。在这种情况下,残差是数据点与拟合直线之间的距离。

在这种情况下,最小二乘成本函数的形式如下:

OLS 成本函数在简单线性回归中的表现

正规方程

我们的目标是找到使得线最符合数据点的参数 w₀ 和 w₁,即使得成本最小的直线。为此,我们可以对 J(w₀, w₁) 关于两个参数分别求偏导数,将其设为 0,然后解这个线性方程组(这些方程被称为正规方程)。

让我们从 J 关于 w₀ 的偏导数开始:

将这个导数设为 0 可以得到以下结果:

我们已经找到了关于 w₀ 的表达式,该表达式以 w₁ 和数据点为变量。

接下来,我们计算Jw₁的偏导数:

将这个导数设置为 0 得到以下结果:

让我们将表达式* w*₀代入这个方程中:

因此,回归线的系数为:

数值示例

假设我们想找出身高和体重之间是否存在线性相关性。我们得到以下 10 个示例,代表了 30 至 39 岁美国女性的平均身高和体重(来源:世界年鉴与事实手册,1975 年)。

训练集

为了手动找到回归线,我们首先构建以下表格:

根据表格最后一行的总计,我们可以计算回归线的系数:

因此,拟合线的方程为:

Python 实现

我们现在将使用 Python 找到回归线。

首先,让我们编写一个通用函数,用于找到任何给定二维数据集的回归线参数:

def find_coefficients(x, y):
    n = len(x)
    w1 = (n * x @ y - x.sum() * y.sum()) / (n * (x**2).sum() - x.sum()**2)
    w0 = (y.sum() - w1 * x.sum()) / n
    return w0, w1

上述代码是将正规方程直接转换为 NumPy 函数和运算符。

让我们在上面的数据集上测试我们的函数。我们首先定义我们的数据点:

x = np.array([1.55, 1.60, 1.63, 1.68, 1.70, 1.73, 1.75, 1.78, 1.80, 1.83])
y = np.array([55.84, 58.57, 59.93, 63.11, 64.47, 66.28, 68.10, 69.92, 72.19, 74.46])

让我们绘制它们:

def plot_data(x, y):
    plt.scatter(x, y)
    plt.xlabel('Height (m)')
    plt.ylabel('Weight (kg)')
    plt.grid()
plot_data(x, y)

训练集

我们现在使用刚刚编写的函数来寻找回归线的参数:

w0, w1 = find_coefficients(x, y)
print('w0 =', w0)
print('w1 =', w1)
w0 = -47.94681481481781
w1 = 66.41279461279636

我们得到了与手动计算相同的结果,但精度更高。

让我们编写另一个函数来绘制回归线。为此,我们可以简单地取输入范围内的最小和最大x值,计算它们在回归线上的y坐标,然后绘制连接这两点的线:

def plot_regression_line(x, y, w0, w1):
    p_x = np.array([x.min(), x.max()])
    p_y = w0 + w1 * p_x
    plt.plot(p_x, p_y, 'r')

最后,让我们将回归线与数据点一起绘制:

plot_data(x, y)
plot_regression_line(x, y, w0, w1)

回归线

我们可以看到这两个变量之间的关系非常接近线性。

作为练习,从 Kaggle 下载身高和体重数据集。该数据集包含了 25,000 名 18 岁青少年的身高和体重。建立一个线性回归模型,用于预测青少年的体重,并绘制结果。

评估指标

有几种评估指标用于评估回归模型的性能。最常见的两个指标是RMSE(均方根误差)和R²得分

注意评估指标成本函数之间的区别。成本函数用于定义模型学习过程的目标,并在训练集上计算。相反,评估指标用于训练过程后评估模型在保留数据集(验证集或测试集)上的表现。

RMSE(均方根误差)

RMSE 定义为平方误差的均值的平方根(模型预测与真实标签之间的差异):

RMSE 定义

注意,我们在模型训练过程中称为残差的东西,通常在计算保留集上的时候称为误差(或预测误差)。

RMSE 总是非负的,较低的 RMSE 表明模型对数据的拟合更好(完美的模型 RMSE 为 0)。

我们可以直接计算 RMSE 或通过使用 sklearn.metrics 模块来计算。这个模块提供了许多用于测量不同类型模型性能的函数。虽然它没有明确计算 RMSE 的函数,但我们可以使用 mean_squared_error() 函数首先计算 MSE,然后取其平方根得到 RMSE。

sklearn.metrics 中的大多数评分函数期望得到一个包含真实标签 (y_true) 和模型预测 (y_pred) 的数组。因此,我们首先需要计算模型在给定数据点上的预测。这可以通过使用回归线的方程轻松完成:

y_pred = w0 + w1 * x

我们现在可以调用 mean_squared_error() 函数并找到 RMSE:

from sklearn.metrics import mean_squared_error as MSE

rmse = np.sqrt(MSE(y, y_pred))
print(f'RMSE: {rmse:.4f}')

我们得到的结果是:

RMSE: 0.5600

RMSE 的优点:

  • 提供了模型误差的平均幅度的度量。

  • 由于误差在平均之前被平方,RMSE 对大误差赋予了相对较高的权重。

  • 可用于比较不同模型在同一数据集上的性能。

RMSE 的缺点:

  • 不能用于比较模型在不同数据集上的表现,因为它依赖于输入特征的尺度。

  • 对离群值敏感,因为每个误差对 RMSE 的影响与平方误差的大小成正比。

R² 分数

R² 分数(也称为决定系数)是衡量模型拟合优度的指标。它计算回归模型的平方误差之和与始终预测 y 的均值的基线模型的平方误差之和之间的比率,并从 1 中减去该比率:

R² 分数定义

其中 是目标标签的均值。

最佳的R²评分为 1,这表明模型预测与数据完全吻合。一个始终预测* y均值的常量模型,无论输入特征如何,其R*²评分为 0。

R²评分低于 0 表示模型的表现比最差的最小二乘预测器还要差。这通常表明选择了错误的模型。

要计算R²评分,我们可以使用 sklearn.metrics 中的r2_score函数:

from sklearn.metrics import r2_score

score = r2_score(y, y_pred)
print(f'R2 score: {score:.4f}')

我们得到的结果是:

R2 score: 0.9905

R²评分非常接近 1,这意味着我们有一个几乎完美的模型。然而,请注意,在这个例子中,我们是在训练集上评估模型,在训练集上模型通常会有比在保留集上更高的评分。

R²评分也可以解释为模型中自变量对因变量* y*方差的解释比例(感兴趣的读者可以在这个维基百科文章中找到原因)。

R²评分的优点:

  • 不依赖于特征的尺度。

  • 可以用来比较不同模型在不同数据集上的表现。

R²评分的缺点:

  • 不提供有关模型误差大小的信息。

  • R²评分随着模型特征数量的增加而单调增加,因此不能用来比较特征数量非常不同的模型。

OLS 和最大似然

最后,我们将展示普通最小二乘(OLS)和最大似然之间的关联,这也是使用 OLS 解决回归问题的主要动机。更具体地说,我们将证明在假设误差服从均值为零的正态分布的条件下,OLS 估计量与最大似然估计量(MLE)是相同的。

对最大似然概念不熟悉的人,可以查看我的上一篇文章

记住,在线性回归中,我们假设标签由特征的线性函数加上一些随机噪声生成:

假设误差是独立同分布(i.i.d.)的,并且具有均值为 0、方差为σ²的正态分布:

在这种情况下,标签* y也服从均值为wx 和方差为σ*²的正态分布(向正态分布变量中添加常数将得到一个正态分布的变量,但其均值被该常数平移):

因此,给定输入x和权重向量wy的概率密度函数(PDF)为:

基于误差(因此标签)的独立假设,我们可以将模型参数w的似然表示如下:

因此,对数似然是:

我们可以看到,对数似然中唯一依赖于参数w的表达式是:

这正是普通最小二乘法(OLS)的成本函数!因此,最大化模型的似然等同于最小化平方残差和。

最后的说明

除非另有说明,否则所有图片均由作者提供。

你可以在我的 GitHub 上找到本文的代码示例:github.com/roiyeho/medium/tree/main/simple_linear_regression

讨论多元线性回归的文章第二部分可以在这里找到。

感谢阅读!