前面讲过了回归(Regression) 问题,现在来讲分类(Classification) 这件事情。与回归任务不同,分类任务的输出是一个类别。如果要进行贷款申请决策,输入是某个人的收入、储蓄和年龄等信息,输出则决定是否给这个人贷款;如果用于医疗诊断,输入是症状、年龄、性别和病史等信息,输出则是这个人生病的种类;如果做手写数字识别,输入是一张手写图像,输出则是判断这属于哪一个字符。

案例分析:宝可梦属性预测

宝可梦有十八种属性,包括一般系、火系、水系、电系等等。我们需要找一个函数,输入是某一只宝可梦,输出该宝可梦的属性,这是一个分类任务。首先要解决一个问题,如何将宝可梦作为函数的输入?我们需要用数值来量化宝可梦的各种信息:总体评价(Total)、生命值(HP)、攻击力(Attack)、防御力(Denfense)、特殊攻击(SP Atk)、特殊防御(SP Def)、速度(Speed) 等等。因此一只宝可梦可以用 $7$ 个数字组成的一个向量(Vector) 来表示前面描述的 $7$ 个特征。

使用回归思想考虑分类问题

有一种思想是将分类问题作为回归问题来处理,我们以二分类(Binary Classification) 为例子,即输出只有两种类别,在训练时类别一的标签用 $1$ 表示,类别二用 $-1$ 表示。而在测试时,回归问题的测试数据输出不会正好是 $1$ 或 $-1$, 因此预测值越接近 $1$ 则分类为类别一,否则分类为类别二。所以可以将 $0$ 作为分界线,预测值大于 $0$ 时认为它接近于 $1$, 小于 $0$ 时认为它接近于 $-1$.

这种思想存在着什么样的缺陷呢?假设现在的线性模型为 $y=b+w_{1} x_{1}+w_{2} x_{2}$, 即输入的特征为 $x_1$ 和 $x_2$, 上图中蓝色的点为类别一,红色的点为类别二,经过训练后得到的函数(两个类别的分界) 使用图中的直线 $b+w_{1} x_{1}+w_{2} x_{2}=0$ 来表示。但如果类别一的数据分布如右图所示时,假设使用绿色线考虑右下角的那些点,输出可能会远大于 $1$, 这对于回归模型来说是不好的样本点,会造成很大的训练误差。因此实际在训练后,得到的最好的函数可能是紫色线条,这样右下角的蓝色点造成的误差会小一些。

因此回归模型定义好坏的方式,对于分类问题而言并不适用,它会惩罚那些预测值“过于正确”的点。另一个问题在于,如果现在处理一个多分类问题(Multiple-class), 将类别一用 $1$ 表示,类别二用 $2$ 表示,类别三用 $3$ 表示… 等同于说类别一和类别二比较接近(差值为 $1$), 而和类别三比较遥远(差值为 $2$), 而实际上这些类别之间可能并没有这种关系。

处理分类问题的理想思路

处理分类问题的理想方法应该是:

  1. 找一个函数(模型) $f(x)$, 其输出的预测值之间不应该像回归模型一样连续,而应当是离散的。
  2. 而在训练的时候,损失应该定义成当前函数 $f$ 在训练数据上预测错误的次数或错误率,即 $L(f)=\sum_{n} \delta\left(f\left(x^{n}\right) \neq \hat{y}^{n}\right)$, 其中 $\delta$ 在预测错误时取 $1$, 预测正确时取 $0$.
  3. 我们希望损失越小越好,但是由于这样的损失函数无法微分,梯度下降无法使用,所以要使用其它的方法来找到最好的函数 $f^{\ast}$, 比如感知机算法或支持向量机算法,这些方法以后再提。

线性分类:概率生成模型

我们先从概率的视角来考虑分类问题的解法。

假设有两个盒子,都放有蓝球和绿球,现在从这两个盒子中随机抽取了一颗球出来,已经发现是蓝色的。问这个球是从盒子 $1$ 抽取出来的概率,与从盒子 $2$ 抽取出来的概率分别是多少?注意这个表述和下面的表述是不一样的:从这两个盒子中随机抽取一颗球,球是蓝色的概率是多少?

