当前位置: 首页 > article >正文

线性回归简介:从理论到应用

什么是线性回归?

线性回归是一种用于预测数值型结果的统计方法,它通过建立一个或多个自变量(输入特征)与因变量(输出目标)之间的线性关系模型来工作。在最简单的形式中,即简单线性回归,仅涉及一个自变量和一个因变量,而多变量线性回归则考虑了多个自变量。

数学表达

在线性回归中,假设自变量 x x x 和因变量 y y y 之间存在线性关系,可以表示为:
y = θ 0 + θ 1 x + ϵ y = \theta_0 + \theta_1 x + \epsilon y=θ0+θ1x+ϵ
其中, θ 0 \theta_0 θ0 是截距项, θ 1 \theta_1 θ1 是斜率参数,描述了 x x x y y y 的影响程度,而 ϵ \epsilon ϵ 表示误差项,代表了未被模型捕捉到的变异性。

损失函数

为了找到最佳拟合直线,我们定义了一个损失函数,通常采用均方误差(Mean Squared Error, MSE)的形式:
J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta) = \frac{1}{2m} \sum_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)})^2 J(θ)=2m1i=1m(hθ(x(i))y(i))2
这里, h θ ( x ) h_\theta(x) hθ(x)是模型的预测值, y ( i ) y^{(i)} y(i) 是实际值, m m m 是样本数量。

参数估计

为了最小化损失函数 J ( θ ) J(\theta) J(θ),我们使用梯度下降法或正规方程等方法来更新参数 θ \theta θ。这些方法旨在寻找一组参数值,使得模型对训练数据的预测尽可能准确。

梯度下降法

梯度下降是一种迭代优化算法,它通过沿着损失函数的负梯度方向调整参数来逐步减少损失。更新规则如下:
θ j : = θ j − α ∂ ∂ θ j J ( θ ) \theta_j := \theta_j - \alpha \frac{\partial}{\partial \theta_j} J(\theta) θj:=θjαθjJ(θ)
其中, α \alpha α 是学习率,控制每次更新的步长大小。线性回归利用梯度下降法进行参数更新的公式推导如下:

  1. 定义损失函数:首先,定义线性回归的损失函数(通常为均方误差,Mean Squared Error, MSE):
    J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta) = \frac{1}{2m} \sum_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)})^2 J(θ)=2m1i=1m(hθ(x(i))y(i))2
    其中:
  • h θ ( x ( i ) ) = θ T x ( i ) h_\theta(x^{(i)}) = \theta^T x^{(i)} hθ(x(i))=θTx(i) 是模型的预测值。
  • y ( i ) y^{(i)} y(i) 是实际值。
  • m m m 是训练样本的数量。
  1. 求导:为了最小化损失函数 J ( θ ) J(\theta) J(θ),我们需要对参数 θ \theta θ 求导,并令导数等于0。具体来说,我们对每个参数 θ j \theta_j θj 偏导数:
    ∂ ∂ θ j J ( θ ) = ∂ ∂ θ j ( 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 ) \frac{\partial}{\partial \theta_j} J(\theta) = \frac{\partial}{\partial \theta_j} \left( \frac{1}{2m} \sum_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)})^2 \right) θjJ(θ)=θj(2m1i=1m(hθ(x(i))y(i))2)

  2. 计算偏导数:计算上述表达式的偏导数 ∂ ∂ θ j J ( θ ) = 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) ⋅ ∂ ∂ θ j h θ ( x ( i ) ) \frac{\partial}{\partial \theta_j} J(\theta) = \frac{1}{m} \sum_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)}) \cdot \frac{\partial}{\partial \theta_j} h_\theta(x^{(i)}) θjJ(θ)=m1i=1m(hθ(x(i))y(i))θjhθ(x(i))
    由于 h θ ( x ( i ) ) = θ T x ( i ) h_\theta(x^{(i)}) = \theta^T x^{(i)} hθ(x(i))=θTx(i),所以: ∂ ∂ θ j h θ ( x ( i ) ) = x j ( i ) \frac{\partial}{\partial \theta_j} h_\theta(x^{(i)}) = x_j^{(i)} θjhθ(x(i))=xj(i)
    因此: ∂ ∂ θ j J ( θ ) = 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \frac{\partial}{\partial \theta_j} J(\theta) = \frac{1}{m} \sum_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)}) x_j^{(i)} θjJ(θ)=m1i=1m(hθ(x(i))y(i))xj(i)

  3. 更新规则:为了最小化损失函数,我们沿着负梯度方向更新参数 θ j \theta_j θj
    θ j : = θ j − α ∂ ∂ θ j J ( θ ) \theta_j := \theta_j - \alpha \frac{\partial}{\partial \theta_j} J(\theta) θj:=θjαθjJ(θ)
    代入上面的偏导数结果: θ j : = θ j − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \theta_j := \theta_j - \alpha \frac{1}{m} \sum_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)}) x_j^{(i)} θj:=θjαm1i=1m(hθ(x(i))y(i))xj(i)

  4. 最终更新公式

整理得到最终的参数更新公式:
θ j : = θ j − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \theta_j := \theta_j - \alpha \frac{1}{m} \sum_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)}) x_j^{(i)} θj:=θjαm1i=1m(hθ(x(i))y(i))xj(i)

这就是线性回归中使用梯度下降法进行参数更新的公式。


