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

从头开始学习AI:第二篇 - 线性回归的数学原理与实现

回顾与引言

在上一篇中,我们实现了简单的线性回归模型。本篇将深入探讨背后的数学原理,解释代码中使用的公式,并展示如何使用scikit-learn库更高效地实现相同功能。

线性回归的数学原理

线性回归的目标是找到一条直线,使得所有数据点到这条直线的垂直距离(残差)的平方和最小。这就是所谓的​​最小二乘法​​。

1. 模型表示

简单线性回归模型可以表示为:

y=\beta _{0}+\beta _{1}x+\epsilon

其中:

  • y 是因变量(目标值)
  • x 是自变量(特征)
  • β0​ 是截距
  • β1​ 是斜率
  • ϵ 是误差项

2. 参数估计

我们需要找到β0​和β1​的最佳估计值,使得残差平方和(RSS)最小:

RSS=\sum_{i=1}^{n}(y_{i}-(\beta _{0}+\beta _{1}x_{i}))^{2}

通过对RSS关于β0​和β1​求偏导并令其为零,可以得到以下解:

斜率 (β1​) 的计算公式​​:

\beta _{1}=\frac{\sum_{i=1}^{n}(x_{i}-\bar{x})(y_{i}-\bar{y})}{\sum_{i=1}^{n}(x_{i}-\bar{x})^{2}}

截距 (β0​) 的计算公式​​:

\beta _{0}=\bar{y}-\beta _{1}\bar{x}

这些公式正是我们上一篇文章中simple_linear_regression函数实现的内容。

代码实现与数学公式对应

让我们将代码与数学公式对应起来:

def simple_linear_regression(x, y):"""实现简单线性回归(一元线性回归)对应数学公式:β₁ = Σ[(xᵢ - x̄)(yᵢ - ȳ)] / Σ(xᵢ - x̄)²β₀ = ȳ - β₁x̄参数:x -- 自变量数组(特征)y -- 因变量数组(目标值)返回:slope (β₁) -- 斜率intercept (β₀) -- 截距"""# 计算均值 x̄ 和 ȳx_mean = np.mean(x)  # x̄y_mean = np.mean(y)  # ȳ# 计算分子 Σ[(xᵢ - x̄)(yᵢ - ȳ)]numerator = np.sum((x - x_mean) * (y - y_mean))# 计算分母 Σ(xᵢ - x̄)²denominator = np.sum((x - x_mean) ** 2)# 计算斜率 β₁slope = numerator / denominator# 计算截距 β₀ = ȳ - β₁x̄intercept = y_mean - slope * x_meanreturn slope, intercept

使用scikit-learn实现

虽然自己实现算法有助于理解,但在实际项目中我们通常使用成熟的库。下面是使用scikit-learn的实现:

# 首先导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_scoredef simple_linear_regression(x, y):"""实现简单线性回归(一元线性回归)对应数学公式:β₁ = Σ[(xᵢ - x̄)(yᵢ - ȳ)] / Σ(xᵢ - x̄)²β₀ = ȳ - β₁x̄参数:x -- 自变量数组(特征)y -- 因变量数组(目标值)返回:slope (β₁) -- 斜率intercept (β₀) -- 截距"""# 计算均值 x̄ 和 ȳx_mean = np.mean(x)  # x̄y_mean = np.mean(y)  # ȳ# 计算分子 Σ[(xᵢ - x̄)(yᵢ - ȳ)]numerator = np.sum((x - x_mean) * (y - y_mean))# 计算分母 Σ(xᵢ - x̄)²denominator = np.sum((x - x_mean) ** 2)# 计算斜率 β₁slope = numerator / denominator# 计算截距 β₀ = ȳ - β₁x̄intercept = y_mean - slope * x_meanreturn slope, interceptdef predict(x, slope, intercept):"""使用线性回归模型进行预测参数:x -- 输入值slope -- 斜率intercept -- 截距返回:预测值 y = slope * x + intercept"""return slope * x + interceptdef plot_regression(x, y, slope, intercept):"""绘制数据点和回归线参数:x -- 自变量数组y -- 因变量数组slope -- 斜率intercept -- 截距"""# 创建预测值y_pred = predict(x, slope, intercept)# 绘制散点图plt.scatter(x, y, color='blue', label='实际数据')# 绘制回归线plt.plot(x, y_pred, color='red', label='回归线')plt.xlabel('X')plt.ylabel('Y')plt.title('简单线性回归')plt.legend()plt.show()def sklearn_linear_regression(x, y):"""使用scikit-learn实现线性回归参数:x -- 自变量数组(需要reshape为二维数组)y -- 因变量数组返回:model -- 训练好的线性回归模型"""# 将x转换为二维数组 (n_samples, n_features)x_reshaped = x.reshape(-1, 1)# 创建并训练模型model = LinearRegression()model.fit(x_reshaped, y)# 输出模型参数print(f"scikit-learn实现:")print(f"斜率(系数): {model.coef_[0]:.4f}")print(f"截距: {model.intercept_:.4f}")# 计算预测值y_pred = model.predict(x_reshaped)# 计算评估指标mse = mean_squared_error(y, y_pred)r2 = r2_score(y, y_pred)print(f"均方误差(MSE): {mse:.4f}")print(f"R²分数: {r2:.4f}")return model# 示例使用
if __name__ == "__main__":# 创建示例数据np.random.seed(42)x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])y = np.array([2.1, 3.9, 6.2, 8.1, 10.2, 11.8, 14.1, 15.9, 18.2, 20.1])# 使用自定义实现slope, intercept = simple_linear_regression(x, y)print(f"\n自定义实现:")print(f"斜率: {slope:.4f}")print(f"截距: {intercept:.4f}")# 使用scikit-learn实现model = sklearn_linear_regression(x, y)# 比较两种方法的结果print("\n两种实现结果对比:")print("斜率差异:", abs(slope - model.coef_[0]))print("截距差异:", abs(intercept - model.intercept_))# 可视化结果plot_regression(x, y, slope, intercept)
自定义实现:
斜率: 2.0012
截距: 0.0533
scikit-learn实现:
斜率(系数): 2.0012
截距: 0.0533
均方误差(MSE): 0.0184
R²分数: 0.9994两种实现结果对比:
斜率差异: 0.0
截距差异: 0.0