现在给出:从盒子 $1$ 抽一颗球的概率为 $P\left(B_{1}\right)=2 / 3$, 从盒子 $2$ 抽一颗球的概率为 $P\left(B_{2}\right)=1 / 3$. 盒子 $1$ 中蓝球占 $P\left( \text{Blue} | B_{1}\right)=4 / 5$, 绿球占 $P\left( \text{Green} | B_{1}\right)=1 / 5$. 盒子 $2$ 中蓝球占 $P\left( \text{Blue} | B_{2}\right)=2 / 5$, 绿球占 $P\left( \text{Green} | B_{2}\right)=3 / 5$. 由概率论中贝叶斯公式可以知道

如果将盒子 $1$ 与盒子 $2$ 的概念换成类别 $1$ 与类别 $2$, 给你一只宝可梦 $x$, 属于类别 $1$ 的概率为:

注意在类比上面的小球的例子中,颜色并不是一种类别标签,而是一种特征,就好像宝可梦的原始 CP 值。如果能知道公式中的这些概率值,分类问题便很好解决了,此时可以计算出宝可梦 $x$ 属于每个类别的概率 $P\left(C_{1} | x\right)$ 和 $P\left(C_{2} | x\right)$, 较大的那个概率代表的类可以作为预测的类别。

问题在于,对于这样的二元分类问题,需要计算 $P\left(C_{1}\right)$, $P\left(C_{2}\right)$, $P\left(x | C_{1}\right)$ 和 $P\left(x | C_{2}\right)$ 这四个值。我们希望可以根据已有的训练数据,将这些概率值估测出来,这种想法叫作生成模型(Generative Model). 因为在得到上面的概率之后,我们可以自己计算每一个 $x$ 产生的概率:

这样就可以知道 $x$ 的概率密度,即从这个分布生成或者说从抽样出 $x$ 的概率。

公式中概率值的计算

首先考虑如何计算 $P\left(C_{1}\right)$ 和 $P\left(C_{2}\right)$, 在上面的公式中这样的概率被称为先验(Prior). 依旧考虑简单的二元分类问题,类别分别为水系和一般系(忽略其它的属性以简化问题), 并收集训练和测试数据。假设训练数据中一共有 $79$ 只水系,$61$ 只一般系,可以得到

即随机抓一只宝可梦,为水系的概率为 $0.56$, 为一般的概率为 $0.44$.

之前提到了,每一只宝可梦 $x$ 都使用向量来表示它们的各项特征(Feature), 向量中的每一个元素是特征值。假设我们考虑防御力和特殊防御力两种特征,并将训练数据中水系的 $79$ 只宝可梦样本进行可视化,

假设此时我们重新抓了一只宝可梦 $x$, 它没有在训练数据中出现过,如图所示红点。这时如果你要算从水系抓一只宝可梦刚好是 $x$ 的几率,不能因为训练数据中没出现过从而认为 $\mathrm{P}(\mathrm{x} | \text {Water} )=0$. 我们应当这样理解:

现在获取的这些数据只是真实数据的冰山一角,并假设水系宝可梦的防御力和特殊防御力这两个特征是从一个高斯分布(Gaussian Distribution) 中抽样 $79$ 个点得到的。然而从这种高斯分布中抽样得到宝可梦 $x$ 的概率并不为零,因此问题变成了如何根据现在的训练数据,去找到背后隐藏的高斯分布。

可以将高斯分布想象成一个函数,输入是向量 $x$, 代表宝可梦的特征。输出是这只宝可梦从该分布被抽样出来的概率,准确来说应该是概率密度(与概率成正比). 高斯函数的形状取决于均值 $\mu$ 和协方差矩阵 $\Sigma$.

因此假设存在这种高斯分布,从中抽样出这 $79$ 个点,如果能够根据这些点估测出 $\mu$ 和 $\Sigma$, 得到对应的 $f_{\mu, \Sigma}(x)$, 这样就可以计算某一个 $x$ 从该高斯分布中被抽样出来的概率。

最大似然思想

为了找到 $\mu$ 和 $\Sigma$, 需要引入最大似然(Maximum Likelihood) 的思想。