import numpy as np
def linear_regression_gradient_descent(X: np.ndarray, y: np.ndarray, alpha: float, iterations: int) -> np.ndarray:
    m, n = X.shape
    theta = np.zeros((n, 1))
    for _ in range(iterations):
        predictions = X @ theta
        errors = predictions - y.reshape(-1, 1)
        updates = X.T @ errors / m
        theta -= alpha * updates
    return np.round(theta.flatten(), 4)

正规方程

对于某些问题,可以直接求解最优参数,无需迭代过程。这可以通过解下面的正规方程完成:
θ = ( X T X ) − 1 X T y \theta = (X^T X)^{-1} X^T y θ=(XTX)1XTy
这种方法适用于当特征数量不多且矩阵可逆时的情况。具体推导过程如下:
线性回归参数更新公式的推导如下:

  1. 目标函数:线性回归的目标是找到一组参数 θ \theta θ,使得预测值 h θ ( x ) h_\theta(x) hθ(x) 与实际值 y y y 之间的误差最小。通常使用均方误差(Mean Squared Error, MSE)作为损失函数:
    J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta) = \frac{1}{2m} \sum_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)})^2 J(θ)=2m1i=1m(hθ(x(i))y(i))2
    其中, h θ ( x ) = θ T x h_\theta(x) = \theta^T x hθ(x)=θTx 是预测值, x ( i ) x^{(i)} x(i) y ( i ) y^{(i)} y(i) 分别是第 i i i 个训练样本的特征向量和目标值。

  2. 损失函数的矩阵形式:将上述公式转换为矩阵形式,设 X X X 是特征矩阵(每一行是一个训练样本,每一列是一个特征), y y y 是目标值向量,则损失函数可以写为:
    J ( θ ) = 1 2 m ( X θ − y ) T ( X θ − y ) J(\theta) = \frac{1}{2m} (X\theta - y)^T (X\theta - y) J(θ)=2m1(y)T(y)

  3. 求导:为了找到使损失函数最小化的 θ \theta θ,需要对 θ \theta θ 导,并令导数等于0。首先计算损失函数关于 θ \theta θ 的导数:
    ∇ θ J ( θ ) = 1 m X T ( X θ − y ) \nabla_\theta J(\theta) = \frac{1}{m} X^T (X\theta - y) θJ(θ)=m1XT(y)

  4. 设置导数为0:令导数等于0,得到:
    1 m X T ( X θ − y ) = 0 \frac{1}{m} X^T (X\theta - y) = 0 m1XT(y)=0
    化简得:
    X T X θ = X T y X^T X \theta = X^T y XT=XTy

  5. 解方程:假设 X T X X^T X XTX 是非奇异的(即可逆),则可以通过两边同时左乘 ( X T X ) − 1 (X^T X)^{-1} (XTX)1 得到:
    θ = ( X T X ) − 1 X T y \theta = (X^T X)^{-1} X^T y θ=(XTX)1XTy

这就是线性回归中使用正规方程(Normal Equation)来求解参数 θ \theta θ 的过程。

import numpy as np
def linear_regression_normal_equation(X: list[list[float]], y: list[float]) -> list[float]:
	# Your code here, make sure to round
	X = np.array(X)
	y = np.array(y).reshape(-1, 1)
	X_T = X.T
	theta = np.linalg.inv(X_T @ X) @ X_T @ y
	theta = np.round(theta, 4).flatten().tolist()
	return theta

实际应用

当然线性回归也是可以捕捉到数据中的非线性关系的,只需要在数据中进行预处理即可。比如,当利用变量 ( x 1 , x 2 ) (x_1, x_2) (x1,x2)预测房价 y y y,我们可以手动添加特征 x 1 2 , x 1 x 2 x_1^{2},x_1x_2 x12,x1x2之类经过非线性变换后的变量,这样就可以让线性回归学习到非线性关系了!更细致的线性回归讲解可以参考Google Crash Courese 线性回归


http://www.kler.cn/a/526799.html

相关文章:

  • 仿真设计|基于51单片机的无线投票系统仿真
  • python学opencv|读取图像(四十七)使用cv2.bitwise_not()函数实现图像按位取反运算
  • chrome源码剖析—进程通信
  • maven、npm、pip、yum官方镜像修改文档
  • python | OpenCV小记(一):cv2.imread(f) 读取图像操作(待更新)
  • 基于 NodeJs 一个后端接口的创建过程及其规范 -- 【elpis全栈项目】
  • 01. 计算机系统
  • C++ 中的引用(Reference)
  • 第十一章 F - H 开头的术语
  • 数据结构与算法之哈希表: LeetCode 1797. 设计一个验证系统 (Ts版)
  • 深入剖析 Docker 的镜像分层存储机制
  • jhat命令详解
  • 3.拼正方形python解法——2024年省赛蓝桥杯真题
  • 第28章 星骗计划的开篇
  • 25.Word:学生成绩管理系统【8】
  • plot(a_star_path(:, 1), a_star_path(:, 2), ‘r-‘, ‘LineWidth‘, 2);
  • 实验七 JSP内置对象II
  • 力扣【98. 验证二叉搜索树】Java题解(容易写错的题)
  • Java小白入门教程:内置数据类型(四类八种)和引用数据类型
  • Java知识速记:深拷贝与浅拷贝
  • 基于Python的药物相互作用预测模型AI构建与优化(下.代码部分)
  • LabVIEW透镜多参数自动检测系统
  • HTML DOM 修改 HTML 内容
  • SG算法解析
  • java_throw和throws的区别
  • 【OpenGL】OpenGL游戏案例(二)