2.3 逻辑回归与线性分类

1.从回归走到分类:输出得是个概率

说起来,前面2.1 节我们花了一整篇讲线性回归,它做的事很朴素,就是拿一组参数把输入加权求和,得到一个实数。设输入向量是 xxxx 表示一个样本的特征(比如一封邮件里各个词出现的次数),参数向量是 wwww 表示每个特征对应的权重,偏置项是 bbbb 是一个常数,那么线性回归的输出就是:

z=wTx+bz = w^{T}x + b

这里 wTw^{T} 表示向量 ww 的转置(行变列、列变行,转过来才能和 xx 做内积),zz 就是加权求和之后得到的那个实数。zz 这个数可大可小,正负都行,没有边界。

回归问题里这没什么麻烦,因为我们要预测的本来就是个实数,房价也好、温度也好、销量也好,多大都合理。可分类问题要的就完全不一样了。分类问题想回答的是这一件事属不属于某一类,比如这封邮件是不是垃圾邮件、这个客户会不会违约、这位患者的肿瘤是良性还是恶性。我们最想要的,其实是一个概率,落在 0011 之间,越靠近 11 就越像是正类,越靠近 00 就越不像是。可线性回归给的 zz 是个任意实数,怎么办呢。这就轮到sigmoid函数出场了。sigmoid把任意实数光滑地压到 (0,1)(0,1) 这个开区间里,我们把它记作 σ(z)\sigma(z),读作sigma of z:

σ(z)=11+ez\sigma(z) = \frac{1}{1+e^{-z}}

这里 σ\sigma 就是sigmoid这个函数本身,ee 是自然常数(大约 2.7182.718),z-zzz 的相反数。当 zz 很大的时候,eze^{-z} 接近 00,分母接近 11σ(z)\sigma(z) 就接近 11。当 zz 很小(很负)的时候,eze^{-z} 变得很大,分母跟着很大,σ(z)\sigma(z) 就接近 00。当 z=0z=0 时,σ(0)=0.5\sigma(0)=0.5,正好处在中间。这么一压,我们就得到了一个概率值 y^=σ(z)\hat{y}=\sigma(z)y^\hat{y} 读作y hat,表示模型预测这个样本属于正类的概率。比方说模型算出来 y^=0.83\hat{y}=0.83,就是说模型觉得这封邮件有八成三的把握是垃圾邮件。

我记得看过一本讲医学决策的小书,里面说有经验的大夫下判断时,很少把话说死,总要在确诊之前留个概率余地,宁可说成八成把握,也不愿拍胸脯打包票。这脾气其实和sigmoid挺像,再激烈的输入(动辄正几百负几百),到了它这里都被安抚成一段平稳的、落在 0011 之间的概率表态,既不让你冲过头,也不让你彻底躺平。

2.交叉熵损失:分类为什么不用均方误差

概率有了,下一个问题就是怎么衡量这个概率准不准。1.4 节讲信息论的时候我们提过交叉熵,这里它正好派上用场。设一共有 nn 个样本,nn 表示样本总数,第 ii 个样本的真实标签是 yiy_iyi{0,1}y_i \in \{0,1\}(意思是 yiy_i 只能取 001100 表示负类,11 表示正类),模型预测它属于正类的概率是 y^i\hat{y}_i。那么逻辑回归用的损失函数叫二元交叉熵,写成:

L=1ni=1n[yilogy^i+(1yi)log(1y^i)]L = -\frac{1}{n}\sum_{i=1}^{n}\left[y_i\log\hat{y}_i + (1-y_i)\log(1-\hat{y}_i)\right]

我们一项一项拆。\sum 是求和符号,意思是从第 11 个样本加到第 nn 个样本。log\log 是自然对数(以 ee 为底的对数),它的作用是把概率这种小数映射成一个更方便优化的数。中括号里有两项,靠加号连起来。当真实标签 yi=1y_i=1 时,(1yi)(1-y_i) 就是 00,第二项整个消失,只剩 logy^i\log\hat{y}_i 这一项起作用,意思是模型预测的概率 y^i\hat{y}_i 越接近 11logy^i\log\hat{y}_i 就越接近 00,损失越小。反过来当 yi=0y_i=0 时,第一项消失,只剩 log(1y^i)\log(1-\hat{y}_i) 这一项,意思是 y^i\hat{y}_i 越接近 00 损失越小。最外面那个负号是因为 log\log 算出来是负数(概率小于 11 时对数为负),加个负号把损失变成正数,方便往下做梯度下降。最后除以 nn 是为了取个平均,让损失不随样本量大小起伏。