首先我们要知道,任何的高斯分布,都有可能抽样出这 $79$ 个点,因为高斯分布可以抽样出特征空间任意一点,只是有些点被抽样出来的概率会非常非常低,但又不会等于零。所以如果考虑整体的 $79$ 个点的抽样,不同的高斯函数抽样出这 $79$ 个点的概率也会不同。因此假设给出了高斯分布的 $\mu$ 和 $\Sigma$, 我们可以计算该高斯分布抽样出这 $79$ 个点的概率:

上式中的 $L$ 指的是似然(Likelihood), 不是损失(Loss). 因为所有 $79$ 个点是独立被抽样出来的,所以“高斯分布抽样出这 $79$ 个点”整个事件的概率可以看成分别单次抽样出第 $1,2,3,\ldots , 79$ 个点的概率之积。

接下来作出假设,穷举所有的 $\mu$ 和 $\Sigma$ 并计算似然,如果 $x^{1}, x^{2}, x^{3}, \ldots \ldots, x^{79}$ 这些点从高斯分布 $\left(\mu^{\ast}, \Sigma^{\ast}\right)$ 抽样出来,可以得到最大的似然值,那么我们认为这个高斯分布就是最接近理想高斯分布 $\hat {f}$ 的最佳高斯分布 $f^{\ast}$. 问题变成了:

可以通过微积分去求解,或者记住结果:

通过极大似然估计出某个类 $C$ 的高斯分布$(\mu^{\ast}, \Sigma^{\ast})$, 就能够估计某个 $x$ 从中被抽样出来的概率 $P\left(C | x\right)$ :

对于二分类问题,如果 $P\left(C_1 | x\right) > 0.5$, 则可以认为 $x$ 属于 $C_1$ 类,否则属于 $C_2$ 类(注意我们现在讨论的分类问题一直局限于二分类的情况). 如果选择考虑所有的 $7$ 个特征,则每个宝可梦 $x$ 是存在七维空间的一个点,此时多元高斯分布的 $\mu$ 是一个 $7$ 维向量,$\Sigma$ 是 $7 \times 7$ 的矩阵。

极大似然模型的改进

对于不同类别的高斯函数,其实可以共享相同的协方差矩阵。我们知道输入 $n$ 维特征,会得到 $n \times n$ 大小的协方差矩阵,如果对于不同的类别都计算不同的协方差矩阵,会给模型引入非常多的参数。而模型的参数多了意味着模型变得复杂,方差变大,容易产生过拟合问题。

此时我们需要找到 $\mu^{1}, \mu^{2}, \Sigma$ 最大似然 $L\left(\mu^{1}, \mu^{2}, \Sigma\right)$:

$\mu^{1}$ 和 $\mu^{2}$ 的计算方法和之前一样,而共用的 $\Sigma$ 需要这样计算:

具体的推导在 Bishop PRML 的 4.2.2 章节,这里不做推导了。你可以发现通过这样的处理,分类边界变成了一条直线,因此概率生成模型也可以被看作是线性模型。

概率模型回顾

概率生成模型与机器学习类似,流程也是三步。选择不同的概率分布,会得到不同的模型,而概率分布的参数即模型参数,比如高斯分布的 $\mu$ 和 $\Sigma$. 而我们使用生成训练数据的似然来表示函数的好坏,能够极大似然的参数代表着最好的函数,而计算参数的方法十分简单。

使用何种概率分布取决于模型的设计者,假设训练数据 $x$ 的每个特征 $x_1,x_2, \ldots $ 从概率模型中生成的概率是独立的,即可以拆解成:

假设拆解开后每个特征维度的模型,都是一维高斯分布,此时原来的高维高斯模型的协方差矩阵将变成对角矩阵,即非对角线元素都是零,这样可以进一步减少参数量。大部分时候我们凭直觉使用高斯概率分布,但二值特征更适合使用伯努利分布。假设所有的特征之间都是独立的,不考虑协方差矩阵,则这种分类方法变成了朴素贝叶斯分类器(Naive Bayes Classifier).

接下来分析后验(Posterior) 概率公式,上下同时除以分子:

取自然对数,我们用 $z$ 表示

因此后验概率可以改写为

我们注意到最终形式函数 $\sigma(z)$ 输入为 $z$, 这个函数叫作 Sigmoid 函数。当 $z$ 趋近于无穷大的时候,$\sigma(z)$ 趋近于 $1$; 否则趋近于 $0$. 接下来计算一下 $z$ :

