news 2026/5/28 2:04:57

别再死记硬背公式了!用NumPy手搓线性回归,从MSE、R²到闭式解一次搞懂

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
别再死记硬背公式了!用NumPy手搓线性回归,从MSE、R²到闭式解一次搞懂

从零手搓线性回归:NumPy实现与数学本质深度解析

在机器学习的世界里,线性回归就像"Hello World"一样经典,但很多人只是机械地调用sklearn的LinearRegression,对背后的数学原理一知半解。本文将带你用NumPy从零实现线性回归,不仅会写代码,更要理解每一行背后的数学意义。我们将从最基础的均方误差(MSE)开始,逐步推导到决定系数(R²)和闭式解(Normal Equation),让你真正掌握这个看似简单却内涵丰富的算法。

1. 线性回归的本质与数学表达

线性回归的核心思想是找到一条直线(或超平面),使得所有数据点到这条直线的垂直距离平方和最小。用数学语言表达就是:

$$ y = X\theta + \epsilon $$

其中:

  • $y$ 是目标变量(n×1向量)
  • $X$ 是特征矩阵(n×d矩阵,通常会增加一列1作为截距项)
  • $\theta$ 是参数向量(d×1向量)
  • $\epsilon$ 是误差项

为什么选择平方和而不是绝对值和?这涉及到几个关键原因:

  1. 平方函数处处可导,便于数学处理
  2. 对应了高斯噪声假设下的最大似然估计
  3. 对大误差给予更高惩罚,使模型更稳健

注意:虽然绝对值损失(L1)也有其优点,但在线性回归的经典设定中,平方损失(L2)能给出解析解并具有良好统计性质。

2. 评估指标:MSE与R²的实现与解读

2.1 均方误差(MSE)的NumPy实现

MSE衡量预测值与真实值之间的平均平方误差,计算公式为:

$$ MSE = \frac{1}{n}\sum_{i=1}^n (y_i - \hat{y}_i)^2 $$

用NumPy实现仅需一行代码:

def mse_score(y_predict, y_test): return np.mean((y_predict - y_test)**2)

MSE的物理意义

  • 数值越小表示预测越准确
  • 对异常值敏感(因为平方放大了大误差)
  • 量纲与原始数据的平方相同

2.2 决定系数(R²)的深入理解

R²衡量模型解释目标变量变异的比例,计算公式为:

$$ R^2 = 1 - \frac{\sum(y_i - \hat{y}_i)^2}{\sum(y_i - \bar{y})^2} $$

NumPy实现:

def r2_score(y_predict, y_test): y_mean = np.mean(y_test) numerator = np.sum((y_predict - y_test)**2) denominator = np.sum((y_mean - y_test)**2) return 1 - numerator / denominator

R²的关键特性

特性说明
范围[0,1](可能为负,表示模型比均值预测还差)
解释0.7表示模型解释了70%的数据变异
比较可用于不同量纲模型的比较
陷阱随特征增加而增加,可能过拟合

提示:R²=0.3在某些领域(如社会科学)可能已经不错,而在物理实验中可能难以接受,需要结合领域知识判断。

3. 闭式解的推导与实现

3.1 最小二乘法的矩阵推导

我们的目标是找到θ最小化损失函数:

$$ J(\theta) = (y - X\theta)^T(y - X\theta) $$

对θ求导并令导数为零:

$$ \frac{\partial J(\theta)}{\partial\theta} = -2X^T(y - X\theta) = 0 $$

解得闭式解:

$$ \theta = (X^TX)^{-1}X^Ty $$

3.2 NumPy实现闭式解

class LinearRegression: def __init__(self): self.theta = None def fit_normal(self, train_data, train_label): # 添加截距项 X = np.hstack([train_data, np.ones((len(train_data), 1))]) # 计算闭式解 self.theta = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(train_label) return self.theta def predict(self, test_data): X = np.hstack([test_data, np.ones((len(test_data), 1))]) return X.dot(self.theta)

实现细节分析

  1. np.hstack添加全1列对应截距项
  2. np.linalg.inv计算矩阵逆(当$X^TX$不可逆时需特殊处理)
  3. 矩阵乘法顺序影响计算效率