交叉熵不是拍脑袋选的,它从伯努利分布的最大似然推出来。 这条线我们走一遍,你就明白为什么偏偏是这个公式。标签 yi{0,1}y_i\in\{0,1\} 服从伯努利分布,模型预测正类概率 y^i=σ(zi)\hat y_i=\sigma(z_i),那么单个样本出现的概率是 y^iyi(1y^i)1yi\hat y_i^{y_i}(1-\hat y_i)^{1-y_i}yi=1y_i=1 时等于 y^i\hat y_iyi=0y_i=0 时等于 1y^i1-\hat y_i)。nn 个样本独立的似然是连乘:

L=i=1ny^iyi(1y^i)1yiL=\prod_{i=1}^{n}\hat y_i^{y_i}(1-\hat y_i)^{1-y_i}

取对数把连乘变连加:logL=i[yilogy^i+(1yi)log(1y^i)]\log L=\sum_i\bigl[y_i\log\hat y_i+(1-y_i)\log(1-\hat y_i)\bigr]。最大似然要最大化它,等价于最小化它的负数再除以 nn 取平均——正好就是上面的交叉熵损失。所以最小化交叉熵 = 最大化伯努利似然,这两件事是一件。这也顺带回答了为什么交叉熵比均方误差更适合分类:它和标签的真实分布(伯努利)在概率假设上对得上。

交叉熵对参数的梯度,形式特别干净。 这个梯度后面训练时要用,我们顺手推出来。记 zi=wxi+bz_i=w^\top x_i+by^i=σ(zi)\hat y_i=\sigma(z_i)。单个样本的损失 i=[yilogy^i+(1yi)log(1y^i)]\ell_i=-[y_i\log\hat y_i+(1-y_i)\log(1-\hat y_i)]。先用链式法则,注意 dy^idzi=σ(zi)(1σ(zi))=y^i(1y^i)\frac{d\hat y_i}{dz_i}=\sigma(z_i)(1-\sigma(z_i))=\hat y_i(1-\hat y_i)

didzi=yiy^iy^i(1y^i)+1yi1y^iy^i(1y^i)\frac{d\ell_i}{dz_i}=-\frac{y_i}{\hat y_i}\cdot\hat y_i(1-\hat y_i)+\frac{1-y_i}{1-\hat y_i}\cdot\hat y_i(1-\hat y_i)

化简(y^i\hat y_i 被约掉):didzi=(yiyiy^i)((1yi)y^i)=y^iyi\frac{d\ell_i}{dz_i}=-(y_i-y_i\hat y_i)-((1-y_i)\hat y_i)=\hat y_i-y_i。你看,sigmoid 那一坨导数全约干净了,最后就是预测概率减真实标签。这个漂亮的简化正是交叉熵配 sigmoid 的妙处——均方误差配 sigmoid 会留一个 σ(z)\sigma'(z) 拖累,交叉熵不会。再往 ww 传一步:iw=(y^iyi)xi\frac{\partial\ell_i}{\partial w}=(\hat y_i-y_i)x_i,全体样本求和就是梯度。

这里有个老生常谈的问题,分类为什么不用均方误差(MSE)呢。说穿了有两个原因。第一,把sigmoid套进MSE之后,损失函数关于参数的导数里会多出一个 σ(z)\sigma'(z) 的因子(σ(z)\sigma'(z) 就是sigmoid对 zz 求导的结果,前面3.10 节我们提过它),而sigmoid在输入偏大偏小的时候这个导数接近零,这么一来梯度很容易消失,模型学得特别慢。第二,均方误差背后假设的是高斯分布,而分类问题的标签其实是伯努利分布(抛硬币那种非0即1的分布),交叉熵恰恰是从伯努利分布的最大似然估计一路推出来的,1.4 节讲过的MLE在这里对上了号。所以分类用交叉熵,数值上好优化,概率假设上也对得上,两头都合适。

3.决策边界:一刀切下去是一条直线

讲完损失,我们再看看逻辑回归到底在数据空间里画了一幅什么画。

刚才说 y^=σ(z)\hat{y}=\sigma(z),而 z=wTx+bz=w^{T}x+b 是个线性的东西。判断一个样本属于正类还是负类,常用的规则是看 y^\hat{y} 是否大于 0.50.5。而 y^=0.5\hat{y}=0.5 恰好对应 z=0z=0(因为 σ(0)=0.5\sigma(0)=0.5)。所以分类的边界其实就是 z=0z=0 这条线,也就是:

wTx+b=0w^{T}x + b = 0

如果输入 xx 是二维的(只有两个特征),那这条边界就是平面上的一条直线。如果是三维的,就是空间里的一个平面。再高维的话,就是一个超平面(高维空间里那种广义的平面)。这条线的一边被判作正类,另一边被判作负类,所以大家叫它决策边界。