根据前面的内容我们知道

$z$ 的右边项很容易计出 $\ln \frac{P\left(C_{1}\right)}{P\left(C_{2}\right)}=\frac{N_{1}}{N_{2}}$, 其中 $N$ 为样本数量,计算 $z$ 的左边项:

分别展开方括号其中的项:

因此可以计算出 $z$

而我们已经假设协方差矩阵共用,则有 $\Sigma_{1}=\Sigma_{2}=\Sigma$, 上式可以改写为

可以发现上式只有一项含有 $x$, 通过维度变化可发现,实际上后面的项是标量,因此简写为

这也解释了为什么共用协方差矩阵后,得到的分类边界是线性的。在生成模型中,其实就是在用某些方法估计上式中的 $N_{1}, N_{2}, \mu^{1}, \mu^{2}, \Sigma$, 用来计算 $\boldsymbol{W}$ 和 $b$. 不妨假设我们最终的目标就是在找这样的 $\boldsymbol{W}$ 和 $b$, 那么何必要用概率模型来舍近求远呢?所以人们设计了一种方法,直接寻找 $\boldsymbol{W}$ 和 $b$.

线性分类:Logistic 回归

根据之前的推导,我们发现分类任务其实是想要找到 $P_{w, b}\left(C_{1} | x\right)$ 的值,如果大于等于 $0.5$, 输出的预测类别为 $C_1$, 否则为 $C_2$. 如果使用高斯分布来进行极大似然估计,则有化简后的公式:

考虑机器学习的流程第一步,会发现此时函数集合(模型) 为 $f_{w, b}(x)=P_{w, b}\left(C_{1} | x\right)$.

选用不同的 $w$ 和 $b$ 会得到不同的函数 $f_{w,b}(x)$, 也即是说输入的 $I$ 维特征 $x=[x_1, \ldots , x_i, \ldots, x_I]$ 与一个 $I$ 维权重(Weight) 向量 $w=[w_1, \ldots , w_i, \ldots, w_I]$ 计算内积后,加上一个偏置(Bias) $b$ 得到 $z=\sum_{i} w_{i} x_{i}+b$, 写成这种形式只是为了直观地感受出,在这一步是一个线性的函数。将 $z$ 输入 Sigmoid 函数 $\sigma(z)$ 后得到最终想要的 $f_{w,b}(x)$.

以上整个模型流程,叫作 Losigtic 回归。中文译为逻辑回归或者逻辑斯谛回归,如果你真正了解了这一过程,你会发现这个词译为“对数几率回归”比较合适,因为我们的实际变形为:

几率(Odds) 指的是事件发生的概率和不发生的概率之比,而 $z$ 是两个概率分式取自然对数后的求和,我们希望能够用线性函数来代替它的实际效果。对比 Logistic 回归与线性回归模型,可以发现由于通过了一个非线性的 Sigmoid 函数 $\sigma$, Logistic 回归的输出一定在 $0$ 到 $1$ 之间。

Logistic 回归的最大似然估计

假设二分类任务的一组训练数据 $x^1, x^2, \ldots , x^N$ 是由我们定义的后验概率分布产生的,那么我们可以使用下面这样的似然函数,来计算某一组 $w$ 和 $b$ 产生这 $N$ 个样本数据的概率:

上面的公式中假设 $x^1,x^2,x^N$ 属于类别 $C_1$, $x^3$ 属于类别 $C_2$. 也即是说 $f_{w, b}(x)$ 代表着单个样本 $x$ 属于类别 $C_1$ 的概率,对应另一种情况 $1-f_{w, b}(x)$ 代表着单个样本属于类别 $C_2$ 的概率,由于我们已经知道训练数据中样本的类别,因此可以对应设计出上面的似然函数。

理想情况下的分类函数对于每个样本的类别预测都是绝对准确的,因此 $C_1$ 类样本 $f_{w, b}(x) = 1$, 而 $C_2$ 类样本 $f_{w, b}(x) = 0$, 对应 $1-f_{w, b}(x) = 1$. 由于独立抽样各个样本,因此整个训练数据抽样发生的概率可以表示为所有样本单次抽样发生的概率之积, 用上面的函数计算结果为 $1$.

