【机器学习|DAY04】线性回归(Linear Regression)笔记
线性回归
1. 线性回归核心思想
1.1 什么是线性回归
线性回归是一个监督学习中的回归类算法。
核心思想:利用回归方程(也就是一个函数)对特征值(自变量)和目标值(因变量)之间的关系进行建模,通过训练数据学习出一组合适的参数,使得预测值尽可能接近真实值。
线性回归的数学表达为:
y ^ = w 1 x 1 + w 2 x 2 + ⋯ + w n x n + b \hat{y} = w_1x_1 + w_2x_2 + \dots + w_nx_n + b y^=w1x1+w2x2+⋯+wnxn+b
写成矩阵形式:
y ^ = X w + b \hat{y} = Xw + b y^=Xw+b
其中 w w w 是权重向量, X X X 是特征矩阵, b b b 是偏置项。三者都是矩阵,模型输出就是特征与权重的线性组合。
1.2 “线性”到底指什么?
一开始我也困惑:线性回归只能拟合直线(或平面)吗?如果特征里出现 x²,还是不是线性回归?
答案:线性回归的“线性”,是指对参数 w 线性,而不是对特征 x 线性。
一个模型只要能够写成:
y ^ = w 0 + w 1 ϕ 1 ( x ) + w 2 ϕ 2 ( x ) + ⋯ + w m ϕ m ( x ) \hat{y} = w_0 + w_1 \phi_1(\mathbf{x}) + w_2 \phi_2(\mathbf{x}) + \dots + w_m \phi_m(\mathbf{x}) y^=w0+w1ϕ1(x)+w2ϕ2(x)+⋯+wmϕm(x)
且满足:
- ϕ i ( x ) \phi_i(\mathbf{x}) ϕi(x) 是任意关于原始特征的变换(可以是 x 2 x^2 x2、 sin ( x ) \sin(x) sin(x)、 log x \log x logx、 x 1 x 2 x_1x_2 x1x2 等均可)
- 每个 w i w_i wi 都以一次方的形式出现,且彼此不相乘、不相除、不嵌套
那么,它就是线性回归模型,哪怕 ϕ i ( x ) \phi_i(\mathbf{x}) ϕi(x)再扭曲,也不影响模型的“线性”身份。
举个例子:
y = w₁x² + w₂√x + w₃sin(x) + b ✅ 线性回归
y = w₀ + w₁x₁ + w₂x₂ + w₃x₁x₂ + w₄x₁² ✅ 线性回归
y = w²x + b ❌ 不是线性回归(参数出现平方)
虽然 x 经过了平方、开根号、正弦变换,但 w₁、w₂、w₃ 依然是一次幂,这仍然是线性回归。模型拟合出来的依旧是一个超平面,只不过是在由 x²、√x、sin(x) 构成的新特征空间里的平面。
欧克,看到这里我们又注意到一个关键信息,让我们再理解一下:“模型拟合出来的依旧是一个超平面,只不过是在由 x²、√x、sin(x) 构成的新特征空间里的平面”好~这里我们从根本理解“线性”。
1.3 从几何理解“线性”本质
假设我们构造了这样一组特征: z 1 = x , z 2 = x 2 , z 3 = sin ( x ) z_1 = x, z_2 = x^2, z_3 = \sin(x) z1=x,z2=x2,z3=sin(x)
模型就可以写成: y ^ = w 0 + w 1 z 1 + w 2 z 2 + w 3 z 3 \hat{y} = w_0 + w_1 z_1 + w_2 z_2 + w_3 z_3 y^=w0+w1z1+w2z2+w3z3
现在,我们把这些 z 1 , z 2 , z 3 z_1, z_2, z_3 z1,z2,z3 当作三个独立的坐标轴。那么上式就是一个关于 z z z 的线性方程,也就是说在由 ( z 1 , z 2 , z 3 , y ) (z_1, z_2, z_3, y) (z1,z2,z3,y) 张成的四维空间中,它代表一个超平面(三维平面)。
这就是"线性回归的’线性’是指对参数 w w w 线性"这句话的几何直观:无论原始特征 x x x 经过多么复杂的变换 ϕ i ( x ) \phi_i(x) ϕi(x),只要我们把变换后的新特征 z i = ϕ i ( x ) z_i = \phi_i(x) zi=ϕi(x) 看作新的坐标轴,模型在 z z z 空间里就是线性的(一个超平面)。
因此,线性回归的“线性“本质上是参数空间的线性,而不是原始特征空间的线性。非线性不是模型带来的,是特征工程带来的。
在原始特征空间看y=x^2+x 当然就是一个曲线对吧。
1.4 线性回归的分类
根据特征数量划分:
- 单变量回归(简单线性回归):只有一个特征 x,形式为
y = wx + b - 多元回归(多重线性回归):有多个特征 x₁, x₂, …, xₙ
两者本质相同,只是特征矩阵 X 的列数不同。单变量回归就是多元回归在 n=1 时的特例。
需要注意的是,单变量/多变量的划分依据是原始输入特征的数量。即使我们做了多项式扩展(比如将 x x x 扩展为 x , x 2 x, x^2 x,x2),模型在输入层面仍然是单变量,但算法内部是以多变量线性回归的方式在运作(算法内部就是把 x 和 x² 当成两个独立维度,在这两个维度张成的空间中拟合一个超平面)。
2. 工作流程
线性回归不像 KNN 那样在预测时才临时计算,它有一套清晰的训练 - 预测两阶段流程。
训练阶段(核心:让机器自己总结规律)
- 接收训练数据:给定包含
m个样本的训练集,每个样本有n个特征,以及对应的真实目标值y。 - 定义模型形式:确定使用线性方程
ŷ = X·w + b来表达特征与目标的关系,其中w和b是待学习的参数。 - 初始化参数:通常将所有权重
w和偏置b初始化为随机值或零。 - 定义损失函数:选择一个衡量预测误差的函数(默认为均方误差 MSE),它的值越小表示模型拟合得越好。
- 选择优化算法:决定用哪种算法寻找让损失最小的参数,可以直接求解析解(正规方程),也可以用梯度下降类方法逐步逼近。
- 迭代更新参数(若用迭代法):
- 计算当前参数下的损失函数梯度;
- 沿负梯度方向更新参数,学习率控制步长;
- 重复直到损失收敛或达到最大迭代次数。
(若使用正规方程,则直接通过矩阵运算一步解出最优参数,没有迭代过程。)
- 输出训练好的模型:保存最终的
w和b,训练结束。
预测阶段
- 接收新样本:给定一个或多个待预测样本的特征向量
x_new。 - 代入方程计算:使用训练好的参数,直接计算
ŷ = x_new·w + b。 - 输出预测值:
ŷ即为该样本的连续值预测结果。
回顾之前笔记,我们可以知道机器学习是基于模型的算法,它会根据已有数据自己总结规律。我们不需要深究内部每一步具体是怎么编码构造函数的,但需要清楚它如何定义好坏(损失函数) 以及 如何优化(优化方法及正则化)。
3. 损失函数
3.1 损失值是什么?
模型预测的结果和真实结果之间存在误差,也叫做损失值。损失函数的作用就是把这种误差量化成一个具体的数值,让我们可以衡量当前模型有多"差"。而我们训练模型的目标就是让这个数值尽可能小。
3.2 常用损失函数
-
均方误差 MSE(Mean Squared Error):
M S E = 1 n ∑ i = 1 n ( y ^ i − y i ) 2 MSE = \frac{1}{n} \sum_{i=1}^{n} (\hat{y}_i - y_i)^2 MSE=n1i=1∑n(y^i−yi)2
对每个样本的预测误差求平方,再取平均。因为是平方,大误差会被放大,模型会更关注那些预测偏差大的样本。 -
误差平方和 SSE(Sum of Squared Errors):
S S E = ∑ i = 1 n ( y ^ i − y i ) 2 SSE = \sum_{i=1}^{n} (\hat{y}_i - y_i)^2 SSE=i=1∑n(y^i−yi)2
就是 MSE 不除以 n,只求和。本质上和 MSE 表达的信息一样,只是差了一个常数因子。在线性回归的数学推导中用 SSE 更常见,因为求导时消掉常数更简洁。选择 MSE 还是 SSE 不影响最终优化结果,只影响损失值的绝对大小,不改变最小值的位置。
4. 优化算法:如何找到最小化损失的参数
优化的本质问题:找到一组 w,使损失函数的值最小。这是一个"w 和损失值之间的函数"求最小值的问题。解决思路主要有两派:正规方程 和 梯度下降。
4.1 正规方程(Normal Equation)
思路直接:要求函数最小值,那就对 w 求导,令导数为 0,解出 w。
推导过程:
- 损失函数普通方式转成矩阵方式:
J ( w ) = ( h ( x 1 ) − y 1 ) 2 + ( h ( x 2 ) − y 2 ) 2 + ⋯ + ( h ( x m ) − y m ) 2 = ∑ i = 1 m ( h ( x i ) − y i ) 2 = ∥ X w − y ∥ 2 2 \begin{aligned} J(w) &= (h(x_1)-y_1)^2 + (h(x_2)-y_2)^2 + \dots + (h(x_m)-y_m)^2 \\ &= \sum_{i=1}^m (h(x_i)-y_i)^2 = \|Xw - y\|_2^2 \end{aligned} J(w)=(h(x1)−y1)2+(h(x2)−y2)2+⋯+(h(xm)−ym)2=i=1∑m(h(xi)−yi)2=∥Xw−y∥22
- 对损失函数 J ( w ) = ∥ X w − y ∥ 2 2 J(w) = \|Xw - y\|_2^2 J(w)=∥Xw−y∥22 求导并令导数为零:
2 ( X w − y ) X = 0 2 ( X w − y ) ( X X T ) = 0 X T 2 ( X w − y ) ( X X T ) ( X X T ) − 1 = 0 X T ( X X T ) − 1 2 ( X w − y ) = 0 X w = y X T X w = X T y \begin{aligned} 2(Xw - y)X &= 0 \\ 2(Xw - y)(XX^T) &= 0X^T \\ 2(Xw - y)(XX^T)(XX^T)^{-1} &= 0X^T(XX^T)^{-1} \\ 2(Xw - y) &= 0 \\ Xw &= y \\ X^TXw &= X^Ty \\\end{aligned} 2(Xw−y)X2(Xw−y)(XXT)2(Xw−y)(XXT)(XXT)−12(Xw−y)XwXTXw=0=0XT=0XT(XXT)−1=0=y=XTy
如果 X T X X^TX XTX 可逆,则解为:
w = ( X T X ) − 1 X T y w = (X^TX)^{-1}X^Ty w=(XTX)−1XTy
方阵不一定有逆矩阵。 XᵀX 可逆的前提是 X 的列向量线性无关(列满秩)。如果特征之间存在线性相关(多重共线性),XᵀX 就是奇异矩阵,无法求逆。这也是选择梯度下降而不选正规方程的一个理由。
正规方程的特点:
- 优点:一步到位,不需要迭代,不需要选学习率
- 缺点:矩阵求逆的时间复杂度是 O(n³)(n 为特征数),特征维度高时非常慢;且 XᵀX 不可逆时无法使用。
4.2 梯度下降(Gradient Descent)
4.2.1 理解梯度
从二维开始:在二维空间(y = f(x))中,某一点的导数表示该点的斜率,含义是"当 x 发生微小变化时,y 发生怎样的变化"。
- 导数的符号指明了变化的方向,即导数为正时,x增大会使y增大;导数为负时,y减小会使y减小。
- 导数的数值告诉我们变化的剧烈程度。
可以想象二维空间平面,导数是切线,但是先不要过度限制在这个切线所指方向的思考,理解导数有正负取值,而我们探究的是x如何变化让y变小,x也只有向左向右移动(也就是变大变小的两种选择),而导数为正时,x增大会使y增大;导数为负时,y减小会使y减小。再来看导数是斜率这个点,斜率越大,也就是切线越陡峭,也就代表了x变化会使y变化越大。
推广到多维:上升到多维空间,函数在各个方向上的变化率由方向导数描述。
设方向向量为 l(单位向量),函数 f 沿 l 的方向导数为:
∂ f ∂ l = ∇ f ⋅ l = ∥ ∇ f ∥ ⋅ ∥ l ∥ ⋅ cos θ \frac{\partial f}{\partial l} = \nabla f \cdot l = \|\nabla f\| \cdot \|l\| \cdot \cos\theta ∂l∂f=∇f⋅l=∥∇f∥⋅∥l∥⋅cosθ
这个点积告诉我们:当 l 与梯度 ∇f 同向(夹角为0°)时,cosθ=1,方向导数取最大值,即函数上升最快;当夹角为180°(反向)时,方向导数取最小值,函数下降最快。
梯度就是那个向量,它指向函数值增长最快的方向,其模长表示增长的陡峭程度。 那么我们想要损失函数下降最快,自然应该朝负梯度方向更新参数。
理解梯度的方向和数值:
- 方向:函数值增长最快的方向,即各个维度特征值如何变化,函数值变化最快。
- 数值(模长):沿该方向函数值变化的陡峭程度。
4.2.2 梯度下降
我们的目标是让损失函数变小,而梯度指向的是函数增长最快的方向,恰好和我们想要的相反。所以要减去梯度,沿着梯度的反方向走,才是让损失值下降最快的方向。
参数更新公式:
设损失函数为 L ( w ) L(\mathbf{w}) L(w),其中 w \mathbf{w} w 是待优化的参数向量。梯度下降的迭代公式为:
w new = w old − η ⋅ ∇ L ( w old ) \mathbf{w}_{\text{new}} = \mathbf{w}_{\text{old}} - \eta \cdot \nabla L(\mathbf{w}_{\text{old}}) wnew=wold−η⋅∇L(wold)
- w old \mathbf{w}_{\text{old}} wold:当前参数值
- w new \mathbf{w}_{\text{new}} wnew:更新后的参数值
- ∇ L ( w old ) \nabla L(\mathbf{w}_{\text{old}}) ∇L(wold):损失函数在 w old \mathbf{w}_{\text{old}} wold 处的梯度
- η \eta η:学习率 (Learning Rate),一个正标量,控制每次更新的步长
拆成标量形式,假设参数 w 0 , w 1 , … , w n w_0, w_1, \dots, w_n w0,w1,…,wn,则对第 j j j 个参数: w j : = w j − η ⋅ ∂ L ∂ w j w_j := w_j - \eta \cdot \frac{\partial L}{\partial w_j} wj:=wj−η⋅∂wj∂L