这条边界有个特别朴素的好处,就是好解释。每个特征的权重 wjw_jwjw_j 表示向量 ww 的第 jj 个分量,也就是第 jj 个特征对应的权重)直接告诉你这个特征对决策有多大影响。wjw_j 是正的,说明这个特征越大越偏向正类。wjw_j 是负的,则正好相反。wjw_j 的绝对值越大,影响也越强。在金融风控那种特别讲究可解释性的场景里,这条性质格外值钱,监管来问你为什么拒了某个客户的贷款,你能把权重摊开一条一条解释给他听。

不过这条直线的代价也明显,它只能切线性可分的问题。要是数据是那种你包我我包你的环形分布,一条直线再怎么调也切不开,那就得靠后面要讲的核方法或者神经网络去升维。我记得有本经典的机器学习教材里举过这么个例子,说光看身高和体重这两维,一条直线怎么都分不好男女,可一旦再加上肩宽、腰围这些维度,线性模型又能用了。这就是升维的直觉,1.3 节讲PCA的时候我们也聊过特征维度的处理思路,不妨对照着看。

4.多分类怎么办:softmax来接手

二分类讲完了,可现实里多半是多分类问题。手写数字识别有 1010 个类别,ImageNet有 10001000 个类别,物流公司要把包裹分到普通件、加急件、易碎件、冷链件这几类,同样是多分类。这时候sigmoid就不够用了,我们要请出3.7 节注意力机制里也出现过的softmax。

softmax做的事情是这样的。对每一个类别 kkkk 是类别的编号,从 11KKKK 表示总类别数),模型先各自算出一个logit zkz_k(每个类别都有一组自己的参数 wkw_kbkb_k,加权求和得到 zk=wkTx+bkz_k=w_k^{T}x+b_k),然后softmax把这 KK 个logit一起转成一组概率:

y^k=ezkj=1Kezj\hat{y}_k = \frac{e^{z_k}}{\sum_{j=1}^{K}e^{z_j}}

这里 y^k\hat{y}_k 是模型预测这个样本属于第 kk 类的概率,ezke^{z_k} 是把第 kk 个logit做一次指数(这样保证结果是正数),分母 j=1Kezj\sum_{j=1}^{K}e^{z_j} 是把所有 KK 个指数加起来(jj 是求和时用的临时下标,从 11 取到 KK),这样保证所有类别的概率加起来等于 11。哪个类别的logit zkz_k 越大,它分到的概率 y^k\hat{y}_k 就越大,但每个类别都还能分到一点,所以叫softmax(soft的意思是没那么硬,不像argmax那种赢家通吃的做法)。

多分类用的损失函数是交叉熵的推广形式:

L=1ni=1nk=1Kyi,klogy^i,kL = -\frac{1}{n}\sum_{i=1}^{n}\sum_{k=1}^{K}y_{i,k}\log\hat{y}_{i,k}

这里 yi,ky_{i,k} 是一个one-hot向量里的元素(一个样本只属于一个类别,那一类的位置取 11,其它位置都是 00),y^i,k\hat{y}_{i,k} 是模型预测第 ii 个样本属于第 kk 类的概率。这个式子看着吓人,其实和二分类那份是同一回事,把真实标签那一类对应的 logy^\log\hat{y} 拿出来,取负号再求平均就行。

5.两个常见场景:垃圾邮件和信用违约

最后我们落到两个具体场景里说一说。

头一个是垃圾邮件分类。设小张是一家邮件服务商的工程师,他手里有几十万封打过标签的邮件。他先做一步特征工程,把每封邮件里出现的高频词统计出来,组成向量 xx(比如免费、点击、链接、优惠这些词各出现几次),再给每个词配一个权重 ww。训练完之后,权重 ww 里绝对值最大的那些词,往往就是垃圾邮件最爱用的措辞。小张管它叫词袋模型配合逻辑回归,朴素贝叶斯(1.4 节讲过)做这件事也很在行,两者各有长短,逻辑回归不像朴素贝叶斯那样假设特征之间条件独立,它能把所有词的权重放在同一个线性组合里联合学习,特征间的相关性能更自然地反映到权重上,调起来也更顺手。

记得有一次,小张发现有个版本的模型把所有含红包字样的邮件全判成了垃圾邮件,连公司内部发的红包通知也没放过。排查半天才发现,是训练数据里红包这个词几乎只出现在垃圾邮件里,权重被推得过高。这件事说明逻辑回归虽然好解释,可解释出来的也只是数据里的偏差,数据偏了模型跟着偏,这是机器学习里反复出现的教训。

第二个是信用违约预测。设小明在一家银行的信贷部门做事,他要根据客户的年龄、收入、负债比、历史逾期次数这些特征,预测这个客户未来一年内会不会违约。这同样是个二分类,违约设为正类。逻辑回归在这里几乎是默认的基线模型(baseline,意思是最基础的、拿来对照的模型),一来它输出概率,银行可以直接拿这个概率排序做授信额度,二来它好解释,监管来查你能把每个特征的权重摆出来。金融行业对可解释性的执着,其实比Accuracy(准确率)还要重一些。