3.3 数值稳定性问题与解决方案

当$X^TX$接近奇异矩阵时,求逆会出现数值不稳定。解决方法包括:

  • 正则化:使用$(X^TX + \lambda I)^{-1}$
  • QR分解:更稳定的数值方法
  • SVD分解:处理秩亏矩阵
# 使用SVD的稳健实现 def fit_svd(self, train_data, train_label): X = np.hstack([train_data, np.ones((len(train_data), 1))]) U, s, Vt = np.linalg.svd(X, full_matrices=False) self.theta = Vt.T @ np.diag(1/s) @ U.T @ train_label return self.theta

4. 从数学到实践:常见问题与技巧

4.1 特征工程的重要性

即使数学推导完美,垃圾输入也会产生垃圾输出。关键步骤:

  1. 标准化:使特征均值为0,方差为1
    X = (X - np.mean(X, axis=0)) / np.std(X, axis=0)
  2. 异常值处理:使用RobustScaler或Winsorization
  3. 特征选择:通过R²、p值或正则化选择重要特征

4.2 模型诊断与验证

实现模型后,需要验证其合理性:

  • 残差分析:检查是否随机分布
    residuals = y_test - y_pred plt.scatter(y_pred, residuals)
  • 学习曲线:判断是否欠拟合或过拟合
  • 交叉验证:评估模型泛化能力

4.3 扩展到其他场景

虽然我们实现了普通最小二乘(OLS),但线性回归家族还有:

  • 岭回归:L2正则化解决共线性
  • Lasso回归:L1正则化进行特征选择
  • 弹性网络:结合L1和L2正则化
# 岭回归实现 def fit_ridge(self, train_data, train_label, alpha=1.0): X = np.hstack([train_data, np.ones((len(train_data), 1))]) I = np.eye(X.shape[1]) I[-1,-1] = 0 # 不对截距项正则化 self.theta = np.linalg.inv(X.T.dot(X) + alpha*I).dot(X.T).dot(train_label) return self.theta

在实际项目中,我发现当特征数大于样本数时,直接使用闭式解往往会导致过拟合。这时加入L2正则化(岭回归)能显著提升模型稳定性。另外,对于时间序列数据,还需要特别注意处理自相关性问题,普通线性回归的假设可能不再成立。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/28 2:04:50

SpringBoot学习日记——DAY07(mybatis-plus代码生成器)

今天对MyBatis-Plus的代码生成器展开了学习:1.使用MyBatis-Plus的代码生成器完成代码自动生成:步骤如下:1.1编写application.yml:要在文件里编写上url,username,password,还有swagger的配置原则…

作者头像 李华
网站建设 2026/5/28 2:03:36

008、YOLO 数据标注格式详解:YOLO txt、COCO JSON、VOC XML 互转工程方案

008、YOLO 数据标注格式详解:YOLO txt、COCO JSON、VOC XML 互转工程方案 一个让我熬夜到凌晨三点的标注格式问题 去年做工业缺陷检测项目,甲方给了5000张PCB板图像,标注格式是VOC XML。我习惯用YOLOv5训练,直接拿脚本转成YOLO tx…

作者头像 李华
网站建设 2026/5/28 2:03:05

手把手教你配置鼎捷T100二次开发环境:从模块、表格到函数的命名规则全解析(附实战示例)

鼎捷T100二次开发实战指南:从环境搭建到命名规范全解析1. 开发环境准备与基础概念鼎捷T100作为企业级ERP系统,其二次开发环境与传统软件开发有显著差异。初次接触的开发者在配置环境时往往会遇到各种"水土不服"的情况。我们先从最基础的开发工…

作者头像 李华
网站建设 2026/5/28 2:02:04

品牌推广怎么少走弯路:这 10 个误区别踩

很多人一提品牌问题,第一反应是 Logo 不够高级、颜色没选对、海报不够好看。但真实情况往往不是这样。多数品牌做不好,不是某一个设计细节翻车,而是定位、视觉、文案、体验和业务状态对不上。你说自己专业,页面却很乱;…

作者头像 李华