我们需要找到最好的参数 $w^{\ast}$ 和 $b^{\ast}$ 估计实际可能存在的数据分布带来的抽样概率,它应当有着最大的可能性(似然) 去产生当前的训练数据。所以我们认为能够最大化上面这个似然概率的 $w$ 和 $b$ 就是根据训练数据所能找到的最好的 $w^{\ast}$ 和 $b^{\ast}$. 问题变成了:

为了使得计算方便,我们对似然函数取其负对数,问题等价于:

因此在这个问题中的似然函数由各项相乘变成了各项相加:

现在为了写成标准的求和形式,我们进行符号上的转换:如果某个 $x$ 属于类别 $1$, 则它的目标或者说实际值 $\hat{y}^n = 1$; 如果属于类别 $2$, 则 $\hat{y}^n = 0$. 此时负对数似然的式子可以改写为:

求和的项其实是两个伯努利分布之间的交叉熵(Cross Entropy), 一个是真实数据的分布 $p$, 另一个是我们通过参数估计得到的分布 $q$.

在信息论中,交叉熵代表两个分布之间多么接近,如果两个分布完全一样,计算得到的交叉熵 $H(p, q)=-\sum_{x} p(x) \ln (q(x))$ 应该为零。在 Logistic 回归中,我们需要最小化的对象是所有的样本的真实标签值 $\hat{y}^n$ 与估计值 $f(x^n)$ 的交叉熵之和,也即是说我们希望真实值和估计值的伯努利分布越接近越好。现在可能会留下一种疑惑:为什么我们要用交叉熵的概念来表示 Logistic 回归的损失,而不能像线性回归中简单使用平方误差来表示误差呢?

Logistic 回归模型形式为:

训练数据为很多个 $\left(x^{n}, \hat{y}^{n}\right)$, 且 $\hat{y}^{n}$ 值为 $0$ 或 $1$.

如果使用平方误差(而不是交叉熵) 做梯度下降,损失函数变成

为了更新参数,需要计算偏微分

这会导致一个问题:当某个样本的真实值 $\hat{y}^{n} = 1$ 且对应的估测值 $f_{w, b}(x^n) = 1$ 时,表明预测较为准确,此时代入上式有 $\partial L / \partial w_{i}=0$, 这种情况比较合理。但是如果估测值 $f_{w, b}(x^n) = 0$, 代入上式亦有 $\partial L / \partial w_{i}=0$, 这不太符合我们的期望。如果样本的真实值 $\hat{y}^{n} = 0$, 情况也与之类似。我们尝试给出一种解释:

图片来源:http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf

针对二分类问题,如果我们作出总体损失关于参数 $w_1$ 和参数 $w_2$ 的图象,黑色的是交叉熵,红色的是平方误差。交叉熵在距离理想参数很近的地方微分值很小,距离理想参数很远的地方很大。而此时平方误差在距离理想参数很远的地方,微分值也很小,显得非常平坦。

因此使用平方误差在参数距离理想目标很远时,参数更新会非常慢。如果随机找定参数的初始值,通常离目标参数非常远,这会导致梯度下降在这种所谓的鞍点(Saddle Point) 进行得很慢甚至卡住。当微分值很小时调高学习率或许是一种解决方案,但如果参数距离目标参数很近了,反而会适得其反,因为你根本不知道微分值小意味着在鞍点附近,还是在局部最小点附近。

梯度下降负对数似然损失

现在我们得到了一个可微的损失函数

其中

使用梯度下降的方法,我们来计算偏微分,以 $w_i$ 为例子:

其中

上面用到了 Sigmoid 函数的微分,可以直接记住结果 $ \sigma’(z)=\sigma(z)(1-\sigma(z))$,或推导:

因此可知

类似的推导过程,可以得到

因此经过整理最终有

通过繁琐的推导过程,我们得到了一个简洁的结果

对应梯度下降的更新规则为

其中 $\hat{y}^{n}-f_{w, b}\left(x^{n}\right)$ 表示了估计值与真实值的差距,可以发现差距越大参数更新的幅度也就越大。神奇之处在于,对比线性回归的梯度下降规则,通过计算你会发现它们的更新规则是一样的,唯一的区别在于 Logistic 回归的 $\hat{y}^{n}$ 一定是 $0$ 或 $1$, $f_{w, b}$ 一定介于 $0$ 和 $1$ 之间。

