第六章:逻辑回归(Logistic Regression)
其中第五章是一些软件教程,这里就跳过了,继续跟着吴恩达老师学习接下来的内容。
6.1 分类问题
在分类问题中,你要预测的变量是离散的值,我们将学习一种叫做逻辑回归(Logistic Regression)的算法,这是目前最流行使用最广泛的一种学习算法。
在分类问题中,我们尝试预测的是结果是否属于某一个类(例如正确或错误)。分类问题的例子有:判断一封电子邮件是否是垃圾邮件;判断一次金融交易是否是欺诈;之前我们也谈到了肿瘤分类问题的例子,区别一个肿瘤是恶性的还是良性的。
我们从二元的分类问题开始讨论。
我们将因变量(dependent variable)可能属于的两个类分别称为负向类(negative class)和正向类(positive class),则因变量,其中表示负向类,表示正向类。
如果我们要用线性回归算法来解决一个分类问题,对于分类,取值为或者是1,但是如果你使用的是线性回归,出来的结果就会是连续型的,那么假设函数的输出值可能远大于,或者远小于,但是如果算法得到的值远大于或者远小于的话,就会感觉很奇怪。所以我们在接下来的要研究的算法就叫做逻辑回归算法,这个算法的性质是:它的输出值永远在到之间。
顺便说一下,逻辑回归算法是分类算法,我们将它作为分类算法使用。有时候可能因为这个算法的名字中出现了“回归”使你感到困惑,但逻辑回归算法实际上是一种分类算法,它适用于标签取值离散的情况,如:。
6.2 假说表示
接下来,我要给你展示假设函数的表达式,也就是说,在分类问题中,要用什么样的函数来表示我们的假设。此前我们说过,希望我们的分类器的输出值在和之间,因此,我们希望想出一个满足某个性质的假设函数,这个性质是它的预测值要在和之间。
回顾在一开始提到的乳腺癌分类问题,我们可以用线性回归的方法求出适合数据的一条直线:
根据线性回归模型我们只能预测连续的值,然而对于分类问题,我们需要输出或,我们可以预测:当时,预测,当时,预测。
对于上图所示的数据,这样的一个线性模型似乎能很好地完成分类任务。假使我们又观测到一个非常大尺寸的恶性肿瘤,将其作为实例加入到我们的训练集中来,这将使得我们获得一条新的直线。
这时,再使用来作为阀值来预测肿瘤是良性还是恶性便不合适了。可以看出,线性回归模型,因为其预测的值可以超越的范围,并不适合解决这样的问题。
因此,我们引入一个新的模型,逻辑回归,该模型的输出变量范围始终在和之间。逻辑回归模型的假设是:其中:代表特征向量,代表逻辑函数,是一种常用的S形函数(Sigmoid function),其公式为,该函数的图像为:
python代码实现:
import numpy as np
def sigmoid(z):
return 1 / (1 + np.exp(-z))
的作用是,对于给定的输入变量,根据选择的参数计算输出变量的可能性,即
例如,如果对于给定的,通过已经确定的参数计算得出,则表示有%的几率为正向类,相应地为负向类的几率为
6.3 判定边界
现在讲下决策边界(decision boundary)的概念。这个概念能更好地帮助我们理解逻辑回归的假设函数在计算什么。
现在对于logistic regression,我们已知的有:
在逻辑回归中,我们预测:
当时,预测;当时,预测。
根据上面绘制出的S形函数图像,我们知道当:
时;时;时
又因为,即:时,预测;时,预测
现在假设我们有一个模型:
并且参数是向量。则当,则时,模型将预测。我们绘制直线,这条线便是我们模型的分界线,将预测为的区域和预测为区域分隔开。
上图中间那条线就是分界线,就是判定边界。
那么现在又有一个问题了,假使我们的数据呈现下图的分布情况,怎样的模型才能适合呢?
上图很明显,分界线是需要用曲线才能分隔的区域和的区域,我们需要二次方特征:,其中,则我们得到的判定边界恰好是圆点在圆点且半径为的圆形。
我们可以用非常复杂的模型来适应非常复杂形状的判定边界。
6.4 代价函数
接下来,就要介绍如何拟合逻辑回复模型的参数。具体来说,我要定义用来拟合参数的优化目标或者叫代价函数,这便是监督学习问题中的逻辑回归模型的拟合问题。
对于线性回归模型,我们定义的代价函数是所有模型误差的平方和。理论上来说,我们也可以对逻辑回归模型沿用这个定义,但是问题在于,当我们将带入这样定义了的代数函数中时,我们得到的代价函数是一个非凸函数。
这意味着我们的代价函数有许多局部最小值,这将影响梯度下降算法寻找全局最小值。
线性回归的代价函数为:,其中
与之间的关系如下图所示:
这样构建的函数的特点是:当实际的且也为时误差为,当但不为时误差随着变小而变大;当实际的且也为时代价为,当但不为时误差随着的变大而变大。
将构建的简化如下:
代入代价函数得到:
即
python代码实现:
import numpy as np
def cost(theta, X, y):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(-y, np.log(sigmoid(X* theta.T)))
second = np.multiply((1 - y), np.log(1 - sigmoid(X* theta.T)))
return np.sum(first - second) / (len(X))
在得到这样一个代价函数以后,我们便可以用梯度下降算法来求得能使代价函数最小的参数了。算法为:
在这个视频中,我们定义了单训练样本的代价函数,凸性分析的内容是超出这门课的范围的,但是可以证明我们所选的代价值函数会给我们一个凸优化问题。代价函数会是一个凸函数,并且没有局部最优值。
推导过程:
注:虽然得到的梯度下降算法表面上看上去与线性回归的梯度下降算法一样,但是这里的
与线性回归中不同,所以实际上是不一样的。另外,在运行梯度下降算法之前,进行特征缩放依旧是非常必要的。
一些梯度下降算法之外的选择:除了梯度下降算法以外,还有一些常被用来令代价函数最小的算法,这些算法更加复杂和优越,而且通常不需要人工选择学习率,通常比梯度下降算法要更加快速。这些算法有:共轭梯度(Conjugate Gradient),局部优化法(Broyden fletcher goldfarb shann,BFGS)和有限内存局部优化法(LBFGS)。
6.5 简化的成本函数和梯度下降
下面,我们将会找出一种稍微简单一点的方法来写代价函数,来替换我们现在用的方法。同时我们还要弄清楚如何运用梯度下降法,来拟合出逻辑回归的参数。因此,看了以下内容,你就应该知道如何实现一个完整的逻辑回归算法。
下面是逻辑回归的代价函数:
这个式子可以合并成:
即,逻辑回归的代价函数
根据这个代价函数,为了拟合出参数,该怎么做呢?我们要试图找让取得最小值的参数。
如果我们给出一个新的样本,假如某个特征,我们可以用拟合训练样本的参数,来输出对假设的预测。
另外,我们假设的输出,实际上就是这个概率值:,就是关于以为参数,的概率,你可以认为我们的假设就是估计的概率,所以,接下来就是弄清楚如何最大限度地最小化代价函数,作为一个关于的函数,这样我们才能为训练集拟合出参数。
最小化代价函数的方法,是使用梯度下降法(gradient descent)。这是我们的代价函数:
如果我们要最小化关于的函数值,这就是我们通常用的梯度下降法的模板
我们要反复更新每个参数,用这个式子来更新,就是用它自己减去学习率乘以后面的微分项。求导后可得:,我们就可以将梯度下降算法写作是这个形式了。
所以,如果你有n个特征,也就是说:,你就需要用到式子来同时更新所有的值。
现在,如果你把这个更新规则和我们之前用在线性回归上的进行比较的话,你会惊讶地发现,这个式子正是我们用来做线性回归梯度下降的。
那么,线性回归和逻辑回归是同一个算法吗?要回答这个问题,我们要观察逻辑回归看看发生了哪些变化。实际上,假设的定义发生了变化。
对于线性回归假设函数:
而现在逻辑回归假设函数:
因此,即使更新参数的规则看起来基本相同,但由于假设的定义发生了变化,所以逻辑函数的梯度下降,跟线性回归的梯度下降实际上是两个完全不同的东西。
在之前的讲解中,当我们在谈论线性回归的梯度下降法时,我们谈到了如何监控梯度下降法以确保其收敛,我通常也把同样的方法用在逻辑回归中,来监测梯度下降,以确保它正常收敛。
当使用梯度下降法来实现逻辑回归时,我们有这些不同的参数,就是一直到,我们需要用这个梯度下降表达式来更新这些参数,然后把参数代入到代价函数中,得到。
最后还有一点,我们之前在谈线性回归时讲到的特征缩放,我们看到了特征缩放是如何提高梯度下降的收敛速度的,这个特征缩放的方法,也适用于逻辑回归。如果你的特征范围差距很大的话,那么应用特征缩放的方法,同样也可以让逻辑回归中,梯度下降收敛更快。
就是这样,现在你知道如何实现逻辑回归,这是一种非常强大,甚至可能世界上使用最广泛的一种分类算法。
6.6 高级优化
接下来,会讲一些高级优化算法和一些高级的优化概念,利用这些方法,我们就能够使通过梯度下降,进行逻辑回归的速度大大提高,而这也将使算法更加适合解决大型的机器学习问题,比如,我们有数目庞大的特征量。现在我们换个角度来看什么是梯度下降,我们有个代价函数而我们想要使其最小化,那么我们需要做的是编写代码,当输入参数时,它们会计算出两样东西:以及等于直到时的偏导数项。然后梯度下降所做的就是反复执行找出最优参数和最小J(\theta )。
然而梯度下降并不是我们可以使用的唯一算法,还有其他一些算法,更高级、更复杂。如果我们能用这些方法来计算代价函数和偏导数项两个项,那么这些算法就是为我们优化代价函数的不同方法,共轭梯度法、BFGS (变尺度法)和L-BFGS (限制变尺度法)。就是其中一些更高级的优化算法,它们需要有一种方法来计算,以及需要一种方法计算导数项,然后使用比梯度下降更复杂的算法来最小化代价函数。
6.7 多类别分类:一对多
先看一个例子:假如说你现在需要一个学习算法能自动地将邮件归类到不同的文件夹里,或者说可以自动地加上标签,那么,你也许需要一些不同的文件夹,或者不同的标签来完成这件事,来区分开来自工作的邮件、来自朋友的邮件、来自家人的邮件或者是有关兴趣爱好的邮件,那么,我们就有了这样一个分类问题:其类别有四个,分别用来代表。
对于之前的二元分类问题,我们的数据看起来可能是下图那样的。
对于一个多类分类问题,我们的数据集或许看起来像这样:
我用3种不同的符号来代表3个类别,问题就是给出3个类型的数据集,我们如何得到一个学习算法来进行分类呢?
我们现在已经知道如何进行二元分类,可以使用逻辑回归,对于直线或许你也知道,可以将数据集一分为二为正类和负类。用一对多的分类思想,我们可以将其用在多类分类问题上。
下面将介绍如何进行一对多的分类工作,有时这个方法也被称为"一对余"方法。
现在我们有一个训练集,好比上图表示的有个类别,我们用三角形表示,方框表示,叉叉表示。我们下面要做的就是使用一个训练集,将其分成个二元分类问题。
我们先从用三角形代表的类别开始,实际上我们可以创建一个,新的"伪"训练集,类型和类型定为负类,类型设定为正类,我们创建一个新的训练集,如下图所示的那样,我们要拟合出一个合适的分类器。
这里的三角形是正样本,而圆形代表负样本。可以这样想,设置三角形的值为,圆形的值为,下面我们来训练一个标准的逻辑回归分类器,这样我们就得到一个正边界。
为了能实现这样的转变,我们将多个类中的一个类标记为正向类,然后将其他所有类都标记为负向类,这个模型记作.。接着,类似地第我们选择另一个类标记为正向类,再将其它类都标记为负向类,将这个模型记作,以此类推。
最后我们得到一系列的模型简记为:其中:
最后,在我们需要做预测时,我们将所有的分类机都运行一遍,然后对每一个输入变量,都选择最高可能性的输出变量。
总之,我们已经把要做的做完了,现在要做的就是训练这个逻辑回归分类器:,其中对应每一个可能的,最后,为了做出预测,我们给出输入一个新的值,用这个做预测。我们要做的就是在我们三个分类器里面输入,然后我们选择一个让最大的。
你现在知道了基本的挑选分类器的方法,选择出哪一个分类器是可信度最高效果最好的,那么就可认为得到一个正确的分类,无论值是多少,我们都有最高的概率值,我们预测就是那个值。这就是多类别分类问题,以及一对多的方法,通过这个小方法,你现在也可以将逻辑回归分类器用在多类分类的问题上。