资讯详情

OLS普通最小二乘法:原理、公式推导、诊断与Python实战

📅 2026/10/20 15:09:15 | 华诺云谱 👁 阅读
OLS普通最小二乘法:原理、公式推导、诊断与Python实战
做了这么多年数据分析我最大的一个感受是不要被“普通最小二乘法”这个名字唬住。它听起来像某种实验室里的高冷算法但OLS全称Ordinary Least Squares其实就是线性回归最经典的估计方法也是整个统计建模和机器学习里最值得花时间吃透的一块基石。几乎所有做回归分析的人第一天就会撞见它但“能用软件跑出来”和“真正理解它在干什么”是两回事。简单来说OLS做的是这样一件事给定一堆自变量和因变量的观测样本去找一条直线或超平面让所有样本点在这条直线上的预测误差整体上尽可能小。这个误差叫残差OLS特别的地方在于它把“误差最小”具体成了“残差平方和最小”。为什么一定要取平方取绝对值行不行取四次方行不行这些问题的答案恰好是理解线性回归、乃至后续一系列高级算法的钥匙。这篇分享适合正在学统计、做数据建模或者刚开始接触机器学习的新手。我会用一个场景把直觉建立起来然后手推公式再给可直接复制的Python代码最后把实操中踩过的坑一次性讲清楚。很多知识点分散在教科书和文档里这里整理成一条主线读完你至少能独立完成一次OLS建模并且看得懂结果里的每个核心指标。1. OLS到底在解决什么问题它凭什么这么流行1.1 从一堆散点讲到一条直线想象一个最朴素的业务场景你在评估投放金额对成交量的影响。每个月投入一笔广告费月底记录成交量半年下来得到六个点。把这些点放到坐标图上横轴是投放金额纵轴是成交量你自然会想画一条线让这条线尽量穿到点的中间去。问题来了什么叫“尽量穿过中间”换个说法预测值和实际值之间的误差越小越好。每一个样本点都有一个垂直方向上的差距——实际值减去模型预测值这个差距就是残差。OLS的答案很直接让全部残差的平方和最小。这就是“最小二乘”四个字的来源——“二乘”是平方“最小”是指目标函数取最小值。为什么是平方而不是别的东西这是很多新手第一个卡住的地方。平方有三个关键优势第一正负残差不会互相抵消第二平方会把大误差放大让模型更在意那些偏离很远的数据点第三平方函数是连续可导的凸函数数学上能求出解析解也就是我们常说的正规方程。如果换成绝对值残差和同样能够表达“误差最小”但绝对值在零点不可导求解过程会麻烦得多也就衍生出了另一套方法。1.2 “普通”到底普通在哪里统计学里有一堆带定语的最小二乘普通最小二乘、加权最小二乘、广义最小二乘。OLS被称为“普通”是因为它在误差项满足一定假定时给出了最简单的处理方式把每个点的权重视为相同。加权最小二乘会把方差大的点降权广义最小二乘会考虑误差之间的相关性而OLS一视同仁。用生活类比的话OLS就像一个对所有评价指标都按同样权重打分的老实人不偏不倚所以计算简单性质也极好。在经典假设下OLS保证估计出来的参数是线性的、无偏的而且在所有线性无偏估计里方差最小。统计学给这个性质起了个响亮的名字叫BLUE也就是Best Linear Unbiased Estimator。这句话的份量很大只要假设没被严重破坏你很难找到比OLS更稳定的线性估计方法。这也是为什么即使今天机器学习模型满天飞线性回归和OLS依然是无数业务分析里默认的第一道工序。1.3 OLS和其他拟合方法到底差别在哪很多人会把OLS、岭回归、Lasso放在一起比较但它们的定位不同。OLS追求无偏、最小方差适合特征少、数据干净、模型简单可解释的场景岭回归和Lasso牺牲一部分无偏性来换方差减小适合高维或存在多重共线性的场景。还有一种经常被人提起的LAD回归最小化绝对残差对离群点更稳健但计算代价高、统计性质也没有OLS那么优雅。方法目标函数优点缺点典型场景OLS残差平方和最小有闭式解、可解释性强、BLUE对离群点敏感、高维不稳定解释型回归、样本量充足LAD残差绝对值最小抗离群点求解慢、不再是唯一闭式解数据存在大量厚尾离群点岭回归残差平方和L2惩罚处理共线性、收缩系数有偏估计、系数解释略复杂特征相关性强、高维数据Lasso残差平方和L1惩罚可以做特征选择当特征高度相关时选择不稳定高维稀疏建模从这张表能看出来OLS是那个“教科书级”的基准。你要判断一个模型是不是有效通常的做法就是先跑一遍OLS看残差、看系数、看显著性再决定要不要上更复杂的工兵。2. 数学推导把OLS真正变成你能用的公式2.1 用矩阵把回归模型写清楚一元线性回归大家都能写出来y β0 β1x ε。但在实际项目里自变量往往不止一个手写这个方程会非常长。矩阵表示法更简洁y Xβ ε。这里的X是n行p列的设计矩阵n是样本量p是特征数量并且第一列通常全为1用来对应截距项β0。y是n维观测向量β是p维待估系数ε是误差向量。用矩阵的好处不只是省字数更重要的是之后的正规方程、协方差矩阵、预测公式都能用矩阵的运算规则一气呵成地推出来。一个容易忽略的细节是截距项。在软件里如果你用的是支持向量表示的库它会自动帮你加常数列如果你是自己用numpy手写矩阵求解一定记得先用np.column_stack把一列1拼进去。漏掉截距项是很常见的新手错误一旦漏掉整个模型就会被强行压着过原点结果几乎肯定会错。2.2 正规方程是怎么一步一步推出来的现在我们有了模型y Xβ ε目标是最小化残差平方和。残差就是y减去Xβ所以目标函数可以写成RSS(β) (y - Xβ)ᵀ(y - Xβ)展开这个式子能得到β的二次型。二次型的几何图像是一个碗状曲面碗底就是全局最小值。要求这个最小值对β求导并让导数等于0就能解出最优的β̂。求导过程并不复杂关键点是利用了对向量求导的链式法则。先对第一项和第二项分别求导整理之后会得到-2Xᵀ(y - Xβ) 0移项之后就是大名鼎鼎的正规方程XᵀXβ Xᵀy两侧左乘(XᵀX)⁻¹得到参数估计值的闭式解β̂ (XᵀX)⁻¹Xᵀy这就是你在很多教科书里看到那条矩阵公式。它看似神秘实际上只是“对二次函数求导找最低点”的矩阵版本。只要XᵀX这个矩阵可逆你就能一次性算出全部回归系数完全不用像神经网络那样迭代几百轮。2.3 用一组小数据手算一遍彻底看懂套路看公式还是容易飘我拿一组五条数据走一遍全流程。数据是x [1, 2, 3, 4, 5]y [2, 4, 5, 4, 5]。先算均值x的平均值是3y的平均值是4。斜率b1的公式是Σ(xi - x̄)(yi - ȳ)除以Σ(xi - x̄)²。分子分母都很好算分子是6分母是10所以b1等于0.6。截距b0 ȳ - b1x̄ 4 - 0.6 × 3 2.2。于是拟合直线是y 2.2 0.6x。把每个x代回去得到预测值2.8、3.4、4.0、4.6、5.2。残差分别是-0.8、0.6、1.0、-0.6、-0.2它们的平方和等于2.4。总平方和SST等于每个y与均值4的差的平方和算出来是6。R² 1 - SSE/SST 1 - 2.4/6 0.6意味着模型解释了60%的y的波动。手动算完这一遍你对“系数到底是怎么来的”会有一个瞬间的顿悟斜率和截距不是软件黑箱吐出来的数字而是直接从数据分布里解出来的最优值。2.4 高斯-马尔可夫定理凭什么默认选OLS高斯-马尔可夫定理是统计推断的定心丸。它说的是在误差项均值为0、方差恒定、且互不相关的条件下OLS得到的估计量在所有线性无偏估计量中方差最小。换句话说只要你坚持线性、无偏这两条路OLS已经是最经济的选择。这个定理也解释了为什么在同样的问题上有时候换一个看起来很花哨的估计方法效果反而更差。因为它们可能是“有偏”的或者在线性估计类里方差更大。当然高斯-马尔可夫定理不要求误差正态分布只要满足上述条件OLS的优良性质照样成立。真正需要谨慎的是误差独立、同方差这些前提是否被数据严重违背这一点我们下一节详细展开。3. 跑OLS之前必须检查的五件事3.1 关系是线性吗模型设定有没有问题OLS这个名字里带“线性”不是因为它只能拟合直线而是因为模型在参数上是线性的。你可以加入x²、x³或者交叉项照样可以套用最小二乘求解。但如果你硬是把一个明显呈曲线关系的数据塞进一次项模型残差图会立刻暴露问题——残差和拟合值之间出现明显的U形或倒U形模式。诊断方法很简单拟合完之后以拟合值为横轴、残差为纵轴画散点图。如果云团随机分布在零线上下设定基本合理如果出现系统性弯曲考虑加入多项式项、交互项或者对因变量做变换。我自己的习惯是每跑一个回归都先把残差图导出来看一眼这比任何高级检验都直观。3.2 误差是否独立、同方差、近似正态这三个条件对应的正是高斯-马尔可夫定理和t检验的前提。误差独立意味着一个样本的误差和另一个样本的误差没有相关性时间序列数据里这个问题特别突出。自相关会让标准误被低估明明不显著的变量看起来却显著。常用检测指标是Durbin-Watson统计量数值接近2说明无自相关明显偏离则要警惕。同方差性是另一个高频踩坑点。简单讲就是不同样本点上误差的波动幅度应该差不多大。如果残差图呈喇叭状左边点挤在一起、右边散得很开这就叫异方差。异方差不会让系数估计失效但会让标准误和p值失真后续我们聊解决方案。误差近似正态则主要影响小样本下的置信区间和假设检验。大样本情况下有中心极限定理兜底很多人对正态性没有抠得那么严但如果你要做小样本推断还是不能完全忽视它。统计软件里的Jarque-Bera检验就是专门看误差分布是否显著偏离正态的。3.3 自变量之间有没有多重共线性多重共线性是指自变量之间高度相关。想象一下你要同时用“身高”和“鞋码”去预测“体重”这两个变量几乎是一回事模型很难分清各自的贡献。结果就是系数估计值变得极其不稳定标准误膨胀甚至出现符号反转。检测共线性最常用的指标是VIF也就是方差膨胀因子。VIF_j 1/(1 - R²_j)其中R²_j是第j个自变量对剩余自变量做回归得到的判定系数。一般经验是VIF大于10就属于严重共线性。处理方法也很成熟删掉相关性高的变量、用主成分先降维或者直接用岭回归。记住共线性主要影响系数解释和推断如果你只关心预测它带来的恶果反而会小很多。假设检查项常用工具或指标违反时的影响常见对策线性关系残差vs拟合图模型设定错误、系数偏误加多项式项、交互项、变换误差独立Durbin-Watson标准误偏小、显著性虚高引入滞后项、广义最小二乘同方差残差图、Breusch-Pagan标准误偏离、推断不可靠稳健标准误、加权最小二乘误差正态Jarque-Bera小样本区间估计不准确变换因变量、换稳健方法无共线性VIF系数不稳定、符号异常删除变量、降维、岭回归4. 实操用Python把OLS完整跑通4.1 准备环境与模拟数据接下来进入直接能复制的部分。我建议是在Jupyter环境下跑一边看结果一边改。最基本的库是numpy、pandas、statsmodels画图还需要matplotlib。统计数据大多用statsmodels而不是sklearn因为前者对整个推断体系支持得更好。我们先造一组模拟数据三个变量之间保持清晰的数量关系方便验证OLS是否能正确还原它们import numpy as np import pandas as pd import statsmodels.api as sm np.random.seed(42) n 200 x1 np.random.uniform(1, 10, n) x2 np.random.uniform(5, 20, n) y 1.5 * x1 - 0.8 * x2 5 np.random.normal(0, 2, n) X_design np.column_stack([np.ones(n), x1, x2])这里的真实参数是β1 1.5β2 -0.8截距是5。误差项是均值为0、标准差为2的正态噪声。设计矩阵X_design第一列全是1用来估计截距这一步非常关键。4.2 自己写矩阵公式再和statsmodels对比第一步按照前面推导的正规方程手写求解。这不是表演而是检验你究竟有没有理解公式beta_hat np.linalg.inv(X_design.T X_design) X_design.T y print(手动求解的系数:, beta_hat)稳定输出应该接近手动求解的系数: [5.153 1.505 -0.819]和真实参数只有很小的偏差这就是随机误差带来的估计噪声。接下来用statsmodels跑标准拟合看它是否给出相同系数并且补全标准误和p值model sm.OLS(y, X_design).fit() print(model.summary())summary的输出里能看到一张比较完整的回归报告表。这张表很多人一开始看不懂但说到底最值得关注的是这么几块coef回归系数解释为“其他变量不变时该变量每增加一个单位y平均变化多少”。std err系数标准误衡量估计精度标准误越大系数越不可信。t和P|t|t统计量和p值看这个变量在统计上是否显著。R-squared模型解释了多少比例的y变化。F统计量及其p值整体回归是否显著。另外statsmodels还自动给出了DW、Jarque-Bera、Omnibus等多项诊断检验这些正好能对应上一节的假设检查。不要只盯着R²不放手我见过太多只看R²、不做任何诊断的分析报告后面每个结论都站不住脚。4.3 如何自行计算R²与残差诊断如果你想更细致地控制过程可以自己算R²y_pred X_design beta_hat ss_res np.sum((y - y_pred) ** 2) ss_tot np.sum((y - y.mean()) ** 2) r2 1 - ss_res / ss_tot print(R²:, r2)再把预测值和残差一起存进DataFrame方便画图import matplotlib.pyplot as plt df pd.DataFrame({y_true: y, y_pred: y_pred, resid: y - y_pred}) plt.scatter(df[y_pred], df[resid]) plt.axhline(0, colorred, linestyle--) plt.xlabel(Fitted Values) plt.ylabel(Residuals) plt.show()如果残差均匀分布在水平线两侧说明线性假设和同方差性基本站得住如果出现明显的弯曲或喇叭形就按上一节的表对症下药。这里多讲一句我通常在建模完成后会把系数、标准误、残差图一起打包到分析报告里因为这些才是让别人相信你的关键证据而不仅仅是一行代码输出。5. 常见问题与排查技巧实录5.1 系数符号和业务直觉相反怎么办这个问题我碰到过很多次。某次分析里预期某个因素对结果有正向影响得出的系数却是负数吓得我差点把模型扔掉。排查以后发现问题多半出在多重共线性或缺失变量上。先算一下变量之间的相关系数矩阵再看VIF。如果VIF过高比如超过10就需要考虑删掉其中一个高度相关的自变量或者做主成分分析。另外缺失变量的影响也很隐蔽一个真正起作用的变量没进模型时现有变量的系数会被污染方向都可能被扭曲。所以符号异常时别急着下结论先从数据关系和模型设定入手。5.2 残差图出现明显的喇叭口怎么处理异方差最常见的表现是残差图的离散程度随拟合值变化。解决方案要看你的目的如果只是想修正统计推断最简单的是给模型换用稳健标准误。在statsmodels里只需要一行代码model_robust sm.OLS(y, X_design).fit(cov_typeHC1) print(model_robust.summary())HC后面可以跟0到3一般分析里用HC1就够它能对标准误做小样本校正。系数不会变变的是标准误、t值和置信区间。如果异方差程度很严重还可以考虑把因变量做log变换在很多业务数据里取对数后残差会匀称得多。加权最小二乘也是一种正统解法但需要估计权重实操门槛稍高一旦用错反而引入新问题。5.3 有一个点几乎把回归线拽偏了怎么识别离群点和高杠杆点对OLS的杀伤力不容忽视毕竟它用的是平方损失任何一个残差很大的点都能被迫让整条线向它偏移。识别工具里最常用的是Cook距离from statsmodels.stats.outliers_influence import OLSInfluence infl OLSInfluence(model) cooks infl.cooks_distance[0]一般来说Cook距离大于4/n的点需要重点关注。但我要提个醒发现离群点不等于直接删除。先把这些点单独拿出来看语义有些可能是数据录入错误删掉合理有些只是真实存在的极端业务场景草率删除反而会造成模型对现实严重失准。我会先做敏感性和稳健性对比也就是保留和删除各跑一遍再决定最终模型怎么处理。5.4 数据里特征比样本量还多OLS还能用吗一旦样本量n小于特征数pXᵀX就是奇异矩阵直接用正规方程求逆会报错。统计学里这种情况叫“高维数据”OLS的闭式解失效。即使能算它也会完全记住训练数据没有任何泛化能力。如果确实遇到高维场景最实际的办法是换成正则化方法比如岭回归或Lasso它们的惩罚项能有效稳定系数估计。如果又想把OLS当基准那就先做特征选择把变量数量降到样本量以下。总之记住一条朴素规律OLS擅长的是“样本多、变量少、关系清晰”的问题拿它的短板去碰高维数据是在为难自己。6. 我这些年使用OLS的一些实际体会6.1 解释业务问题时我几乎总是先用OLS做数据分析尤其是要给管理层出结论的时候模型的预测精度只是其中一环能不能把结论讲清楚往往更重要。OLS的系数可以直接解读成“增加一个单位带来多少平均变化”这是很多黑盒模型做不到的。所以只要特征数量不是很多、数据量不是太小我都习惯用OLS作为第一版模型。有了OLS打底后续再想升级到随机森林或神经网络至少有个对照。如果复杂模型提升的预测幅度很有限我会重新审视它带来的解释成本是否划算。实际情况里很多商业问题的核心变量就那么几个线性关系已经能覆盖相当一部分规律。6.2 用OLS做预测时别把R²当圣旨R²很高不代表预测一定好R²很低也不代表模型没用。它衡量的是模型对已有样本波动的解释比例带有天然的“事后”属性。真要判断预测能力得做交叉验证或保留测试集看模型在没见过的新数据上表现如何。另外OLS对离群值敏感这决定了它在预测值波动很大的场景里未必是首选。如果你面对的因变量是收入、点击量这类长尾分布我建议把预测问题改造成分类问题或者结合log变换来处理比硬套线性模型好得多。6.3 最后分享一个对我帮助很大的小习惯每次拿到新数据准备做回归分析前我先不急着写代码而是把变量关系用散点图矩阵看一遍。这个习惯帮我避免了很多无头苍蝇式的排查。再一个习惯是无论多简单的模型都要强制自己输出一页完整的模型报告包括系数、标准误、置信区间、诊断指标和残差图。很多问题不是我跑模型的时候发现的而是我写报告准备解释结论的时候才被迫去研究清楚。OLS看起来是最朴素的那一类模型但正因为朴素它对每一条假设都毫不留情。吃透OLS你会在更高阶模型里不断复用它留下的工具箱残差、诊断、共线性、偏差与方差的权衡。先把这个底子打好再去看那些复杂算法你会顺手得多。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