logistic回归:从生产到使用【下:生产篇】
上篇介绍了logistic模型的原理,如果你只是想使用它,而不需要知道它的生产过程,即拟合方法及编程实现,那么上篇就足够了。如果你想知道它的上游生产,那么请继续。
本篇着重剖析logistic模型的内部生产流程、以及每一个流程的工作原理,暴力拆解。
上下两篇的大纲如下:
【上篇:使用篇】
1. Logistic回归模型的基本形式
2. logistic回归的意义
(1)优势
(2)优势比
(3)预测意义
3. 多分类变量的logistic回归
(1)无序多分类logistic回归
(2)有序多分类:比例优势模型
(3)有序多分类:偏比例优势模型
4.附:Logistic回归模型建模指南
【下篇:生产篇】
1. 模型的拟合
(1)回归模型的拟合流程
(2)logistic回归的拟合
2. 代码实现
(1)Python
(2)SAS
(3)Matlab
1.模型的拟合
(1)回归模型的拟合流程
很多统计出身、尤其是经济统计出身的朋友,并不知道回归模型拟合的标准流程,只知道线性回归用最小二乘法。其实最小二乘问题、最小二乘法、极大似函数等,以及其他回归中用到的梯度下降算法、牛顿法等等,都是不同的东西,首先来看一下回归的一个标准拟合流程(点击查看大图):
下面结合大家都用过的的一元线性模型为例,走一遍这个流程:
- 选择模型
首先我们要对具体分析的问题选择一个模型,对于连续变量我们用线性模型,对于定性变量我们可以用logistic模型(什么情况下用logistic模型,它可以解决什么问题?在微信公众平台“数说工作室”中回复“logit1”查看,不要引号),不同的模型,它的目标函数,以及后面选择的优化算法都会不同。这里我们以最常见的一元线性模型为例:
Y=a bX
- 建立目标函数:
对于上面的例子,我们希望最终能得到这样的回归系数
:
使得由系数计算出来的 值与真实的y值之间差距绝对值最小,即
但其实,绝对值不便于后面的计算。在下一步“选择最优算法”的时候,要务实地考虑这个目标如何实现,绝对值不容易计算,我们用平方来代替:
这里,是的Q这个函数的值最小,就是我们的目标。Q就是目标函数。我们把目标变成一个求最小的问题,这个问题就是最小二乘问题。
对于logistic模型,我们的目标函数就不是最小二乘了,而是极大似然,其实它们之间不是对立的,最小二乘可以通过极大似然推导出来。这在后面会说。
- 选择最优算法
为了使得实现目标函数,即误差的平方最小,我们需要选择一个算法来实现。根据微积分,我们只需要把Q对a和b分别进行求导,另其导数为0,得出来的函数就是最小值(Q函数是二次函数,又是非负的)。因此这里我们就选择求导为0的方法,也就是一般来说的最小二乘法。
并不是所有的情况都可以通过求导来获得,例如当目标函数求导为0之后,求不出解析解,那么只能找其他的方法了,一般来说可以通过迭代的方法。这个后面也会说。
- 对目标函数进行优化
这里的“优化”当然就是“求最小”,我们使用求导为0的方法。
- 拟合出最优的回归系数
求解上一步中的两个导数为零的函数,最终解得:
(2)logistic回归的拟合
弄清楚了回归模型的拟合流程,现在我们看一下logistic模型是如何“生产”出来的。与线性模型相比,logistic很多方法不一样。
- 选择模型——logistic模型
不多说,我们现在需要构建一个因变量y(0=否/1=是),m个自变量的logistic模型(点击查看大图):
如果你对这些基本形式不是很熟悉,那我只能再啰嗦一遍了——在微信公众号“数说工作室”中回复logit1,查看上篇,有详细的解说。
- 建立目标函数——极大似然
Logistic的目标函数是极大似然函数,这是本【生产篇】的一个重头戏,我们要介绍极大似然的思想、logistic模型如何运用极大似然思想、以及极大似然与最小二乘之间的关系。
极大似然的思想如下:
假设我们有样本(X1,Y1),那么
当Y1=1时,这个样本发生的概率为
P{Y=1},
当Y1=0时,这个样本发生的概率为
P{Y=0}=1-P{Y=1}
它可以直接用一个式子来表达:
各位可以想一下是不是,当Y1=1时,等价于第一个式子,Y1=0时,等价于第二个式子。
这时有朋友会问了,
“(X1,Y1)不是样本吗,既然是样本,那就说明它是一个已经发生过了的历史数据,它发生的概率应该是100%呀!”
是的,因为
这个式子是logistic回归模型得出的、样本(X1,Y1)发生的概率,而实际上这个样本是已经发生过了的“历史事实”,正因此,我们要使这个式子得到的值尽可能的大到100%,以使得模型的情况能最贴近现实,所以,
就是最大似然函数,因为我们不止有一个样本,且样本之间是相互独立的,所以n个样本的发生概率就是这n个样本概率的乘积:
至此,我们建立了logistic的目标函数。
还没完,这里还有人问,
“为什么logistic的目标函数不能是最小二乘?而是最大似然?”
线性回归中,因变量Y是连续的,因此我们用拟合出来的
与真实之间的Y的差别平方作为目标函数,目标是使误差平方最小。而logistic模型,因变量Y是分类函数,比如0、1模型中我们计算的缺是Y的发生概率P{Y=0}、P{Y=1}。因此适合用最大似然。
实际上,最小二乘和极大似然并不对立。最小二乘是可以用极大似然推导出来的。
下面给出推导过程,不敢兴趣的可以直接跳过,知道两者相关就好了:
现在有回归模型,模型希望通过参数θ和若干自变量X拟合出因变量
,与真实之间的Y之间有误差:
e是误差项,服从正态分布(回归模型的经典假设):
因此有:
根据极大似然思想,我们希望拟合出来的参数θ,可以使Y这个“历史事实”发生的概率最高,这个目标函数为:
为了简化计算,我们取对数:
之所以简化,因为对于这两个单调函数来说,l(θ)=lnL(θ)达到最大时,L(θ)也达到最大。而让l(θ)最大,也就是让
取最小,这样就转化成了最小二乘的问题,回顾一下看是不是?
- 选择最优算法——梯度下降:
对于logistic的目标函数,我们可不可以再用求导为0的算法?答案是不行,不信?不信走两步——
首先需要取对数化简L(θ)(点击查看大图):
这里,
,下表i表示第i条数据。
用L(θ)对θ求导:
这时我们发现,求导之后令其等于0,是找不到关于θ的解析解的,你可以试一下。因此求导为0的这个算法失效。只能用计算机迭代搜索来找到最优的解了。
梯度下降(上升)算法,就是从一个初始状态出发,一点一点的搜索到全局的最小(最大)值,我们以梯度下降,搜索最小值为例:
这个思想可不可以用一个数学表达式表示呢?可以,假设我们的目标函数为J(θ)
先看一下迭代的思想,再具体说一下每个项都代表什么:
迭代就是这么进行的,这里θ会不断进行更新,直到达到局部最小值点。那么后面的更新项
是怎么来的呢?它什么可以使参数达到局部最小值?
Answer1:α是学习率,代表了每一次迭代的更新程度。α过大过小都不好,过小则参数收敛速度很慢,要很久才能达到最小值点;过大则很容易在极小值点出徘徊,步子太大了,老是走不到关键点上。
Answer2:
这个设计很妙,它起什么作用呢?
想象一下,当J(θ) 接近最小值的时候,它的曲线会变的非常平滑——斜率,也即J(θ) 导数的值,将会接近于0,那么更新将趋近于停滞。当达到最小值的时候,θ就会停止更新了。
现在梯度下降算法基本搞明白了,但是,这里我们是要最大化似然函数啊,应该求的是最大值啊。不错,logistic模型中我们应该使用梯度上升算法,和梯度下降算法的原理是一样的,比如,求J(θ) 的最大值,其实也就是求-J(θ) 的最小值,加个负号,就可以用梯度下降算法了。
因此这里,我们的目标函数实际是:
注意加了负号,因此我们可以使用梯度下降算法,迭代的数学表达式为:
梯度下降法在具体实践上,分为“批量梯度下降”和“随机梯度下降”:
批量梯度下降,是进行迭代时,使用所有的样本,正如上面的式子中有一个sigma求和函数,考虑的是所有样本。这个方法处理100个样本的数据还可以,如果有数十亿的样本数据,这个方法复杂度就太高了。
随机梯度下降,是迭代时,只用一个样本来更新,使用这个样本迭代完之后,再用下一个样本再更新迭代。那么上面的式子中就没有sigma求和函数了,不明白不要紧,下面的python代码中,会有一个图,来解释两者的区别。
2.代码实现
下面我们以一个名字为testSet.txt的数据为例,它的样子如下图:
第一行、第二行是自变量X1,X2,第三行作为因变量Y。该数据来源于《Machine Learining》这本书中,要数据的同学可以数说君(微信公众号“数说工作室”)。
(1)Python
首先看一下Python如何实现梯度下降的一轮迭代的:
对于批量梯度下降:
对于随机梯度下降:
以上就是批量梯度下降和随机梯度下降中,每一轮迭代的思想,以及Python实现。下面要写出具体的代码:
(2)SAS
直接把testSet.txt文件导入SAS,自变量命名Y,因变量命名X1,X2,X3...
——————————————
proc logistic desc data=a;
model Y=X1 X2;
run;
——————————————
注意SAS默认把数值较高的作为对照值,即Y=0、1时,SAS默认1值作为不发生的情况,0值作为发生的情况,而事实相反,因此应该把顺序换一下,使用descending关键句。
(3)Matlab
不多说,Python代码出来了,在Matlab中稍修改一下就可以,代码如下图。
只是,数说君发现Matlab和Python的计算结果差的蛮大的。排查了一下觉得应该不是程序问题,因为迭代的时,初始值一样,第一轮迭代计算没有差别,第二轮迭代计算,出现了小的差别,第三轮第四轮....后面的差别越来越大。有找到原因的同学可以加数说君微信(在微信公众号“数说工作室”)私聊。