数值示例
L ( w ) = w 2 L(w) = w^2 L(w)=w2
这个函数的全局最小值在 w = 0 w=0 w=0 处。其梯度(导数)为:
d L d w = 2 w \frac{dL}{dw} = 2w dwdL=2w设初始值 w = 5 w=5 w=5,学习率 η = 0.3 \eta = 0.3 η=0.3,我们来手动模拟前几步:
第 1 步:
- 当前 w = 5 w=5 w=5,梯度 = 2 × 5 = 10 = 2 \times 5 = 10 =2×5=10
- 更新: w new = 5 − 0.3 × 10 = 5 − 3 = 2 w_{\text{new}} = 5 - 0.3 \times 10 = 5 - 3 = 2 wnew=5−0.3×10=5−3=2
第 2 步:
- 当前 w = 2 w=2 w=2,梯度 = 2 × 2 = 4 = 2 \times 2 = 4 =2×2=4
- 更新: w new = 2 − 0.3 × 4 = 2 − 1.2 = 0.8 w_{\text{new}} = 2 - 0.3 \times 4 = 2 - 1.2 = 0.8 wnew=2−0.3×4=2−1.2=0.8
第 3 步:
- 当前 w = 0.8 w=0.8 w=0.8,梯度 = 2 × 0.8 = 1.6 = 2 \times 0.8 = 1.6 =2×0.8=1.6
- 更新: w new = 0.8 − 0.3 × 1.6 = 0.8 − 0.48 = 0.32 w_{\text{new}} = 0.8 - 0.3 \times 1.6 = 0.8 - 0.48 = 0.32 wnew=0.8−0.3×1.6=0.8−0.48=0.32
第 4 步:
- 当前 w = 0.32 w=0.32 w=0.32,梯度 = 2 × 0.32 = 0.64 = 2 \times 0.32 = 0.64 =2×0.32=0.64
- 更新: w new = 0.32 − 0.3 × 0.64 = 0.32 − 0.192 = 0.128 w_{\text{new}} = 0.32 - 0.3 \times 0.64 = 0.32 - 0.192 = 0.128 wnew=0.32−0.3×0.64=0.32−0.192=0.128
可以看到, w w w 的值从 5 迅速衰减,每一步都更接近 0,而且越靠近 0 梯度越小,步长自然也越来越小,不会跨过最低点。
如果我们将学习率改为 η = 1.2 \eta=1.2 η=1.2,则在 w = 5 w=5 w=5 时:
- 梯度 = 10 = 10 =10,更新 w = 5 − 1.2 × 10 = 5 − 12 = − 7 w = 5 - 1.2 \times 10 = 5 - 12 = -7 w=5−1.2×10=5−12=−7
- 下一步: w = − 7 w=-7 w=−7,梯度 = 2 × ( − 7 ) = − 14 = 2 \times (-7) = -14 =2×(−7)=−14,更新 w = − 7 − 1.2 × ( − 14 ) = − 7 + 16.8 = 9.8 w = -7 - 1.2 \times (-14) = -7 + 16.8 = 9.8 w=−7−1.2×(−14)=−7+16.8=9.8
- 再下一步又跳回负值,开始大幅震荡,永远收敛不到 0。
这就是学习率对收敛行为的决定性影响:太小收敛慢,太大震荡甚至发散。