不过这里有个常见的坑。要是直接把原始收入(几万到几百万都有)塞进去,这个特征的尺度会压垮别的特征,权重数值乱跳,训练很不稳定。小明通常会先做一步标准化(把每个特征减去均值再除以标准差,让每个特征大致落在 00 附近、方差为 11 的范围里),让各个特征在同一个尺度上说话。这个细节看着不起眼,可往往是模型能不能收敛、收敛得好不好的关键。顺手提一句,如果觉得特征太多想压一压,可以加L1正则(Lasso)或者L2正则(Ridge),前者会把一部分权重直接压成 00,相当于顺带做了特征选择,后者只是把权重整体往小里拉,两者思路不同,按需取用就行。

逻辑回归这个东西,看着就是个线性模型套了一层sigmoid,可它把线性组合、概率、信息论、最大似然这几样东西严丝合缝地接到一起,是入门机器学习绕不过去的一关。把它吃透了,后面softmax、神经网络、注意力机制这些就都有了着落。今天就先到这儿,下一章见。

练习

Q1. 分类任务为什么用交叉熵而不用均方误差?从"梯度会拖一个 σ(z)\sigma'(z)"和"概率假设对不对"两个角度说。

两个原因。第一,把 sigmoid 套进 MSE 后,损失对参数的导数里会多出一个 σ(z)\sigma'(z) 因子,而 sigmoid 在输入偏大偏小时这个导数接近零,梯度容易消失、模型学得特别慢。第二,MSE 背后假设的是高斯分布,可分类标签其实是伯努利分布(非 0 即 1),而交叉熵恰恰是从伯努利分布的最大似然推出来的。所以交叉熵数值上好优化、概率假设也对得上,两头都合适。

Q2.σ(0)\sigma(0)σ(2)\sigma(2)(取 e2.718e\approx2.718e20.135e^{-2}\approx0.135),分别说明 z=0z=0zz 很大时模型的态度。

σ(0)=11+e0=12=0.5\sigma(0)=\frac{1}{1+e^0}=\frac{1}{2}=0.5,模型五五开、拿不准。σ(2)=11+e2=11+0.1350.881\sigma(2)=\frac{1}{1+e^{-2}}=\frac{1}{1+0.135}\approx0.881,模型强烈倾向正类(约 88% 把握)。sigmoid 把任意大的实数光滑地压到 (0,1)(0,1)zz 越大越接近 1,越小(越负)越接近 0。

Q3. 逻辑回归的决策边界是什么形状?为什么说它处理不了"你包我我包你"的环形数据?

决策边界是 z=wTx+b=0z=w^\mathsf{T}x+b=0 这条线,二维时是平面上的一条直线,高维时是超平面。判断规则是看 y^=σ(z)\hat{y}=\sigma(z) 是否大于 0.5,而 y^=0.5\hat{y}=0.5 恰好对应 z=0z=0。一条直线再怎么调也切不开环形分布里外两团数据,这种线性不可分的问题得靠后面的核方法或者神经网络去升维才能分开。

Q4.(面试题) 完整推导单个样本的交叉熵损失对 zz 的梯度,说明为什么 sigmoid 那一坨导数会约干净,最后正好剩下 y^y\hat{y}-y

单样本损失 =[ylogy^+(1y)log(1y^)]\ell=-\bigl[y\log\hat{y}+(1-y)\log(1-\hat{y})\bigr],其中 y^=σ(z)\hat{y}=\sigma(z)。用链式法则,先注意 dy^dz=σ(z)(1σ(z))=y^(1y^)\frac{d\hat{y}}{dz}=\sigma(z)(1-\sigma(z))=\hat{y}(1-\hat{y}),于是 ddz=yy^y^(1y^)+1y1y^y^(1y^)\frac{d\ell}{dz}=-\frac{y}{\hat{y}}\cdot\hat{y}(1-\hat{y})+\frac{1-y}{1-\hat{y}}\cdot\hat{y}(1-\hat{y})。化简时 y^\hat{y} 被约掉:=(yyy^)(y^yy^)=y^y=-(y-y\hat{y})-(\hat{y}-y\hat{y})=\hat{y}-y。sigmoid 那一坨导数全约干净,最后就是"预测概率减真实标签"。再往 ww 传一步:w=(y^y)x\frac{\partial\ell}{\partial w}=(\hat{y}-y)x。这个漂亮的简化正是交叉熵配 sigmoid 的妙处——均方误差配 sigmoid 会留一个 σ(z)\sigma'(z) 拖累,交叉熵不会,所以分类学得又快又稳。

相关标签
机器学习逻辑回归分类