资讯动态

线性回归从原理到实战:最小二乘、sklearn实现与调参避坑指南

发布时间:2026/9/15 17:04:28 来源:尧图企业网站定制
很多人第一次接触机器学习都会被线性回归(LinearRegression)这个名词劝退觉得满屏都是公式和矩阵。但我可以用一句大实话给你交底线性回归的本质就是初中数学里求一条直线的加强版。它要做的是从一堆散乱的数据点里找到一条最合适的直线让这条线尽量贴合数据。只是到了机器学习的语境下这条线不再只是画在纸上而是变成了一个能做预测的模型。这篇文章我就用大白话把线性回归从原理到sklearn代码、从调参到避坑一次讲清楚保证你听完之后能直接上手并且知道每一步背后的为什么。这篇文章适合所有被机器学习公式劝退的初学者也适合已经会调包但总感觉原理模模糊糊的开发者。我会尽量少堆公式重点讲清楚每个选择背后的理由再用实际代码带你跑一遍最后分享一些常规文档里不会写的实战经验。1. 线性回归到底在干嘛从生活场景说起1.1 先忘掉公式用租房直觉理解线性回归想象一下你要租房在App上刷到几十套房源。你大概会观察到这样一个规律面积越大的房子租金往往越贵。如果把这几十套房子的面积和月租金画在坐标轴上横轴是面积纵轴是租金你就会看到一堆散点大致呈一条朝右上方倾斜的带状分布。线性回归要做的就是在这堆散点之间画一条直线让这条直线尽量从点的中间穿过去。这条线一旦画出来你就有了一件很实用的工具下次看到一个未知面积的房子你可以沿着这条线找到它对应的租金预测值。这条直线在数学上长这样y kx b。其中k是斜率代表面积每增加一平米租金平均涨多少钱b是截距可以理解为和面积无关的基础价格。当影响因素不止一个时公式就扩展成 y b k1x1 k2x2 ... knxn。这里的x1可以是面积x2可以是房龄x3可以是离地铁站的距离。每一个k都代表对应特征对目标值的影响程度。所以线性回归干的事情翻译成人话就是给定一堆样本数据找到一组系数让这条直线对现有数据的预测误差整体最小。这个朴素的优化问题在数学上有个听起来挺唬人的名字——最小二乘问题。1.2 为什么是最小二乘而不是最小绝对值最小二乘拆开来看就是误差的平方和最小。每次预测值和真实值之间会有一个差我们叫它残差。最小二乘把所有残差先平方、再求和让这个总和最小化。那为什么不直接让残差的绝对值之和最小呢这还真不是随意选的。第一个原因是平方会让大误差被加倍惩罚。举个例子你和朋友约好见面迟到5分钟和迟到10分钟对方的感觉差别绝不是简单翻倍10分钟的烦躁感明显更强烈。在数学上5的平方是2510的平方是100惩罚从25跳到100翻了4倍。这个特性会让模型更加重视那些偏差大的样本逼着回归线不要离任何一个点太远。第二个原因更重要平方函数处处可导求最优解非常方便。绝对值函数在零点处有个尖角不可导做最优化就要绕不少弯路。再加上最小二乘在矩阵形式下可以一步求出解析解计算效率高所以它成了默认选择。当然这个选择也有代价。正因为平方对大误差的惩罚更狠离群值会格外影响回归线的位置。这个坑我们后面会专门讲。1.3 损失函数与学习的本质算法里的学习本质上是定义一个损失函数然后通过调整参数让这个函数的值越来越小。线性回归的损失函数就是均方误差MSEJ (1/n) Σ(yi - ŷi)²。这里yi是真实值ŷi是预测值n是样本数量。我们训练模型的全部目标就是找到一组系数让这个J最小。找到最小值有两条路。一条路是直接解方程也就是正规方程θ (X^T X)^(-1) X^T y。这相当于拿着公式一步算出最优解。sklearn里的LinearRegression默认用的就是这类最小二乘解法底层通过奇异值分解来做比直接求逆数值上更稳定。另一条路是梯度下降。它的直觉特别像下山你在山顶看不清路但可以感受脚下哪个方向最陡然后朝最陡的方向迈一小步重复这个过程最后就能走到山谷。每一步迈多大由学习率决定迈太大可能跳过谷底迈太小则走得太慢。当样本量和特征数都不大的时候正规方程一步到位很方便当数据规模很大或者特征维度很高时直接求逆的计算量会爆炸这时候梯度下降更高效。理解这两条路你就明白了为什么有些机器学习库默认用解析解也知道什么时候该切换到迭代算法。2. 从直觉到代码用Python实现LinearRegression2.1 数据怎么选波士顿房价还能不能用很多老教程里用的都是波士顿房价数据集代码长得像这样from sklearn.datasets import load_boston。但如果你用的是新版本sklearn直接运行这行代码会报错因为官方在后续版本中移除了这个内置数据集。想继续用经典数据集的话有三条路使用sklearn内置的加利福尼亚房价数据集from sklearn.datasets import fetch_california_housing数据在联网时可以自动下载。自己合成数据训练之前我们就知道真实系数方便验证模型有没有学准。从外部下载波士顿房价的csv文件手动加载。我在教学时最喜欢用合成数据因为你能亲眼看到模型把对应的斜率和截距还原出来那种模型真的学到东西了的感觉特别明显。2.2 完整可复现的训练代码我们先从一个最简单的例子开始。我生成200个样本真实规律是 y 2.5x 5再加上一些服从正态分布的噪声模拟现实世界里大约如此但不完全精确的关系。import numpy as np import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split from sklearn.linear_model import LinearRegression # 生成合成数据 rng np.random.RandomState(42) X rng.rand(200, 1) * 10 # 特征0~10 true_k 2.5 # 真实斜率 true_b 5.0 # 真实截距 y true_k * X[:, 0] true_b rng.randn(200) * 2 # 画图看看数据分布 plt.scatter(X, y, alpha0.6) plt.xlabel(面积) plt.ylabel(价格) plt.show() # 切分训练集和测试集 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 ) # 训练线性回归模型 model LinearRegression() model.fit(X_train, y_train) print(模型斜率:, model.coef_) print(模型截距:, model.intercept_)运行这段代码你会看到输出大致是模型斜率: [2.508...] 模型截距: 4.993...斜率和截距都跟真实值非常接近说明模型在噪声干扰下还是把潜在规律挖出来了。2.3 fit和predict到底做了什么fit是训练方法它做的事情归结起来就是解最小二乘优化问题算出系数coef_和截距intercept_。predict是预测方法它做的是把新样本的x代入已经拟合好的方程算出预测值。这里值得多说一句fit并不是调用之后就明白了它是实实在在在求解一个优化问题。在sklearn内部的LinearRegression里这个求解过程通常是基于最小二乘法的矩阵分解不显式求逆所以即使数据中存在一些相关性较强的特征解出来的结果一般也不会报矩阵奇异的错只是系数会变得不稳定。这一点对我们理解后面的共线性问题很有帮助。fit完成后模型对象里就保存了学到的系数。你完全可以打印出来看甚至把它当成业务分析报告里的解释。比如系数是2.5你就可以说在其他条件不变的情况下面积每增加一个单位价格平均增加2.5。2.4 评估模型R²、MSE、RMSE怎么读模型训练完不能光看它自己说什么要拿它在测试集上的表现说话。from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score y_pred model.predict(X_test) mse mean_squared_error(y_test, y_pred) rmse np.sqrt(mse) mae mean_absolute_error(y_test, y_pred) r2 r2_score(y_test, y_pred) print(fMSE {mse:.3f}) print(fRMSE {rmse:.3f}) print(fMAE {mae:.3f}) print(fR² {r2:.3f})这四个指标各有各的脾气指标全称说明特点MSE均方误差预测误差的平方平均值对大误差非常敏感单位是目标变量的平方RMSE均方根误差MSE开根号单位回到目标变量本身更好理解MAE平均绝对误差误差绝对值平均对离群值不那么敏感R²决定系数模型解释了多少方差越接近1越好最大为1可为负数R²的计算公式是 R² 1 - SS_res / SS_tot。SS_res是模型残差的平方和SS_tot是真实值围绕均值波动的总平方和。如果R²接近1说明模型解释了数据里绝大部分波动如果R²等于0说明模型和直接用均值预测差不多如果R²小于0说明模型还不如均值预测。我之前遇到过有人看到MSE特别大就慌了实际上如果目标变量本身就大比如房价在几百万的量级MSE几百万很正常。所以判断模型好不好要综合R²、RMSE以及业务场景一起看不能单看一个数字。3. 核心细节与调参实战3.1 特征怎么选先看相关性别一把梭做多元线性回归时特征不是多多益善。第一个快速排查工具是相关性矩阵。拿真实数据集来做演示from sklearn.datasets import fetch_california_housing import pandas as pd housing fetch_california_housing() df pd.DataFrame(housing.data, columnshousing.feature_names) df[MedHouseVal] housing.target corr df.corr()[MedHouseVal].sort_values(ascendingFalse) print(corr)输出会告诉你每个特征和目标之间的线性相关程度。相关性高的特征一般对模型有用但这里有个坑相关性不代表因果而且如果两个特征彼此强相关比如房间数和居住人数模型可能就会不稳定。我的经验是在正式建模前先看一眼特征之间的相关性矩阵。如果发现某两个特征的相关系数超过了0.8我会认真考虑去掉其中一个或者用VIF方差膨胀因子做进一步判断。VIF超过10说明多重共线性严重这时系数容易被特征之间的拉扯搞得很不稳定解释起来也很别扭。3.2 数据标准化什么时候必须做标准化StandardScaler是把特征的均值变成0、标准差变成1的操作。很多人搞不清楚线性回归到底要不要做标准化我直接给结论如果只用普通最小二乘线性回归不做标准化也能算出正确结果但各特征系数的大小不能直接用来比较谁更重要因为特征的单位和取值范围完全不同。比如面积范围是0到100房龄范围是1到20它们系数的尺度天然不一样。如果用了正则化Ridge、Lasso必须做标准化。因为惩罚项会把所有系数按统一尺度往0压缩如果特征量纲差异大惩罚会不公平。如果后续要自己实现梯度下降标准化能明显加快收敛速度。from sklearn.preprocessing import StandardScaler scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test)这里有一件特别重要的事我必须单独拎出来说先切分数据集再在训练集上做fit_transform然后在测试集上只做transform。千万不要在train_test_split之前就对着整个数据集做fit_transform。否则测试集的信息提前泄露给模型了评估结果会虚高。这是新手很容易踩的坑。3.3 哑变量陷阱分类特征怎么处理线性回归输入的特征要求是数值型所以分类变量比如城市、房屋朝向需要转成哑变量也就是one-hot编码。比如朝向有东、南、西、北四种取值one-hot后会生成四列0/1的列。但这里有个陷阱如果四列全留加上模型本身的截距项就会发生完全共线性也就是著名的哑变量陷阱。原因是截距项可以看作是全1的列而四个朝向的哑变量加起来也等于全1的列出现线性相关矩阵不可逆系数解不唯一。解决办法很简单生成哑变量时丢掉第一列。pd.get_dummies(df, columns[朝向], drop_firstTrue)。这样n个类别只生成n-1列剩下的那个类别作为基准不会和截距打架。如果哪天你发现模型训练后某些系数的符号明显违背业务直觉而且数值忽大忽小先检查一下是不是哑变量没drop_first。3.4 正则化岭回归和Lasso什么时候用当特征很多、样本相对少或者特征间存在多重共线性时标准的最小二乘解会变得非常极端系数可能特别大模型对训练集拟合得很好但一到新数据就完全崩溃也就是过拟合。正则化的思路是在损失函数里加一个惩罚项逼着系数不要太大。常用有三种方法惩罚项效果Ridge岭回归L2系数平方之和把系数往0压缩但不会正好等于0LassoL1系数绝对值之和部分系数会被压缩成0相当于自动特征选择ElasticNetL1L2综合两者适合特征很多的情况from sklearn.linear_model import Ridge, Lasso ridge Ridge(alpha1.0) ridge.fit(X_train_scaled, y_train) lasso Lasso(alpha0.01) lasso.fit(X_train_scaled, y_train)这里的alpha是惩罚强度越大系数压得越狠。调参时可以用交叉验证sklearn里有RidgeCV和LassoCV能自动帮你挑一个合适的alpha。但我得提醒一句不要为了用正则化而用正则化。如果特征数量不多、数据量也不小普通LinearRegression完全够用结果也更直观。正则化最核心的应用场景是特征维度高、共线性强、模型波动大的时候。我自己的习惯是先跑普通线性回归作为baseline发现测试集效果远低于训练集、或者系数明显不合理再引入Ridge或Lasso。4. 常见问题与排查技巧实录4.1 模型效果差按这个顺序排查新手最常问的问题就是为什么我的R²这么低或者我用了线性回归但预测出来全是差不多的值。遇到这种情况别急着换算法先按顺序检查这些环节检查线性关系是否成立。先用散点图看特征和目标之间的分布。如果散点图明显是U形或倒U形线性模型当然拟合不好。看有没有缺失值。df.isnull().sum()缺失值是老生常谈但真的很常见。找离群点。一个极端值就能把回归线拉偏一大截。可以用箱线图或者标准化后z-score大于3的样本检查。因为均方误差对离群点的惩罚被平方放大了所以离群点对线性回归的影响比很多人想象中大得多。看特征量纲差异。量纲悬殊太大时如果用正则化模型结果会被大数值特征主导。检查数据泄露。是不是先做了标准化再切分的是不是模型训练时不小心用到了未来的信息看是否真的需要做特征变换。比如把特征取对数有时候能把非线性关系掰直一大半。这条排查路径我走过无数次大部分模型效果差的问题其实都是在前三步就找到答案了根本轮不到换模型。4.2 R²为负数是怎么回事R²的公式是 1 - SS_res / SS_tot理论上如果你严格按照线性回归训练在训练集上R²不会为负但测试集上完全可能。这意味着你的模型比不管三七二十一直接预测平均值还要差。常见原因有三个测试集和训练集分布不一致。比如训练集里大面积房子多测试集里小面积房子多模型预测就会乱套。没有设置截距。LinearRegression(fit_interceptFalse)会在数据本身有偏置时效果很差相当于强制让回归线穿过原点。数据强非线性。比如真实关系是二次的你用直线去拟合在端点附近的预测会非常离谱测试集R²变成负数很正常。遇到R²为负我的建议是先把训练集和测试集的分布对比一下再检查特征和目标的关系别急着宣布模型凉了。4.3 系数不稳定、一跑就变是怎么回事这是我在实际项目中经常遇到的问题训练数据和代码都没变偶尔多几个样本再一跑系数的变化幅度大得吓人。最常见的原因就是多重共线性。举个例子特征x1表示房屋面积特征x2表示房间数。这两个特征高度相关模型可以把解释力在它们之间来回分配。于是x1的系数可能一会儿是2一会儿是5x2的系数一会儿是3一会儿是0但整体预测精度差不多。这就是系数不稳定的根源。我的处理办法是先算VIF把高度共线的特征剔除一个或者改用Ridge用L2惩罚把系数固定下来。次常见的原因是样本量太小一两个新样本就能显著改变最优解。这种情况除了尽量收集更多数据也可以考虑用bagging之类的思路做多模型平均。5. 线性回归的边界与进阶路线5.1 线性回归的四条基本假设线性回归不是魔法它在一个理想假设体系下工作效果最好自变量和因变量存在线性关系。误差项相互独立。误差项方差恒定即同方差性。误差项近似正态分布。这些假设如果被严重违背预测效果和系数解释都会受影响。怎么检查最简单的方法是画残差图把预测值放在横轴残差放在纵轴。如果残差随机分布在零线附近说明模型还算健康如果残差呈现明显的喇叭形分布说明方差并不恒定如果呈现弯曲的形状说明关系不是纯线性的。我刚入门的时候觉得这些假设都是课本上的废话直到在一个真实数据集上看到残差图后才明白这些假设是排查问题的指南针。5.2 什么时候别用线性回归虽然我说线性回归是baseline神器但它不是万能的。下面几种场景我一般会直接绕开它预测目标是分类标签二分类、多分类应该用逻辑回归或者树模型。特征与目标之间的关系高度非线性而且在业务逻辑上这种非线性是有明确原因的。高维稀疏数据比如文本的TF-IDF矩阵特征几万维线性回归容易过拟合而且训练慢这时候更适合线性模型配L1正则或者直接用树模型。特征之间存在复杂交互线性回归表达不了只有当x1很大时x2才有作用这类关系。但即便明知最后要上复杂模型我也会先跑一版线性回归拿一个baseline分数。这个习惯的价值后面我会专门说。5.3 从线性回归走向更复杂模型的进阶路线理解了线性回归就等于拿到了理解一大票模型的钥匙。逻辑回归就是线性回归加了一个sigmoid函数用于分类多项式回归是给特征加上高次项相当于用曲线去做拟合广义线性模型则是换掉误差分布和链接函数扩展到更多场景。往后走你可以去了解决策树、随机森林、梯度提升树但你会发现自己理解起来比直接上来就啃树模型的人快很多因为你知道什么是baseline、什么是过拟合、损失函数和评估指标为什么长那个样子。线性回归是机器学习里最小的完整闭环数据、模型、损失函数、优化、评估、调参全都在里面。最后分享一个我个人的习惯每次接到新的预测任务无论业务方最终想要多复杂的模型我第一版永远是线性回归。不是因为我偷懒而是因为它能让我在一个小时内搞清楚这些特征到底和目标有没有关系、方向对不对、大概量级是多少。很多次我跑完线性回归后发现业务方嘴里说的核心变量在系数上根本不显著反而是某个冷门特征贡献很大这就是可解释性的价值。我还有一个用了很久的小技巧模型建完先画残差图有点规律就回去修数据而不是急着换算法。这些经验看着不起眼但在真实项目里能帮你省下的时间和踩坑成本却是实打实的。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价