4.2.3 梯度下降的变体
根据每次计算梯度时用多少样本参与,分为三种:
| 变体 | 每次梯度计算用多少样本 | 更新公式 | 特点 |
|---|---|---|---|
| 批量梯度下降(BGD) | 全部 m m m 条样本 | w j : = w j − η ⋅ 1 m ∑ i = 1 m ( y ^ ( i ) − y ( i ) ) x j ( i ) \displaystyle w_j := w_j - \eta \cdot \frac{1}{m}\sum_{i=1}^{m} (\hat{y}^{(i)} - y^{(i)}) x_j^{(i)} wj:=wj−η⋅m1i=1∑m(y^(i)−y(i))xj(i) | 稳定,但每次更新需要遍历全部数据,计算量大,不适合大数据集 |
| 随机梯度下降(SGD) | 随机 1 条样本 | w j : = w j − η ⋅ ( y ^ ( i ) − y ( i ) ) x j ( i ) w_j := w_j - \eta \cdot (\hat{y}^{(i)} - y^{(i)}) x_j^{(i)} wj:=wj−η⋅(y^(i)−y(i))xj(i) | 更新快,有噪声,可能震荡,但能跳出局部最优 |
| 小批量梯度下降(MBGD) | 随机 k k k 条样本( 1 < k < m 1<k<m 1<k<m) | w j : = w j − η ⋅ 1 k ∑ i ∈ batch ( y ^ ( i ) − y ( i ) ) x j ( i ) \displaystyle w_j := w_j - \eta \cdot \frac{1}{k}\sum_{i\in \text{batch}} (\hat{y}^{(i)} - y^{(i)}) x_j^{(i)} wj:=wj−η⋅k1i∈batch∑(y^(i)−y(i))xj(i) | 平衡了 BGD 的稳定性和 SGD 的速度,最常用 |
4.3 正规方程 vs 梯度下降
| 对比维度 | 正规方程 | 梯度下降 |
|---|---|---|
| 是否需要选学习率 | 不需要 | 需要 |
| 是否需要迭代 | 不需要,一步求解 | 需要多次迭代 |
| 特征维度高时 | 慢(矩阵求逆 O ( n 3 ) O(n^3) O(n3)) | 仍然可用 |
| X T X X^TX XTX 不可逆时 | 无法使用 | 不受影响 |
| 适用场景 | 小规模数据,特征维度低 | 大规模数据,特征维度高 |

