Python机器学习(原书第3版)
上QQ阅读APP看书,第一时间看更新

3.3 基于逻辑回归的分类概率建模

虽然感知器规则提供了良好且易用的入门级机器学习分类算法,但其最大缺点是,如果类不是完全线性可分的,那么它将永远不收敛。前一节的分类任务就是该场景的一个示例。直观地说,原因是权重在不断更新,因为每次迭代至少会有一个错误分类样本存在。当然,我们也可以改变学习速率,增加迭代次数,但是要小心感知器永远都不会在该数据集上收敛。

为了提高效率,现在让我们来看看逻辑回归,这是一种简单且强大的解决线性二元分类问题的算法。不要望文生义,逻辑回归是一种分类模型,但不是回归模型。

3.3.1 逻辑回归与条件概率

逻辑回归是一种很容易实现的分类模型,但仅在线性可分类上表现不错。它是行业中应用最广泛的分类算法之一。与感知器和Adaline类似,本章所介绍的逻辑回归模型也是一个用于二元分类的线性模型。

008-01

用于多元分类的逻辑回归

请注意,逻辑回归可以很容易地推广到多元分类,这被称为多项式逻辑回归或softmax回归。关于多项式逻辑回归的更详细的讨论超出了本书的范围,但是感兴趣的读者可以在我的讲稿中找到更多的信息(https://sebastianraschka.com/pdf/lecture-notes/stat479ss19/L05_gradient-descent_slides.pdf或http://rasbt.github.io/mlxtend/user_guide/classifier/SoftmaxRegression/)。

在多元分类设置中使用逻辑回归的另外一种方法是利用之前讨论过的OvR技术。

要解释作为概率模型的逻辑回归原理,首先要介绍让步比(odds),即某一特定事件发生的概率。让步比可以定义为055-01,p代表正事件的概率。正事件并不一定意味着好,它指的是要预测的事件,例如,病人有某种疾病的可能性;可以认为正事件的分类标签y=1。可以进一步定义logit函数,这仅仅是让步比的对数形式(log-odds):

055-02

注意log是自然对数,与计算机科学中的通用惯例一致。logit函数的输入值取值在0到1之间,并将其转换为整个实数范围的值,可以用它来表示特征值和对数概率(log-odds)之间的线性关系:

055-03

这里p(y=1|x)是给定特征x,某个特定样本属于类1的条件概率。

实际上,我们感兴趣的是预测某个样本属于某个特定类的概率,它是logit函数的逆函数。

这也被称为逻辑sigmoid函数,由于其特别的S形,有时简称为sigmoid函数或S形函数

056-01

其中z为净输入,是权重和样本特征的线性组合:

z=wTx=w0x0+w1x1+…+wmxm

008-01

注意,与第2章中用过的约定类似,w0代表偏置单元,是为x0提供的额外输入值,其值为1。

现在用-7到7之间的一些值简单地绘出sigmoid函数来观察具体的情况:

056-02

执行前面的示例代码,现在我们应该能看到S形曲线,如图3-2所示。

056-03

图 3-2

从图3-2可以看出,当z趋向无限大时(z→∞),ϕ(z)的值接近于1,因为当z值很大时,e-z的值会变得非常小。类似地,作为越来越大的分母,当z→∞时,ϕ(z)的值趋于0。因此得出这样的结论:sigmoid函数将以实数值作为输入,并在截距为ϕ(z)=0.5时转换为[0,1]范围内的值。

为了直观地理解逻辑回归模型,我们可以把它与第2章介绍的Adaline联系起来。在Adaline中,用恒等函数ϕ(z)=z作为激活函数。在逻辑回归中,只是简单地将前面定义的sigmoid函数作为激活函数。Adaline和逻辑回归的区别如图3-3所示。

057-01

图 3-3

sigmoid函数的输出则被解释为特定样本属于类1的概率,ϕ(z)=P(y=1|x;w),假设特征x被权重w参数化。例如,对于某种花的样本,计算出ϕ(z)=0.8,说明该样本属于Iris-versicolor的机会为80%。因此,该样本属于Iris-setosa的概率可以计算为P(y=0|x;w)=1-P(y=1|x;w)=0.2或者20%。预测概率可以通过阈值函数简单地转换为二元输出:

057-02

前面的sigmoid函数图等同于下述结果:

057-03

事实上,对于许多应用实践来说,我们不仅对预测分类标签感兴趣,而且对估计类成员概率也特别有兴趣(应用阈值函数之前sigmoid函数的输出)。例如,天气预报用逻辑回归不仅能预测某天是否会下雨,而且还能预报下雨的可能性。同样,可以用逻辑回归来预测病人有特定疾病某些症状的机会,这就是逻辑回归在医学领域备受欢迎的原因。

3.3.2 学习逻辑代价函数的权重

学习了如何使用逻辑回归模型来预测概率和分类标签,现在简要讨论一下如何拟合模型的参数(例如前一章的权重w)上一章代价函数定义为误差平方和:

058-01

为了在Adaline分类模型中学习权重w,我们简化了函数。要解释清楚如何得到逻辑回归的代价函数,在建立逻辑回归模型时,需要首先定义最大似然函数L,假设数据集中的每个样本都是相互独立的。公式为:

058-02

在实践中,很容易最大化该方程的自然对数(求其最大值),故定义了对数似然函数:

058-03

首先,应用对数函数降低数值下溢的可能性,这种情况在似然率非常小的情况下可能发生。其次,假如你还记得微积分的话,可以把因子乘积转换成因子求和,这样就可以通过加法技巧更容易地得到该函数的导数。

现在可以用梯度上升等优化算法最大化这个对数似然函数。另外一个选择是改写对数似然函数作为代价函数J,就像在第2章中那样,用梯度下降方法最小化代价函数J:

058-04

为了能更好地理解这个代价函数,让我们计算一个训练样本的代价:

J(ϕ(z),y;w)=-ylog(ϕ(z))-(1-y)log(1-ϕ(z))

从上面的方程可以看到,如果y=0,第一项为零,如果y=1,第二项为零:

058-05

通过下述简短的代码绘制一张图,以说明对于不同的ϕ(z)值,分类一个训练样本的代价:

058-06

图3-4绘制了0到1范围内(sigmoid函数的输入值z的范围为-10到10),x轴的sigmoid激活函数y轴是相关联的逻辑代价。

059-01

图 3-4

从图3-4可以看到,如果正确地预测样本属于类1,代价就会接近0(实线)。类似地,可以在y轴上看到,如果正确地预测y=0(虚线),那么代价也接近0。然而,如果预测错误,代价就会趋于无穷大。关键就在于用越来越大的代价惩罚错误的预测。

3.3.3 将Adaline实现转换为一个逻辑回归算法

如果要自己动手实现逻辑回归,可以直接用新的代价函数取代第2章Adaline实现中的代价函数J:

059-02

在对训练样本进行分类的过程中,用该公式来计算每次迭代的代价。另外,需要用sigmoid激活函数替换线性激活函数,同时改变阈值函数,返回类标签0和1,而不是返回-1和1。如果能在Adaline编码中完成这三步,即可获得下述逻辑回归的代码实现:

059-03
060-01

当拟合逻辑回归模型时,必须记住该模型只适用于二元分类。

所以,只考虑Iris-setosaIris-versicolor两种花(类0和类1),并验证逻辑回归的有效性:

061-01

运行上述代码可以绘制如图3-5所示的决策区域图。

061-b1

图 3-5

008-01

逻辑回归的梯度下降学习算法

应用微积分可以发现,梯度下降逻辑回归过程中的权重更新相当于第2章讨论Adaline时用过的方程。但是要注意的是,下面的梯度下降学习规则推导是为那些对逻辑回归梯度下降学习规则的原理感兴趣的读者而准备的,并非学习本章其余部分的必要条件。

首先从计算对数似然函数的偏导数开始:

061-02

在继续我们的讨论之前,先计算sigmoid函数的偏导数:

061-03

现在可以在第一个等式中替换061-04,得到下列等式;

062-01

记住,目的是要找出可以最大化对数似然的权重,这样我们就可以通过下列方式更新每个权重:

062-02

因为要更新所有的权重,所以把通用的更新规则表达如下:

w:=ww

我们把Δw定义为:

Δw=η▽l(w

由于最大化对数似然相当于最小化前面定义的代价函数J,因此,可以得到下述梯度下降更新规则:

062-03

这与第2章中的Adaline梯度下降规则相同。

3.3.4 用scikit-learn训练逻辑回归模型

前一小节我们刚讨论了实用的代码以及相关的数学计算,这有助于解释Adaline与逻辑回归概念之间的差异。现在来学习如何用scikit-learn或者更优化的逻辑回归来实现,我们也默认支持多元分类的场景。请注意,在scikit-learn的新版中,将会自动选择多元分类、多项式或者OvR技术。我们将在下面的代码示例中用sklearn.linear_model.LogisticRegression类以及熟悉的fit方法,在三种花的标准化训练数据集上训练模型。同时,为了方便解释,我们将设置multi_class='ovr'。读者可能想与把参数定义为multi_class='multinomial'的结果进行对比。请注意,multinomial设置通常推荐用于排他性分类,比如鸢尾花数据集中出现的那些。在这里,“排他”意味着每个训练样本只能属于某类(多元分类的训练样本可以属于多个类)。

现在,让我们看看下面的示例代码:

062-04

在训练数据上拟合模型后,上述代码把决策区域、训练样本和测试样本绘制出来,如图3-6所示。

063-02

图 3-6

008-01

请注意,目前有许多不同的优化算法用于解决优化问题。为了最小化凸损失函数,如逻辑回归的损失,我们建议用比常规随机梯度下降(SGD)更先进的方法。实际上,scikit-learn实现了一系列这样的优化算法,可以通过解算器参数'newton-cg''lbfgs''liblinear''sag''saga'来指定调用这些算法。

当逻辑回归损失呈凸点时,大多数优化算法应该很容易收敛到全局损失的最小点。但是,某些算法有一定的相对优势。例如,当前版本(v 0.21)中的scikit-learn,以'liblinear'作为解算器的默认值,无法处理多项式损失,而且局限于多元分类的OvR。但是,scikit-learn的未来版本(即v 0.22),将默认解算器变为更灵活的'lbfgs',代表内存受限的BFGS(Broyden-Fletcher-Goldfarb-Shanno)算法(https://en.wikipedia.org/wiki/Limited-memory_BFGS)。为了采用这个新的默认选择,本书在使用逻辑回归时将显式地指定solver='lbfgs'

看到前面用来训练逻辑回归模型的示例代码,你可能会想:“这个神秘的参数C到底是什么呢?”下一节,我们将先介绍过拟合和正则化的概念,然后再讨论该参数。在此之前,我们先讨论一下类成员的概率问题。

可以用predict_proba计算训练数据集中某个样本属于某个特定类的概率。例如,可以用如下方法预测测试数据集中前三类的概率:

063-03

执行这段代码会返回如下数组:

064-01

第一行对应属于第一种花的概率,第二行对应属于第二种花的概率,以此类推。注意,所有列数据之和为1(可以通过执行lr.predict_proba(X_test_std[:3, :]).sum(axis=1)来确认)。

第一行的最大值约为0.85,这意味着第一个样本属于第三种花(Iris-virginica)的预测概率为85%。你可能已经注意到,我们可以通过识别每行中最大列的值得到预测的分类标签,例如可以用NumPy的argmax函数实现:

064-02

执行该调用返回对应于Iris-virginicaIris-setosaIris-setosa的分类结果:

064-03

在前面的代码示例中,我们计算了条件概率,并用NumPy的argmax函数将其手动转换为分类标签。实际上,在用scikit-learn时,获得分类标签更方便的方法是直接调用predict方法:

064-04

最后提醒一句,如果想单独预测花样本的分类标签:sciki-learn期望输入一个二维数组,因此,必须先把单行转换成这种格式。调用NumPy的reshape方法增加一个新维度可以将一行数据转换成为二维数组,代码如下:

064-05

3.3.5 通过正则化解决过拟合问题

过拟合是机器学习中的常见问题,虽然模型在训练数据上表现良好,但不能很好地泛化未见过的新数据或测试数据。如果某个模型出现了过拟合问题,我们会说该模型有高方差,这有可能是因为相对于给定的数据,参数太多,从而导致模型过于复杂。同样,模型也可能会出现欠拟合(高偏差)的情况,这意味着模型不足以捕捉训练数据中的复杂模式,因此对未知数据表现不佳。

虽然迄今我们只遇到过线性分类模型,但是比较线性决策边界和更复杂的非线性决策边界,是解释过拟合与欠拟合问题的最好方法,如图3-7所示。

064-06

图 3-7

008-01

偏差-方差权衡

研究人员经常用术语“偏置”和“方差”或“偏置-方差权衡”来描述模型的性能,也就是说,你可能偶然会在谈话、书籍或文章中发现人们提到模型具有“高方差”或“高偏置”。那么,这是什么意思?一般来说,我们可以说“高方差”与过拟合成正比,“高偏置”与欠拟合成正比。

在机器学习模型的场景中,如果我们多次重复训练一个模型,例如在训练数据集的不同子集上,方差可以用于测量模型对特定样本进行分类时预测结果的一致性(或可变性)。可以说,模型对训练数据中的随机性很敏感。相比之下,偏置测量的是,假如在不同的训练数据集上反复建模,预测值离正确值有多远;偏置测量的是非随机性引起的系统误差。

如果你对术语“偏置”和“方差”的技术规范和推导感兴趣,可以从下面网站获取我的课堂讲义:https://sebastianraschka.com/pdf/lecture-notes/stat479fs18/08_eval-intro_notes.pdf

找到一个好的偏置-方差权衡的方法是通过正则化来调整模型的复杂性。正则化是处理共线性(特征间的高相关性)、滤除数据中的噪声并最终防止过拟合的一种非常有用的方法。

正则化背后的逻辑是引入额外的信息(偏置)来惩罚极端的参数值(权重)。最常见的正则化是所谓的L2正则化(有时也称为L2收缩或权重衰减),可写作:

065-01

这里λ为所谓的正则化参数

008-01

正则化与特征归一化

特征缩放(如标准化)之所以重要,其中一个原因就是正则化。为了使得正则化起作用,需要确保所有特征的衡量标准保持统一。

通过增加一个简单的正则项,就可以正则化逻辑回归的代价函数,这将在模型训练的过程中缩小权重:

065-02

通过正则化参数λ,保持权重较小时,我们可以控制模型与训练数据的拟合程度。加大λ值可以增强正则化的强度。

scikit-learn实现LogisticRegression类的参数C来自下一节要介绍的支持向量机中的约定。C是正则化参数λ的倒数,与λ直接相关。因此,减小逆正则化参数C意味着增加正则化的强度,这可以通过绘制对两个权重系数进行L2正则化后的图像予以展示:

065-03
066-01

通过执行上面的代码,我们用不同的逆正则化参数C值拟合10个逻辑回归模型。为了方便讲解,我们只收集分类标签为1的权重系数(这里对应数据集中的第2类,即Iris-versicolor)而不是所有类,记住我们使用OvR技术进行多元分类。

如图3-8所示,如果减小参数C,即增加正则化的强度,那么权重系数会缩小。

066-02

图 3-8

008-01

其他关于逻辑回归的资源

由于深入讨论各种分类算法超出了本书的范围,我强烈建议读者阅读斯科特·梅纳德博士2009年的书籍Logistic Regression: From Introductory to Advanced Concepts and Applications,以了解更多关于逻辑回归方面的知识。