机器学习_第五篇_逻辑回归

今天咱们聊一个最基础、也最常用,但名字最容易让人误解的算法——逻辑回归(Logistic Regression)。它叫"回归",干的却是"分类"的活,怪哉,怪哉。
一、逻辑回归是什么?
先说人话:逻辑回归是一个用来做"分类"的算法。
最常见的就是二分类,什么是二分类?就是结果只有两种:是 / 否、垃圾邮件 / 正常邮件、患病 / 没患病、点头 / 摇头。逻辑回归最擅长回答的就是这类"是不是"的问题。
它和线性回归最大的区别在最后一脚:
- 线性回归解决的是多少的问题,它吐出来的是一个任意实数,比如 3.5、−12、100,你拿它当"预测房价"挺合适。
- 逻辑回归解决归属哪一类的问题,它吐出来的是一个概率,永远落在 0 到 1 之间,比如 0.87,意思是"我有 87% 的把握,这封邮件是垃圾邮件"。
所以你可以把逻辑回归理解成:先像线性回归那样算个数,再套一个"压缩器"把这个任意数压成 0~1 的概率,最后按概率下判断。
一句话总结它是什么:一个把特征加权求和、再压缩成概率、用来做二分类的模型。
二、为什么需要逻辑回归?
要回答"为什么",最好的办法是反过来问:线性回归干不了这活吗?
还真干不了,问题出在三个地方:
1. 线性回归的输出没有上界和下界。
我们拿"是不是垃圾邮件"举例。线性回归可能给你算出一个 −3,或者 +5。−3 算啥?比 0 还低的"负概率"?概率明明不能小于 0。+5 又算啥?超过 100% 的概率?也不合理。我们真正想要的是一个清清爽爽、卡在 [0, 1] 区间里的概率,线性回归给不出来。
2. 在"分类"这个任务上,线性回归对异常值太敏感。
比如绝大多数样本都在正常区间,突然混进来一个极端样本,线性回归的"直线"会被它拽偏一大截,导致整条边界都歪了。
3. 我们需要的是一个"做决定的依据",而不只是一个趋势值。
分类说到底是要拍板的:到底归到这一类,还是那一类?逻辑回归直接给你一个"把握有多大"的概率,你拿着这个概率,就能很自然地设一条"超过多少就判为是"的线。
所以逻辑回归存在的理由很朴素:我们需要一个能把任意打分压进 [0,1]、并且能直接当概率用的模型。 它就是为这个缺口而生。
三、它是怎么做的?(四步走)
下面这张流程图,把逻辑回归从"拿到数据"到"给出判断"的全过程拆开。
原始特征 x₁, x₂, ..., xₙ
│
▼
第一步:线性打分 z = w₁x₁ + w₂x₂ + ... + wₙxₙ + b
│
▼
第二步:压缩成概率 p = σ(z) = 1 / (1 + e^(−z))
│
▼
第三步:按阈值拍板 p ≥ 0.5 → 判为"1类";否则 → "0类"
│
▼
第四步(训练时):用损失函数 + 梯度下降,把 w、b 调好
▍先交代一个前提:数据标注在流水线的哪?
你大概会问:这条四步走,吃的是啥"原材料"?答案是已经标好类的样本——每个样本不光有特征 x,还得带一个标签 y(比如"是 / 否垃圾邮件"对应的 0 或 1)。
这个标签 y 从哪来?就是数据标注:人工或者规则,给每个样本打上"正确答案"。所以——
- 它不在"四步走"里面,而是更上游的数据准备阶段。逻辑回归属于"监督学习","监督"二字指的就是这些现成的标准答案;没有标注,就谈不上"监督"这回事。
- 它和每一步的关系:第四步(训练)必须用到 y——上文那句"用一堆已知答案的样本"里的"已知答案"就是它,损失函数里减来减去的那个 y 也是它;而第一到第三步是用训好的模型做预测,只需要 x,用不上 y。
一句话:数据标注不在流水线上,在流水线开工之前;它是"原材料",不是"工序"。 咱们下面专心看模型拿到这批 (x, y) 之后怎么干活。
第一步:算一个"线性打分" z
把每个特征 x₁、x₂… 乘上对应的权重 w₁、w₂…,再加个偏置 b,得到一个总分。这个过程和线性回归一模一样:
权重 w 可以理解成"这个特征有多重要",偏置 b 可以理解成"默认倾向"。
第二步:把打分丢进 Sigmoid,压成概率
这就是逻辑回归的招牌动作,用来描述"这个样本属于哪一类的概率"。Sigmoid 函数长这样:
无论 z 是 −100 还是 +100,套完这个函数,出来的 p 一定乖乖待在 0 到 1 之间。z = 0 时,p 正好是 0.5。
第三步:按阈值做决定
拿到概率 p 之后,最常用的规则是:p ≥ 0.5 判为"1 类"(比如"是垃圾邮件"),p < 0.5 判为"0 类"。这个 0.5 叫决策阈值,实际业务里可以根据需要调(比如宁可错杀也不放过垃圾邮件,就把阈值调低一点)。
第四步:训练时,把参数调好
前三步是"用模型做预测"。但模型一开始的 w、b 是瞎设的,预测肯定不准。训练阶段要干的事,就是用一堆已知答案的样本,把 w、b 慢慢调到一个"预测最准"的状态。怎么调?后面原理部分细说,先记住两个关键词:损失函数负责"算错得有多离谱",梯度下降负责"朝更准的方向挪"。
▍顺带一笔:它和线性回归到底有多像,又差在哪?
聊到这儿,你大概已经隐约觉得:逻辑回归这"四步走",怎么跟之前听过的线性回归一个路数?没错,它俩在做法上简直是一个模子刻出来的,区别其实就卡在第二脚那一哆嗦。咱们拆开看。
像在哪(做法上几乎复刻)
- 第一步完全一样:都是先算一个线性打分 \(z = \mathbf{w}^T\mathbf{x} + b\)。线性回归靠这步直接出结果,逻辑回归也靠这步打底——所以逻辑回归才叫"回归",根儿上它就是线性回归加了个尾巴。
- 第四步的优化套路一样:都是"先定个损失函数衡量错多远,再用梯度下降把参数往更准的方向挪"。训练的逻辑一模一样,都是调 w 和 b。
- 梯度长得几乎一个样:逻辑回归对 \(w_j\) 的偏导是 \(\frac{1}{m}\sum(p - y)x_j\),线性回归是 \(\frac{1}{m}\sum(\hat{y} - y)x_j\)。你看,骨架分毫不差,差别只在于括号里塞的是谁——逻辑回归是"概率 p 减标签 y",线性回归是"预测值 ŷ 减标签 y"。这点咱们在第六章还会再点一次。
差在哪(关键就这么几处)
| 比什么 | 线性回归 | 逻辑回归 |
|---|---|---|
| 干啥活 | 预测连续值(回归) | 预测类别概率(分类) |
| 最终输出 | 任意实数(如 3.5、−12) | 卡在 0~1 的概率 \(p=\sigma(z)\) |
| 多出来的动作 | 无 | Sigmoid 压缩 + 阈值拍板 |
| 损失函数 | 平方误差 MSE(天然凸) | 交叉熵(MSE 会套娃成非凸) |
| 要不要"判类" | 不需要(输出本身就是答案) | 需要(p ≥ 阈值才归为某类) |
说到底,最关键的一脚区别就在第二步那层 Sigmoid:
- 线性回归止步于 \(z\),把 \(z\) 直接当预测值甩出去;
- 逻辑回归在 \(z\) 上又套了一层 Sigmoid,把任意实数逼进 [0,1],变成"概率"。
而正是因为这层"套娃",后面两件事被连锁改掉了:输出变成了概率,所以多了"按阈值拍板"这一步;损失函数也不能再用平方误差(套完 Sigmoid 会非凸、容易卡局部最优,详见第五章),得换成交叉熵。但奇妙的是,换完损失之后,梯度公式反而和线性回归长得几乎一样——这层血缘关系,正是广义线性模型(GLM)把它们俩绑在一起的原因。
一句话收住:逻辑回归 = 线性回归的线性打分 + 一层 Sigmoid 压缩 + 一次阈值判决。 像,是因为根都一样;不像,是因为最后那一哆嗦改变了整个任务的味道。
▍顺着损失函数这茬,把平方误差和交叉熵讲透
上面那张对比表里,"损失函数"一行写了:线性回归用平方误差,逻辑回归用交叉熵。这俩名字你大概率听过,但到底在量什么、差在哪,咱们掰开说;至于"为什么逻辑回归偏偏选交叉熵、MSE 套上 Sigmoid 会翻车",深层的理由留到第五章再拆。
平方误差(MSE,均方误差)是什么?
它衡量的是"预测值和真实值,数值上差了多远"。做法最直白:把(预测值 − 真实值)平方一下(平方是为了让正负误差都算数,而且把大错、小错拉开差距),再对一批样本取平均。
- 直觉:你预测 0.8、真实是 1,差 0.2,平方后是 0.04;差得越多,平方后的惩罚越狠,像一条开口向上的抛物线。
- 它是回归任务里的"老黄牛",线性回归就靠它。因为回归预测的是连续数值,直接比"两个数差多少"最自然。
交叉熵(cross-entropy)是什么?
这名字听着唬人,其实度量的是"你给的概率分布,和真实答案贴不贴"。借用个直觉:模型给"正确答案"的概率越高,交叉熵越低;给低了,惩罚是 \(-\log(p)\) 这种"越接近 0 越爆炸"的形状(比如真实是 1、你却只给了 0.01 的概率,惩罚会非常大)。
- 它天生是为"概率 vs 类别标签"这种活设计的——你不是在比两个数的大小,而是在比"你猜的概率像不像真的"。
它俩的关键区别
| 比什么 | 平方误差 MSE | 交叉熵 |
|---|---|---|
| 度量的是什么 | 预测值 − 真实值的数值差 | 预测概率与真实的贴合度 |
| 典型用在 | 回归(预测连续值) | 分类(预测概率 / 类别) |
| 对"离谱预测"的惩罚 | 平方级增长 | 对数爆炸(越错罚得越狠) |
| 配合 Sigmoid 后 | 损失面非凸,易卡局部最优 | 损失面凸,梯度下降走得稳 |
| 对输出的要求 | 无(只要是实数就行) | 强制你去拟合 0~1 的概率 |
简单总结:平方误差是在比"数差多少",交叉熵是在比"概率像不像"。 逻辑回归选交叉熵,不是因为它多高级,而是它的语义正好对得上"预测概率 + 分类"这活,而且能让训练稳当。至于为什么 MSE 套上 Sigmoid 会翻车(非凸、容易卡在局部最优),咱们第五章再拆。
四、原理深挖:Sigmoid 函数
是什么?
Sigmoid 是一个形状像 S 的曲线函数,公式就是上面那个 \(\sigma(z) = 1 / (1 + e^{-z})\)。它把整条实数轴 \((-\infty, +\infty)\) 平滑地映射到 \((0, 1)\) 区间。
为什么是它(而不是别的压缩函数)?
因为它的数学性质太"懂事"了:
- 当 z 很大(正无穷),e^(−z) 趋近 0,σ(z) 趋近 1;
- 当 z 很小(负无穷),e^(−z) 爆炸大,σ(z) 趋近 0;
- 当 z = 0,σ(z) 正好等于 0.5,是个天然的"中立点"。
而且它处处可导,导数还有个漂亮的自带公式:\(\sigma'(z) = \sigma(z)(1 - \sigma(z))\)。这一点在后面算梯度时省了我们大麻烦——不用每次都重新推一遍微积分。
进一步:Sigmoid 不是唯一选择
理论上任何能把实数压到 (0,1) 的单调函数都行,比如 tanh 压到 (−1,1)。但在二分类 + 概率语义这个场景下,Sigmoid 最对味,因为它输出的就是"正类的概率"。它也不是没缺点:当 z 特别大或特别小时,梯度几乎为 0("饱和"),训练后期容易"学不动",这也是后来 ReLU 等激活函数在深度网络里更受宠的原因之一。
五、损失函数
▍先打地基:伯努利分布——标签背后的统计模型
看公式之前,先补一块地基,不然"为什么损失长那样"会显得像拍脑袋。
伯努利分布是什么?
它描述的就是"一次试验、两种结果"这种最朴素的随机现象:抛一次硬币,正面(记为 1)概率是 p,反面(记为 0)概率就是 \(1-p\)。数学上写清楚就是:
合起来一个紧凑写法:\(P(X = x) = p^x(1-p)^{1-x}\),其中 \(x\) 取 0 或 1。它的期望(均值)正好是 p,方差是 \(p(1-p)\)。
它和逻辑回归有什么关系?
二分类的标签 y(是/否、1/0)本质上就是一个伯努利随机变量:真实的"它属于正类"这件事,发生的概率是某个 p。逻辑回归干的事,就是用 Sigmoid 去建模这个 p——把第四节那个输出 p,解释成"在给定特征 \(\mathbf{x}\) 的条件下,y=1 的概率":
也就是说,Sigmoid 吐出来的那个概率,在统计意义上就是伯努利分布的参数 p。
那参数 w、b 到底怎么定?——这就引出了最大似然估计(MLE)
既然我们认定标签服从伯努利分布、又用 Sigmoid 去拟合它的参数 p,接下来最自然的问题就是:这组 w、b 到底怎么求?统计学里最讲道理的求参办法,就是最大似然估计(Maximum Likelihood Estimation,简称 MLE)。它也是一种"求参数"的思路,但和前面"最小化误差"的视角不太一样。
MLE 是什么?
假设你手里有一堆已经发生的观测数据(比如 100 张图,92 张标了"猫"、8 张标了"狗"),模型里还有几个待定的参数(逻辑回归里就是 w、b)。MLE 干的事很直白:挑出一组参数,让"已经发生的事实"看起来最顺理成章——也就是让这组参数下,观测到这批数据的概率最大。
"似然(likelihood)"这个词,本质上就是"在给定参数 θ 时,观测到当前这批数据的联合概率"。我们挑那个把这个概率撑到最大的 θ,就是 MLE 给的答案。
为什么是"最大化"而不是"最小化"?
直觉是这样的:你手里的标签是板上钉钉发生过的现实。那最合理的参数,自然该是"让这件已发生的事看起来最不稀奇"的那组——换个说法,就是给"眼前这批真实数据"赋予最高概率的那组参数。训练时把"似然"最大化,等价于在找"最配得上这些真实标签"的模型。
原理往深走一步:为什么实际算的时候都要取个对数?
原始的似然是一堆概率的乘积(每条样本一个概率,互相独立就乘起来)。乘积有两个麻烦:数值上特别容易下溢成 0(一堆小于 1 的数连乘),求导也麻烦。于是大家默契地加一层对数(log):
- 对数把乘法变成加法:\(\log(\prod_i p_i) = \sum_i \log p_i\),好算也好求导;
- 对数函数是单调递增的,所以"最大化似然"和"最大化对数似然"挑出来的参数是同一组,不丢信息。
这就是"对数似然(log-likelihood)"的由来,后面交叉熵里那个 \(\log\) 就是它。
把 MLE 套到咱们的伯努利标签上:损失函数就是"负对数似然"
有了 MLE 这个工具,回头看咱们的逻辑回归就顺了——伯努利的参数 p 被 Sigmoid 建模成了 \(\sigma(\mathbf{w}^T\mathbf{x}+b)\),那"让真实标签出现的概率最大"翻译成人话,就是找一组 w、b,使得这批样本的真实标签最可能出现。具体长这样:假设样本互相独立,整批同时出现的概率(也就是 MLE 要最大化的似然)是每个样本概率的乘积:
我们训练时想让这个似然最大。乘积取对数、再加个负号变成"要最小化"的目标,就得到:
把它除以 m 取个平均,是不是眼熟?这正是本节要讲的交叉熵损失。 所以交叉熵不是凭空冒出来的,它就是"假设标签服从伯努利分布"之后,最大似然估计顺理成章推出来的结果;MLE 也不是另一个孤立的东西,它就是逻辑回归训练目标的"统计老祖宗"。
它解决了什么痛点
有了这块地基,逻辑回归就不再只是"画条边界"的启发式方法,而是一个有概率语义的模型:它输出的 p 是真有统计含义的"属于正类的概率",不是随便一个 0~1 的数;我们用交叉熵来训练,也因为这正是该模型下最讲道理的误差度量。后面那句"等价于极大似然估计",根儿上就扎在这。
是什么?
损失函数用来衡量"模型预测的概率"和"真实标签"差了多远。差得越离谱,损失越大。逻辑回归用的是对数损失 / 交叉熵损失。
单个样本的损失长这样:
其中 y 是真实标签(0 或 1),p 是模型预测的概率。你品一下这个设计:
- 如果真实是 1(y=1),公式后半截消失,损失变成 \(-\log(p)\)。p 越接近 1,损失越接近 0;p 越接近 0,损失爆炸大。模型会因此"害怕"把该判 1 的判成 0。
- 如果真实是 0(y=0),公式前半截消失,损失变成 \(-\log(1-p)\)。p 越接近 0,损失越小。
整批样本的平均损失就是最终要最小化的目标:
为什么不用线性回归里那套"平方误差(MSE)"?
这是个特别容易踩的坑。你当然可以把平方误差搬过来:\(L = (p - y)^2\)。问题出在:p 本身又是 Sigmoid(z),而 z 又是 w、b 的线性组合。三层套娃叠在一起,损失函数关于 w、b 的图像不再是漂亮的下凸碗状,而是坑坑洼洼、到处是局部最低点。
这下麻烦了:梯度下降最怕局部最优,从一个随机起点出发,很容易卡在半山腰的小水坑里出不来,学到的模型也就废了。而交叉熵损失配合 Sigmoid,能保证优化面是"好走的",梯度下降能稳定地走向最低点。
进一步:它其实等价于极大似然估计
如果你学过一点统计,会发现上面这个损失函数不是拍脑袋发明的。它等价于"极大似然估计"——我们在找一个 w、b,让"已经发生的这批真实标签"出现的概率最大。把似然取对数、加个负号,就正是交叉熵损失。所以逻辑回归在统计上是有坚实地基的,不是玄学。
六、原理深挖:梯度下降怎么更新参数
是什么?
梯度下降是一种"笨办法但极其有效"的寻优法:把损失函数看成一个山坡,我们要找最低的那个谷底。梯度(导数)指向的是"最陡的上坡方向",那我们反着梯度走一步,就是在下坡,损失就变小了。
为什么有效?
因为对 w、b 各自的偏导,正好告诉我们"动一点点 w,损失会往哪偏、偏多少"。偏导是正的,说明 w 大了会让损失上升,那就把 w 调小;偏导是负的,说明 w 小了会让损失上升,那就把 w 调大。每一小步都朝着"让损失更小"的方向挪,多走几步就到谷底了。
逻辑回归的好处是,梯度公式出奇地干净。对权重 wⱼ 和偏置 b 的偏导是:
你注意看,最后那个 \((p - y)\) 是不是很眼熟?它就是"预测值减真实值"的误差。更新规则就是:
这里的 \(\alpha\) 叫学习率,控制每步走多大:步子太小,走到天黑都到不了谷底;步子太大,容易一步跨过谷底、在两边来回横跳。它是最需要靠经验调的那个旋钮。
进一步:和线性回归的梯度长一个样?
没错,你会发现逻辑回归的梯度形式和线性回归几乎一致,区别只在于这里的 p 是 Sigmoid 压出来的概率,而线性回归里是直接的线性输出。这种"形式统一"不是巧合,背后是广义线性模型(GLM)的框架在撑腰——这也是为什么逻辑回归和线性回归经常成对出现、一起讲。
七、多分类:Softmax 回归(多分类版逻辑回归)
前面咱们聊的全是二分类——标签只有 0 和 1,"是"或"否"。可现实里更多时候是"一堆类别里选一个":猫 / 狗 / 兔子,或者邮件分"工作 / 广告 / 社交 / 垃圾"。这种"从 K 个类别里挑一个"的任务,叫多分类(multi-class classification)。逻辑回归本质是二分类,但稍微扩一扩就能扛起多分类——这节专门讲这件事。
是什么?
二分类时,模型只学一套权重 \(\mathbf{w}\),算出"是正类的概率" \(p\)。多分类时类别有 K 个,最直白的做法是给每个类别都配一套自己的权重 \(\mathbf{w}_k\)(和偏置 \(b_k\)),于是第 k 类也有一个自己的打分:
注意现在有 K 个 \(z_k\),不是一个。接下来的核心问题就是:怎么把这 K 个打分,变成"属于每个类的概率"?
为什么不直接复用二分类那套?
你当然可以偷懒:训练 K 个互不相干的二分类器(这路数叫"一对多 / OvR",咱们在后面"几个你大概率会追问的问题"那节会细说)。但它的毛病也明显——K 个输出各自独立、加起来不等于 1,你读不出"每个类的全局概率";而且每个分类器都面对"一类 vs 剩下所有类"的极度不平衡。我们需要一个"一次前向、直接吐出 K 类归一概率"的干净接口,Softmax 就是干这个的。
怎么做:Softmax 把 K 个打分压成一份概率分布
Softmax 干的事,和 Sigmoid 一样是"把分数变概率",只是从"1 个分数"升级成"K 个分数一起处理":
你品一下这个公式的设计:
- 分子 \(e^{z_k}\):把第 k 类的打分指数化,谁的分数高,谁被放得越大(指数放大差距);
- 分母 \(\sum_j e^{z_j}\):把所有 K 类的指数化分数加起来,当"总盘子";
- 于是每个 \(p_k\) 都在 (0,1),且所有 K 个 \(p_k\) 加起来正好等于 1——这是一份合法的概率分布,可以直接读成"模型认为样本属于第 k 类的把握"。预测时取概率最大的那个类即可。
原理往深走一步:它和 Sigmoid、交叉熵到底什么关系?
这仨名字老被一起提,但角色不一样,别搞混:
- Sigmoid、Softmax 是"输出层"操作:管"分数 → 概率"这一步。Sigmoid 处理 1 个分数(二分类),Softmax 处理 K 个分数(多分类)。类别只剩 2 个时,Softmax 会退化成 Sigmoid(把其中一个分数当成 0 即可),所以它是 Sigmoid 在多类上的亲兄弟。
- 交叉熵是"损失函数":管"预测和真相差多远"那一步,是另一层面的东西,不跟激活函数抢同一个位置。
- 固定搭档:二分类 → Sigmoid + 二元交叉熵;多分类 → Softmax + 多元交叉熵。交叉熵是站在后面给预测打分的"裁判"。
它解决了什么痛点?
二分类 + Sigmoid 天生只管两类。硬做 K 类,要么去训 K 个互不相干的 Sigmoid(概率不归一、还容易类不平衡),要么就缺一个"一次输出 K 类、且互斥又归一"的接口。Softmax 一口气补上:一个模型、一次前向,直接吐出合法分布;而且公式里那个分母把 K 类"拉到一起竞争"——推高某一类,天然就压低其他类,正好契合"一个样本只能属于一类"的语义。
进一步:损失函数也跟着升级成多分类交叉熵
既然输出是 K 个类的概率分布,标签也得跟上。多分类里真实标签通常用独热编码(one-hot):样本属于第 k 类,就写成一个长度为 K 的向量,第 k 位是 1、其余是 0,记作 \(y_k\)。损失函数升级成多分类交叉熵(categorical cross-entropy):
你对比一下第五节的二分类交叉熵——其实是一回事:因为只有真实类那一位的 \(y_k=1\),其他位乘出来都是 0,求和后塌缩回"只看真实那一类的概率"。所以多分类交叉熵就是二分类交叉熵在 K 类上的自然推广。
进一步:训练时怎么更新参数?
原理和第六章一模一样——还是用梯度下降最小化上面的损失。只是现在每个类别都有自己的 \(\mathbf{w}_k\),梯度也按每个类分别算,形式依然是"误差 × 特征"那套骨架。这再次印证:多分类 Softmax 回归,本质上就是"把逻辑回归复制 K 份、共用一个 Softmax 输出层",骨子里还是咱们前面那套线性打分 + 梯度下降。
好处与坑(速判)
- 好处:输出是干净、归一的概率,类别互斥时(一张图要么是猫要么是狗)最对味;一个模型一次前向搞定。
- 坑:它默认类别互斥。如果一个样本能同时属于多类(多标签,比如一张图"既是猫又是宠物"),Softmax 就用错了——这种场景该回头用"一对多(OvR)"或者专门的多标签模型。
八、模型评估:用混淆矩阵看模型到底行不行
模型训完了、预测也给出了(就是第三节那个"按阈值拍板"吐出的 0 或 1),下一步自然要问:它猜得准不准?光数"对了几个"太粗糙,于是我们搬出一张 2×2 的表,把每一次预测和真实标签对一对,能落到四种情况里。这张表就叫混淆矩阵(confusion matrix)——它是分类任务所有评估指标的"老地基"。
是什么?
用一个最朴素的画法(行是真实标签,列是模型预测):
预测:1(正类) 预测:0(负类)
真实:1(正类) TP FN
真实:0(负类) FP TN
四个格子的名字得记牢,后面所有指标都从它们身上长出来:
- TP(True Positive,真正例):真实是 1、预测也是 1——"抓对了"。
- FN(False Negative,假负例):真实是 1、预测是 0——"漏报了",该抓的没抓到。
- FP(False Positive,假正例):真实是 0、预测是 1——"误报了",冤枉了好人。
- TN(True Negative,真负例):真实是 0、预测也是 0——"放对了"。
"混淆"这名字挺形象:模型最容易"混淆"的就是 FN 和 FP 这两种错法,而这两种错的代价天差地别(下面会讲)。
为什么单看"准确率"会翻车?
最直觉的指标是准确率(accuracy)= 猜对的 ÷ 全部。但它在类别不平衡时会骗人。举个极端的:100 个人里只有 1 个病人,模型偷懒永远猜"健康",准确率照样 99%,可那个病人一个都没诊出来。混淆矩阵的价值,正是把"猜对/猜错"拆成四种,让你看清错在哪、错的是哪种。
原理往深走一步:从这四个数里长出一堆指标
光有矩阵还不够,往里塞公式,得到几个真正有用的率。但光背公式记不住,得先搞懂它们各自在问一个什么样的问题——这是理解这三个指标的关键:
-
精确率 Precision = TP / (TP + FP)。
分母 (TP + FP) 是"模型报出来的所有正类"——不管报对报错,只要它喊了"是",都算进去。所以精确率回答的问题是:"在你所有喊'正类'的警报里,真警报占多少?" 它是站在"预测结果"这头往回看(条件概率写作 P(真实为正 ∣ 预测为正))。FP 越多(瞎报警),分母不变、分子被稀释,精确率越低——你越爱乱喊"狼来了",别人越不信你。 -
召回率 Recall = TP / (TP + FN)。
分母 (TP + FN) 是"真实存在的所有正类"——不管你抓没抓到,该抓的本来就有这么多。所以召回率回答的问题是:"在真实正类里,你到底抓出了多少?" 它是站在"真实标签"这头往前看(条件概率写作 P(预测为正 ∣ 真实为正))。FN 越多(漏抓),分母不变、分子变少,召回率越低。注意它俩的分母根本不是一回事:精确率看的是"你报的",召回率看的是"实际有的"。一个盯预测、一个盯真相——这"一字之差",正是两者最核心的原理分野,也是下面"此消彼长"的根源。
-
F1 分数 = 2·Precision·Recall / (Precision + Recall)。
它是精确率和召回率的调和平均。为什么不用更常见的算术平均?因为算术平均会被"一个很高、一个很低"骗过去:比如精确率 1.0、召回率 0.1,算术平均还有 0.55,看着还行,但其实你基本没抓到人。调和平均不一样——它对"偏科"很苛刻,只有两者都高时它才高。所以 F1 是个"综合但挑剔"的打分:想拿高分,俩率都得拿得出手。 -
还有准确率 Accuracy = (TP + TN) / 全部,适合类别均衡时看个整体,不平衡时参考意义有限(前面讲过了)。
来个具体例子落地:假设 100 个样本,模型给出 TP=70、FP=10、TN=15、FN=5。
- 准确率 = (70+15)/100 = 85%
- 精确率 = 70/(70+10) ≈ 87.5%(你喊的 80 个"正类"里,87.5% 是真没错)
- 召回率 = 70/(70+5) ≈ 93.3%(真实 75 个正类里,你抓到了 93.3%)
- F1 = 2×0.875×0.933/(0.875+0.933) ≈ 90.3%
你看,同样是 85% 的准确率,拆开后才发现"漏报只有 5 个、误报却有 10 个"——精确率(管误报)和召回率(管漏报)各管一摊,信息量一下子就大了。
进一步:精确率和召回率,是一对冤家
它们常常此消彼长,根子就在上面那点——精确率的分母是你报的正类数,召回率的分母是真实的正类数。你把判定阈值(第三节那个 0.5)调高,模型更保守,只极有把握才判 1:报的正类变少 → FP 变少(精确率升),但很多 borderline 的正类没被判出来 → FN 变多(召回率降)。反过来调低阈值,召回率升、精确率降。业务上得想清楚更怕"漏"还是更怕"冤枉":
- 癌症筛查:宁可误报也别漏报(FN 代价大),所以看重召回率;
- 垃圾邮件:宁可漏过也别误杀重要邮件(FP 代价大),所以看重精确率。
F1 就是给这对冤家找个折中分数,前提是你得先想清楚自己站在哪头。
说到底,混淆矩阵和它派生的一堆率,是逻辑回归(以及所有分类模型)从"训出来"走向"敢不敢用"的必经一关——它把我们第三节那个"阈值"从预测参数,变成了评估旋钮。
九、几个你大概率会追问的问题
1. 决策边界一定是条直线吗?
不一定。先把判定规则翻出来看:模型判"1 类"的条件是概率 \(p \geq 0.5\),等价于打分 \(z \geq 0\),也就是 \(\mathbf{w}^T\mathbf{x} + b = 0\)。在你喂进去的那些特征组成的坐标系里,这确实是一条直线(更高维就是超平面)。
但"线性模型"这词特别容易误导人——它说的是"对参数 w 线性",不是"对原始特征 x 线性"。所以只要你在喂特征之前先做点变换,边界就能弯。
- 举个具体例子:假设真实的分界线是个圆——圆内是一类、圆外是另一类。光靠 \(w_1x_1 + w_2x_2 + b = 0\) 这种直线,永远切不出一个圆。但如果你新造一个特征 \(x_3 = x_1^2 + x_2^2\) 一起喂进去,判定式就变成 \(w_3(x_1^2 + x_2^2) + b = 0\),回到原始 \((x_1, x_2)\) 空间一看,正好是个圆。特征一变,边界就弯了。
- 这带出一个关键认知:逻辑回归能画多复杂的边界,上限取决于你怎么造特征。神经网络能自己学特征,逻辑回归不行,它全靠你把"好特征"喂到嘴边——所以才有那句老话:"特征工程决定了逻辑回归的上限。"
- 也得说实话:它终究只是在"变换后的空间"里画一个线性分界。碰到纠缠得特别厉害、形状很妖娆的边界,要么你得堆一大堆手工特征,要么干脆换模型(核方法、决策树、神经网络)。逻辑回归不是包打天下的。
2. 不止两类怎么办?
现实里常是多分类(猫 / 狗 / 兔子)。逻辑回归本质是二分类,套多类常见两种打法:
- 打法一:一对多(One-vs-Rest,OvR)。训 K 个二分类器,第 k 个只回答"是不是第 k 类"。预测时把 K 个都跑一遍,谁的分数最高归谁。
- 好处:简单,直接复用二分类逻辑回归;而且它不要求类别互斥——一张图可以同时"是猫又是宠物",适合多标签场景。
- 坑:K 很大时,每个分类器都面临"一类 vs 剩下所有类"的极度不平衡;而且 K 个输出各自独立,加起来不等于 1,你没法直接读出"每个类的全局概率"。
- 打法二:Softmax 回归(多分类版逻辑回归)。这是多分类的"正经"解法——一个模型、一次前向,用 Softmax 把 K 个打分压成一份加起来正好为 1 的概率分布,再取概率最大的类。它到底是什么、公式怎么来的、和 Sigmoid / 交叉熵是什么关系、解决了什么痛点、损失函数和梯度怎么跟着升级,咱们专门开了第七章细讲,这里不重复。一句话记住:二分类逻辑回归是"1 套权重 + Sigmoid",Softmax 回归是"K 套权重 + Softmax",骨子里还是线性打分 + 梯度下降。
- 怎么选:类别互斥、想要正经概率分布 → 上 Softmax(第七章);类别不互斥、或者类别特别多想偷懒复用二分类 → 用一对多。(还有个"一对一"打法,SVM 用得多,逻辑回归里较少碰。)
- 说到底,二分类逻辑回归就是这两套打法的乐高积木。
3. 训练集上很准、新数据就拉胯,咋办?
这名儿叫过拟合:模型没学到背后的规律,反而把训练集里的噪声和特例都背下来了。典型症状是训练误差小得感人,一换没见过的验证 / 测试数据误差就爆。那个"训练误差 和 验证误差之间的差距",就是过拟合的体温计。
- 逻辑回归也会过拟合吗? 会,尤其在你按第一题那样堆了一堆多项式特征之后。参数一多,权重就能放飞到把每个训练点都"完美穿过",边界变得歪歪扭扭专门贴合噪声。
- 解药一:正则化。在损失函数后面加一项"惩罚权重过大"的因子,变成 \(J + \lambda\cdot R(\mathbf{w})\):
- L2(岭 / Ridge):惩罚 \(R = \sum w_j^2\),把权重往 0 拽但很少正好拽到 0,平滑好调,是默认首选。
- L1(套索 / Lasso):惩罚 \(R = \sum|w_j|\),能干脆把某些权重直接压成 0,顺手做了特征选择——当你怀疑一堆特征没用时特别好使。
- 还有 L1 + L2 混合的 Elastic Net。
- 那个旋钮 \(\lambda\) 很关键:太小,惩罚不够,还是过拟合;太大,矫枉过正,模型变"傻"(欠拟合),连真规律都丢了。它得在验证集上调,不能拿测试集调。
- 解药二:干脆多搞点数据、砍掉没用的特征、降低多项式阶数——从源头减少模型"作弊"的空间。
- 解药三(也是前提):先得能发现它。过拟合光看训练集准确率看不出来,你得留一份验证集(或做交叉验证),盯着"训练误差 vs 验证误差"的差距。这又绕回咱们前面说的——你那批标注数据得切成训练 / 验证 / 测试三份。
- 往深里想,正则化本质上就是把"奥卡姆剃刀"写进了损失函数:在数据许可的范围内,优先选更简单(权重更小)的解释。
十、写在最后
逻辑回归是理解分类问题、理解损失函数、理解梯度下降最好的那块敲门砖,往深的神经网络的输出层、推荐系统的点击率预估、风控的评分卡,背后都能看到它的影子。
与君共勉~

浙公网安备 33010602011771号