5. 正则化
注意不能一味追求极小的损失值,否则容易过拟合。
回顾:
- 欠拟合
- 表现:训练集和测试集上表现都不好。
- 本质:模型学到特征规律太少,模型太简单,表达能力不足。
- 解决方向:增加特征维度、引入多项式特征、换更复杂的模型。
- 过拟合
- 表现:训练集上表现很好,测试集上表现差。
- 本质:模型学到了过多训练数据中的具体规律(包括噪声和偶然性),这些规律不属于我们想要学习的目标范围,模型太过复杂。
- 解决方向:
- 数据清洗:通过预处理清除噪声特征
- 增加数据集:让模型看到更多样的样本,学到真正的普遍规律
- 正则化:约束模型复杂度=
为什么欠拟合不能靠增加数据解决,过拟合却可以?
欠拟合的本质是模型本身太弱,就像用一个一次函数去拟合抛物线形状的数据,给你再多数据点,一次函数还是只能画一条直线。
过拟合的本质是模型太强但见识太少,它把训练集里那几个样本的死记硬背下来了,没有学到真正的规律。增加数据可以让模型看到更多变化,逼它从"背答案"变成"找规律"。
正则化的通俗理解:在损失函数后面加上一个关于权重 w 的惩罚项,制约模型不要过度依赖某些特征。
5.1 核心思路
原来的损失函数只关心"预测准不准":
L o s s = M S E ( 预测值 , 真实值 ) Loss = MSE(预测值, 真实值) Loss=MSE(预测值,真实值)
加上正则化后:
L o s s = M S E ( 预测值 , 真实值 ) + α ⋅ 惩罚项 ( w ) Loss = MSE(预测值, 真实值) + α · 惩罚项(w) Loss=MSE(预测值,真实值)+α⋅惩罚项(w)
在损失函数末尾加一个与权重大小有关的惩罚项,优化时模型必须同时让原损失和惩罚项都变小,从而压抑不重要的权重。其中 α 是惩罚系数。α 越大,惩罚越重,模型就越不敢让 w 太大,对 w 的限制越强。
为什么要限制 w 的大小?如果一个特征的权重 w 很大,说明模型对这个特征非常"依赖",这个特征的微小变化都会引起预测结果剧烈波动。过拟合往往表现为某些 w 值异常大,模型为了拟合训练集中的个别样本而把某些特征的权重拉得很大。正则化就是给这种行为进行惩罚:你想让 w 变大来降低 MSE?可以,但要付出 α·惩罚项(w) 的代价。
5.2 L1 正则化(Lasso) vs L2 正则化(Ridge)
-
L1 正则化(Lasso):
惩罚项 = Σ ∣ w i ∣ 惩罚项 = Σ|wᵢ| 惩罚项=Σ∣wi∣
线性惩罚:权重是 100,就惩罚 100;权重是 1,就惩罚 1。大权重和小权重受到的惩罚是等比例的。 -
L2 正则化(Ridge):
惩罚项 = Σ ( w i 2 ) 惩罚项 = Σ(wᵢ²) 惩罚项=Σ(wi2)
平方惩罚:权重是 100,惩罚 10000;权重是 1,惩罚 1。大权重受到指数级加重的惩罚,对小权重则几乎没有惩罚。 -
L1 vs L2 对比:
| 维度 | L1(Lasso) | L2(Ridge) |
|---|---|---|
| 惩罚项 | Σ|wᵢ| | Σ(wᵢ²) |
| 惩罚方式 | 线性惩罚 | 平方惩罚 |
| 对大权重的态度 | 按比例约束 | 指数级打压 |
| 能否使 w 精确为 0 | 可以,产生稀疏解 | 不能,只能趋近于 0 |
| 特征选择 | 自动筛掉不重要的特征 | 保留所有特征但削弱 |
5.3 几何视角解释正则化:拉格朗日乘子与约束优化
前面讲的是“往损失函数里加一个惩罚项”的视角,数学上还有另一种完全等价的表述,用的是拉格朗日乘子法。
拉格朗日乘子法回顾:对于一个带约束的优化问题,在约束条件 g(w) = C 下求 f(w) 的最小值,解法是构造拉格朗日函数,令目标函数的梯度和约束函数的梯度平行。
几何含义是:想象约束条件 g(w) = C 在参数空间中画了一个圈,你只能在这个圈上行动。f(w) 的梯度指向 f 值增长最快的方向。你在圈上找一个点,如果圈在该点的切线方向和 f 的梯度方向不垂直,那你沿着圈往某个方向走,f 还会变小,说明当前点不是约束下的最小值。只有当 f 的梯度和圈的梯度方向平行(在同一条直线上),你才无处可去,圈上的任何微小移动都不会再让 f 变小。这个点就是约束下最优解,也就是切点。
正则化等价于给参数 w 画了一个范围圈,规定 w 只能在这个圈里面待着,然后在圈内(或圈上)找让损失最小的点。
- L2 的圈是一个圆:w₁² + w₂² ≤ C
- L1 的圈是一个菱形:|w₁| + |w₂| ≤ C
惩罚系数 α 和圈的大小 C 是一一对应的:α 越大,相当于圈越小(约束越紧);α = 0 相当于圈无限大(没有约束)。
分两种情形来看:
-
圈很大,损失函数的谷底就在圈里面:那你直接走到谷底就行,约束根本没起作用。对应 α 很小、模型几乎不受限制的情况。
-
圈很小,谷底在圈外面:你想去谷底但不准出去,只能走到圈的边界上,找一个“圈上最低的点”站着。这就是正则化起作用的情形:不要求损失绝对最小,而是要求在一个受约束的 w 范围内找最小。
那么为什么L1 为什么能产生稀疏解(w=0)?
把 L2(圆)和 L1(菱形)的约束圈和损失函数的等高线画在一张图上。
对于 L2(圆),边界是光滑的,没有尖角。在圆上,每个点都有唯一确定的切线方向,损失函数的等高线想切上来,必须正好对上那个特定方向,概率上比较"严格"。这就是 L2 只会把 w 往 0 方向压缩、但不会精确置零的几何原因。
对于 L1(菱形),边界有四个尖角,恰好落在坐标轴上。而在菱形的角上,这个点不存在唯一的切线,因为棱角处可以引出无数条支撑线而不穿入内部。数学上称其为次梯度,所有合法斜率的集合形成一个扇形。损失函数等高线在扩张过程中,有更高的概率先撞上菱形的角而不是边。而角上的点,至少有一个 w 分量恰好等于 0。
这就是 L1 正则化能够自动实现特征选择的几何本质:菱形的尖角使得许多权重被精确驱赶到零。
6. API 详解
前面我们详细拆解了线性回归中最重要的三个“可调组件”:
- 损失函数:MSE / SSE 等
- 优化算法:正规方程 / 梯度下降(还可细分批量、随机、小批量)
- 正则化:无 / L1 / L2 等
不同的 sklearn 模型,其实就是对这三个组件做出了固定的或可配置的选择。
6.1 模块概览
线性回归相关的类都在 sklearn.linear_model 模块中:
| 模型 | 损失函数(默认) | 优化算法 | 正则化 | 关键参数 |
|---|---|---|---|---|
LinearRegression |
MSE(最小二乘) | 正规方程(SVD分解) | 无 | 无 |
Ridge |
MSE + L2 惩罚项 | 正规方程 / 随机平均梯度等 | L2,固定 | alpha(λ) solver |
Lasso |
MSE + L1 惩罚项 | 坐标下降 | L1,固定 | alpha,max_iter |
ElasticNet |
MSE + L1+L2 混合 | 坐标下降 | L1+L2,可调混合比 | alpha,l1_ratio |
SGDRegressor |
可自定义(默认MSE) | 随机梯度下降 | 可自定义(默认L2) | loss,penalty,alpha,learning_rate |
6.2 LinearRegression :普通最小二乘
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
- 损失函数:均方误差(MSE),无法更改。
- 优化算法:内部使用奇异值分解(SVD)来求解最小二乘,等价于正规方程的稳定版。
- 正则化:无。所以当特征多、样本少或存在共线性时,容易过拟合。
- 优点:完全无超参数,无需调参,训练快(小数据)。
- 适用场景:数据量不大、特征之间相关性弱、且确认不需正则化的简单任务。
理解 SVD
把特征矩阵 X X X 分解为三个矩阵的乘积:
X = U Σ V T X = U \Sigma V^T X=UΣVT
其中 Σ \Sigma Σ 是一个对角矩阵,对角线上的值叫奇异值。通过对奇异值“取倒数”的巧妙操作,可以直接得到最小二乘解:
w = V Σ + U T y w = V \Sigma^+ U^T y w=VΣ+UTy
这里 Σ + \Sigma^+ Σ+ 是 Σ \Sigma Σ 的伪逆(对非零奇异值取倒数,零奇异值对应位置保持为 0)。打个比方:
- 正规方程相当于先给 X X X 来一次“平方”(计算 X T X X^TX XTX),原本只是稍微不可靠的方向,平方后会被放大成灾难;
- SVD 则直接检查 X X X 本身在各个方向上的“可靠程度”(奇异值),遇到为零或极小的奇异值,就把对应方向在解中的贡献直接置零,相当于自动绕过那些“捣乱”的方向。
方式 稳定性 对不可逆的处理 直接求 ( X T X ) − 1 (X^TX)^{-1} (XTX)−1 差,病态矩阵误差大 直接报错或解不可靠 SVD 求解 优秀,数值稳定 自动产生最小范数解,忽略零奇异方向 核心结论:SVD 不是一种新的优化算法,而是求解正规方程的数值稳定实现。本质还是在找解析解,只是走了一条更聪明的数学路径。你调用
LinearRegression()时,背后自动执行的就是这套稳定的 SVD 解法。
6.3 带正则化的解析类模型:Ridge, Lasso, ElasticNet
这三者都在损失函数后加了惩罚项,通过解析或坐标下降等高效算法求解。
6.3.1 Ridge(岭回归):L2 正则化
from sklearn.linear_model import Ridge
ridge = Ridge(alpha=1.0) # alpha 即 λ,越大惩罚越强
ridge.fit(X_train, y_train)
- 固定配置:损失 = MSE + L2 惩罚,默认求解器会自动选择(正规方程或随机平均梯度等)。
- 优化算法:由
solver参数决定。可选值包括:'auto':根据数据自动选择(默认)。'svd':奇异值分解,稳定但计算稍重。'cholesky':利用X^T X的 Cholesky 分解,速度最快,适合样本多、特征不太多的场景。'sag':随机平均梯度下降,属于梯度下降的变体,适合大数据量。- …
不同solver对正则化项的计算方式略有不同,但目标一致。
- 关键参数:
alpha:正则化强度,默认 1.0。调大 → 权重更趋于零,模型更简单。
- 适用场景:特征间存在共线性、需要整体抑制模型复杂度但不要求特征选择。
6.3.2 Lasso: L1 正则化
from sklearn.linear_model import Lasso
lasso = Lasso(alpha=0.1, max_iter=10000)
lasso.fit(X_train, y_train)
- 固定配置:损失 = MSE + L1 惩罚,优化算法为坐标下降。
- 关键参数:
alpha:惩罚力度,越大越容易让某些权重变为 0。max_iter:迭代次数,Lasso 的求解比 Ridge 慢,数据量大时可能需要调大。
- 适用场景:希望自动筛选重要特征,构建更简洁、可解释性强的模型。
理解坐标下降
梯度下降是沿着整个参数向量的梯度方向一起更新,而坐标下降是每次只更新一个坐标方向上的参数,固定其他参数不动,找到当前方向上的最小损失点,然后换下一个坐标。循环往复,直到总体收敛。因为 L1 惩罚项不可导(绝对值的次梯度问题),直接用梯度下降不好处理,而坐标下降在单变量优化时可以轻松处理带绝对值的子问题,所以 Lasso 和 ElasticNet 默认用它。
6.3.3 ElasticNet(弹性网络):L1 + L2 混合
from sklearn.linear_model import ElasticNet
en = ElasticNet(alpha=0.1, l1_ratio=0.5, max_iter=10000)
en.fit(X_train, y_train)
- 固定配置:损失 = MSE +
l1_ratio * L1 + (1 - l1_ratio) * L2,优化算法为坐标下降。 - 关键参数:
alpha:总惩罚力度。l1_ratio:L1 惩罚的占比。0 时完全等同 Ridge,1 时等同 Lasso,中间值则两者兼具。
- 适用场景:特征极多、高度相关时,纯 Lasso 可能随机选一个特征而忽略其他相关特征(不稳定);弹性网络通过加入 L2 部分使相关特征被一起保留或一起舍弃,稳定性更好。
6.4 SGDRegressor :梯度下降
这是前面梯度下降理论的直接对应,也是可配置性最高的线性回归类。
from sklearn.linear_model import SGDRegressor
model = SGDRegressor(
loss='squared_error', # 损失函数
penalty='l2', # 正则化类型
alpha=0.0001, # 正则化强度
learning_rate='invscaling',# 学习率策略
eta0=0.01, # 初始学习率
max_iter=1000, # 最大迭代次数
tol=1e-3, # 收敛容忍度
)
model.fit(X_train, y_train)
关键参数:
-
loss(默认'squared_error'):损失函数。可选:'squared_error':MSE,标准线性回归用'huber':Huber 损失,对异常值更鲁棒'epsilon_insensitive':epsilon 不敏感损失(类似 SVM 回归)
-
penalty(默认'l2'):正则化类型。可选:'l2':L2 正则化'l1':L1 正则化'elasticnet':L1 + L2 的混合None:不使用正则化
-
alpha(默认0.0001):正则化强度 -
learning_rate(默认'invscaling'):学习率策略。可选:'constant':恒定学习率,η = eta0'optimal':按公式 η = 1/(α·(t+t₀)) 衰减'invscaling':eta = eta0 / pow(t, power_t),逐步缩小步长。'adaptive':自适应,损失不降时自动减小学习率
-
eta0(默认0.01):初始学习率 -
max_iter(默认1000):遍历数据的最大次数(epoch 数) -
tol(默认1e-3):收敛容忍度,损失下降小于此值则提前停止
6.5 注意前置处理:缩放与多项式特征
-
特征缩放:
梯度下降对特征的尺度非常敏感。如果不同特征的数值范围差异很大(比如一个特征在 0~1,另一个在 0~10000),梯度在不同方向上的分量大小会严重失衡,导致优化路径来回震荡、收敛极慢。无论你选用哪个模型,只要涉及梯度下降或坐标下降,就一定要做特征缩放。正规方程类的模型虽不强制,但统一缩放能让系数具有可比性。 -
PolynomialFeatures:多项式特征
from sklearn.preprocessing import PolynomialFeatures poly = PolynomialFeatures(degree=2, include_bias=False) X_poly = poly.fit_transform(X) # 生成 x1, x2, x1², x1x2, x2² 等- degree:最高次项的次数,为 2 时生成所有一次和二次组合。
- include_bias:是否包含偏置列(全 1),线性模型通常自带偏置,可设为 False。
应用场景:多项式特征的核心应用场景正是之前我们提到的欠拟合解决方法。当线性模型在训练集和测试集上都表现不佳,且怀疑原因是特征与目标之间存在明显的非线性关系时,就可以通过 PolynomialFeatures 构造平方项、交叉项等来增强模型的表达能力,使其在原始特征空间中能够拟合曲线或曲面。这本质上是在做特征工程,用更高维的映射赋予线性模型非线性威力。
同时它也不仅限于欠拟合,即使模型复杂度足够,有时加入多项式特征还能进一步挖掘隐藏的非线性规律,但此时要注意配合正则化防止过拟合。
以上为个人学习总结,旨在梳理个人理解。如有疏漏或不当之处,欢迎指正与交流。如果文章对你有帮助,别忘了点个赞、留个言,让更多的小伙伴看到~ 我们下篇再见!
更多推荐




所有评论(0)