多分类问题与 Soft-max

假设有三个类别,每个类都有自己的权重和偏置参数,输入需要分类的 $x$, 进行如下计算:

这一步的输出 $z$ 可以是任何值,接下来将 $z_1,z_2,z_3$ 丢进 Soft-max 函数,得到输出

Soft-max 函数等于对 $z$ 进行了一个限制,其中一个作用就好像 Sigmoid 函数 $\sigma$ 将 $z$ 的输出限制在 $0$ 到 $1$ 之间以表示概率,另外满足了对于 $I$ 个类别可以有 $\sum_{i} y_{i}=1$, 这是因为分母起到了标准化(Normalization) 作用。由于取指数的原因,原本存在差异的值之间的差异会变得更大,起到了强化大小关系的作用,可以认为 $y_{i}=P\left(C_{i} | x\right)$, 即用 Soft-max 函数的输出来估计后验概率。

从概率的观点,假设数据来自高斯分布,且共用协方差矩阵,可以推导出为什么使用 Soft-max 函数。而从信息论的角度,则可以使用最大熵(Maximum Entropy) 模型进行推导,也可以得出 Soft-max 函数的具体形式。

在训练模型的时候,需要有真实值 $\hat{y}$ 作为目标,我们需要最小化 $y$ 分布与 $\hat{y}$ 分布之间的交叉熵 $-\sum_{i=1}^{3} \hat{y}_{i} \ln y_{i}$, 这个式子也可以通过极大似然估计得到。在线性回归用于分类的情况中我们提到,不能够直接用数值 $1$ 表示类别 $1$, 用数值 $2$ 表示类别 $2$, 用数值 $3$ 表示类别 $3$. 这样等同于假设类别 $1$ 和类别 $2$ 比较接近,类别 $2$ 和类别 $3$ 比较接近。使用下面的表示可以避免这种类别关系之间的假设:

这种编码形式叫作 One Hot 编码。

Logistic 回归的局限性

考虑上面的分类任务,由于 Logistic 回归在两个类别之间的边界就是一条直线,不论使用什么样的 $w$ 和 $b$, 都无法很好地对上面的点进行分类。如果坚持要使用 Logistic 回归,则需要进行特征转化(Feature Transformation), 找到一个比较好的特征空间对其进行表示。例如用 $x_{1}^{\prime}$ 表示点到 $\left[ \begin{array}{l}{0} \ {0}\end{array}\right]$ 的距离,用 $x_{2}^{\prime}$ 表示点到 $\left[ \begin{array}{l}{1} \ {1}\end{array}\right]$ 的距离,样本原来的特征便发生了转化 $\left[ \begin{array}{l}{x_{1}} \ {x_{2}}\end{array}\right] \rightarrow \left[ \begin{array}{l}{x_{1}^{\prime}} \ {x_{2}^{\prime}}\end{array}\right]$.

此时两个红色点会重合在一起,分类也变得简单了。问题在于这种特征转化关系并不是那么容易去寻找,如果人为地使用太多时间去寻找转化关系,则无法体现人工智能的智能,也无法体现机器在自动学习。因此我们希望有一种方法,可以让机器自己学出这种特征的转化关系。

一种改进策略是,将很多的 Logistic 回归拼接起来,不考虑偏置则是这样:

等同于让前面的两个 Logistic 回归进行了特征转化,如果用转换后的特征 $x_{1}^{\prime}$ 和 $x_{2}^{\prime}$ 表示出来的样本是线性可分的,就丢进新的 Logistic 回归模型中进行分类。对于更高维的特征,我们可以延续这种思想,将更多的 Logistic 回归前后拼接在一起,就可以处理更加复杂的变化。我们将其中的每个 Logistic 回归单元称为神经元(Neural), 多个神经元组合起来得到的模型就是神经网络模型。

这时你就可以向其它人吹嘘了,这个神经网络可以模拟人类大脑的工作!实际上,如果神经网络的结构很复杂,尤其是层数加深时,相应的研究领域就变成了深度学习(Deep Learning).