模型评估指标

在机器学习中,我们需要量化模型的性能。常用的回归评估指标有:

1. 均方误差 (MSE)

MSE=\frac{1}{n}\sum_{i=1}^{n}(y_{i}-\hat{y}_{i})^{2}

2. R²分数 (决定系数)

R^{2}=1-\frac{\sum_{i=1}^{n}(y_{i}-\hat{y}_{i})^{2}}{\sum_{i=1}^{n}(y_{i}-\hat{y})^{2}}

R²分数表示模型解释的目标变量方差的比例,取值范围在0到1之间,越接近1表示模型拟合越好。

数学推导补充

最小二乘法推导

为了找到使RSS最小的β0​和β1​,我们需要解以下优化问题:

\min _{\beta_{0}, \beta_{1}} \sum_{i=1}^{n}\left(y_{i}-\beta_{0}-\beta_{1} x_{i}\right)^{2}

对β0​求偏导:

\frac{\partial R S S}{\partial \beta_{0}}=-2 \sum_{i=1}^{n}\left(y_{i}-\beta_{0}-\beta_{1} x_{i}\right)=0

对β1​求偏导:

\frac{\partial R S S}{\partial \beta_{1}}=-2 \sum_{i=1}^{n} x_{i}\left(y_{i}-\beta_{0}-\beta_{1} x_{i}\right)=0

解这组方程即可得到前面的参数估计公式。

学习心得与总结

通过本次学习,我更加深入地理解了:

  1. 1.线性回归背后的数学原理
  2. 2.最小二乘法的推导过程
  3. 3.如何使用scikit-learn高效实现线性回归
  4. 4.模型评估的重要指标

有趣的是,比较自定义实现和scikit-learn的实现结果,两者几乎完全一致(差异在浮点数精度范围内),这验证了我们自己实现的正确性。

下一步计划

  1. 1.学习多元线性回归及其实现
  2. 2.探索正则化方法(岭回归和Lasso回归)
  3. 3.深入研究梯度下降算法
  4. 4.学习交叉验证技术
http://www.xdnf.cn/news/1458271.html

相关文章:

  • 基础crud项目(前端部分+总结)
  • Flink反压问题
  • 算法 --- 分治(归并)
  • 【Markdown转Word完整教程】从原理到实现
  • VOC、COCO、YOLO、YOLO OBB格式的介绍
  • AgentThink:一种在自动驾驶视觉语言模型中用于工具增强链式思维推理的统一框架
  • 深入剖析Spring Boot / Spring 应用中可自定义的扩展点
  • elasticsearch学习(五)文档CRUD
  • 基于脚手架微服务的视频点播系统-界面布局部分(二):用户界面及系统管理界面布局
  • 02-ideal2025 Ultimate版安装教程
  • SPI flash挂载fatfs文件系统
  • 什么是静态住宅IP 跨境电商为什么要用静态住宅IP
  • More Effective C++ 条款28:智能指针
  • 稠密矩阵和稀疏矩阵的对比
  • 神马 M21 31T 矿机解析:性能、规格与市场应用
  • Python多序列同时迭代完全指南:从基础到高并发系统实战
  • vcruntime140_1.dll缺失?5个高效解决方法
  • 手机秒变全栈IDE:Claude Code UI的深度体验
  • SpringBoot实现国际化(多语言)配置
  • MySQL 8.0 主从复制原理分析与实战
  • 深入解析Java HashCode计算原理 少看大错特错的面试题
  • 多线程——线程状态
  • 并发编程——17 CPU缓存架构详解高性能内存队列Disruptor实战
  • ResNet(残差网络)-彻底改变深度神经网络的训练方式
  • linux——自定义协议
  • 多Agent协作案例:用AutoGen实现“写代码+测Bug”的自动开发流程
  • 秒店功能更新:多维度优化升级,助力商家经营
  • 当 LLM 遇上真实世界:MCP-Universe 如何撕开大模型 “工具能力” 的伪装?
  • 记录相机触发相关
  • 机器学习入门,第一个MCP示例