(转载)【机器学习算法系列之二】浅析Logistic Regression

(原文:https://chenrudan.github.io/blog/2016/01/09/logisticregression.html)


【转载请注明出处】chenrudan.github.io

本文是受rickjin老师的启发,谈谈关于logistic regression的一些内容,虽然已经有珠玉在前,但还是做一下自己的总结。在查找资料的过程中,越看越觉得lr实在是博大精深,囊括的内容太多太多了,本文只能浅显的提到某些方面。文章的内容如下:

  • 1. 起源
  • 2. 模型介绍与公式推导
    • 2.1 Logistic Distribution
    • 2.2 Binomial logistic regression model
  • 3. 解法
    • 3.1 梯度下降法
    • 3.2 牛顿法
    • 3.3 BFGS
  • 4. 正则化
    • 4.1 过拟合
    • 4.2 正则化的两种方法
  • 5. 逻辑回归与其他模型关系
    • 5.1 逻辑回归与线性回归
    • 5.2 逻辑回归与最大熵
    • 5.3 逻辑回归与svm
    • 5.4 逻辑回归与朴素贝叶斯
    • 5.5 逻辑回归与能量函数
  • 6. 并行化
  • 7. 小结
  • 8. 引用

1. 起源

logistic regression的起源主要分为几个阶段,从开始想到logistic这个词,到发现logistic function,再推导出logit function,最后才命名logistic regression。这些过程都是大量的研究者们共同努力发现的,只是在历史的长河中,很多人被渐渐遗忘了。

logistic起源于对人口数量增长情况的研究,最重要的工作是Pierre François Verhulst在1838年提出了对人口增长的公式描述(这人是个比利时人,写的文章是法语的,一个字都看不懂,下面的内容都是看了一篇将研究人口数量增长发展历程的书[1]才知道的…),他博士毕业于根特大学的数学系,是个数学教授和人口学家。在1835年Verhulst的同乡人Adolphe Quetelet发表了一篇关于讨论人口增长的文章,文中认为人口不可能一直是几何(指数)增长,而会被与增长速度平方成比例的一种阻力而影响,但是这篇论文只有猜想没有数学理论基础,却极大的启发了Verhulst。因此在1838年Verhulst发表了关于人口数量增长的论文,就是在这篇论文里面他推导出了logistic equation,文章中谈到一个重要观点,随着时间的增加,一个国家的大小(我理解为资源)和这个国家人们的生育能力限制了人口的增长,人口数量会渐渐趋近一个稳定值。厉害的是他将这个过程用公式给描述出来了,他从人口数量增长的速度公式入手,即人口数量 P(t) P(t)对时间t的导数:

Pt=rP(1PK) ∂P∂t=rP(1−PK)

其中 K K就是他认为人口数量稳定的值,当 P(t) P(t)远小于 K K时,求导公式后一项约等于0,那么就变成了 PtrP ∂P∂t≃rP,这个阶段人口增长速度与人口数量和一个常数的乘积成正比,并且在渐渐变大。然后对这个式子求解一阶线性微分方程得到 P(t)P(0)ert P(t)≃P(0)ert。当 P(t) P(t)接近 K K时,人口增长速度开始渐渐变小,同样求解二阶微分方程(论文中是将二阶转化成一阶求解),然后将二者整合在一起得到最初的形式。

P(t)=P(0)ert1+P(0)(ert1)/K P(t)=P(0)ert1+P(0)(ert−1)/K

他将法国英国等过十几年的人口实际数据拿来跟这个公式对比之后发现确实拟合的很不错。但他当时并没有那么多年的数据,下图1是在他过世以后人们总结的300年来的人口增长分布,可以看到非常漂亮的拟合了logisitc分布的累积分布函数走势。但是当时这个公式并没有名字,直到1845年他发表了另外一篇重要文章[2],他给这个公式起了一个名字——“logistic”,此外在这篇文章中,他发现在$P(t)K/2 P(t)$呈凹增长(通过求二阶导来分析,这里略)。这个增长的趋势类似logistic分布的概率密度函数。

图1 比利时的人口增长数量图(图来源[2])

然而在后来的几十年内人们都没有意识到这个工作的重要性,很多人都独立的研究出了这个增长现象,直到1922年一个叫做Raymond Pearl的人口学家注意到Verhulst在1838年就已经提出了这个现象和公式,并在他的文章中也使用了logistic function来称呼它,并且沿用至今。在1920年Pearl[3]在研究美国人口增长规律时提出了另外一种表示logistic function的方法。

y=beax1+ceax y=beax1+ceax

基于这个表达式,Joseph Berkson在1944年提出了logit function, logit=In(1QQ) logit=In(1−QQ),假如 Q=11+eabx Q=11+ea−bx,结果就是 logit=abx logit=a−bx

后来,在1958年David Cox提出了logistic regression[4]。他的文章是为了解决这样一个问题,有一组取值为0,1的观测值,它们的取值 Yi Yi依赖于一些独立变量 xi xi, 当 Yi=1 Yi=1时对应的概率为 θi=pr(Yi=1) θi=pr(Yi=1)。由于 θi θi限制在[0,1]之间,因此假设 θi θi xi xi的关系符合logit function,即 logitθilogθi1θi=α+βxi logitθi≡logθi1−θi=α+βxi,文章主要在分析如何求解里面的参数 β β,这里就不提了。由于用到了logistic function,而这个问题本身又个回归问题(建立观测值与独立变量之间的关系),因而它被称呼为logistic regression。

貌似Cox在这篇文章中并不是刻意提出logistic regression,但确实这个词第一次出现就是在这篇文章中,虽然Cox之前已经有很多人做过这方面的研究了,但是他们没给个名字,因此Cox成了提出logistic regression的人。这个故事告诉我们一个道理,无论是发文章还是写软件一定要取一个言简意赅又好听又好记的名字…

以上是逻辑回归的历史发展中比较有代表性的几件事(我认为的…还有好多论文没时间细看…),J.S Cramer[5]在他的文章中有更加详细的讨论。它是由数学家对人口发展规律研究得出,后来又被应用到了微生物生长情况的研究,后来又被应用解决经济学相关问题,直到发展到今天作为一个非常重要的算法而存在于各行各业。逻辑回归作为Regression Analysis的一个分支,它实际上还受到很多Regression Analysis相关技术的启发,例如Berkson就是基于probit function提出的logit function。光它的起源到应用就能写一本书出来了,难怪rickjin老师说lr其实非常非常复杂…

2.模型介绍与公式推导

上面说过了逻辑斯蒂回归的起源,下面讨论一下完整的模型,首先介绍一下何为逻辑斯蒂分布,再由逻辑斯蒂分布推出逻辑回归。

2.1 Logistic Distribution

随机变量X服从逻辑斯蒂分布,即X的累积分布函数为上文提到过的logistic function。对分布函数求导得到了概率密度函数。公式如下,参数影响参考图2(图来自维基百科,它的参数s就是统计学习方法上的 γ γ)

F(x)=P(Xx)=11+e(xμ)/γ F(x)=P(X⩽x)=11+e−(x−μ)/γ

f(x)=F(x)=e(xμ)/γγ(1+e(xμ)/γ)2 f(x)=F′(x)=e−(x−μ)/γγ(1+e−(x−μ)/γ)2

图2 不同参数对logistic分布的影响(图片来源维基百科)

可以看到 μ μ影响的是中心对称点的位置, γ γ越小中心点附近增长的速度越快。而常常在深度学习中用到的非线性变换sigmoid函数是逻辑斯蒂分布的 γ=1,μ=0 γ=1,μ=0的特殊形式。

2.2 Binomial logistic regression model

图3 数据示例

逻辑回归是为了解决分类问题,根据一些已知的训练集训练好模型,再对新的数据进行预测属于哪个类。如图3所示,有一些属于两个类的数据,目标是判断圆圈属于哪一类。也就是说逻辑回归的目标是找到一个有足够好区分度的决策边界,从而能够将两类很好的分开。假设已经存在这样一个边界,针对于图中这种线性可分的情况,这条边界是
输入特征向量的线性组合,假设输入的特征向量为 xRn x∈Rn(图中输入向量为二维), Y Y取值为0,1。那么决策边界可以表示为 w1x1+w2x2+b=0 w1x1+w2x2+b=0,假如存在一个例子使得 hw(x)=w1x1+w2x2+b>0 hw(x)=w1x1+w2x2+b>0,那么可以判断它类别为1,这个过程实际上是感知机,即只通过决策函数的符号来判断属于哪一类。而逻辑回归需要再进一步,它要找到分类概率 P(Y=1) P(Y=1)与输入向量 x x的直接关系,然后通过比较概率值来判断类别,而刚好上文中的logit function能满足这样的要求,它令决策函数的输出值 wTx+b wTx+b等于概率值比值取对数 logP(Y=1|x)1P(Y=1|x) logP(Y=1|x)1−P(Y=1|x),求解这个式子得到了输入向量 x x下导致产生两类的概率为:

P(Y=1|x)=ewx+b1+ewx+b(1) P(Y=1|x)=ew⋅x+b1+ew⋅x+b(1)

P(Y=0|x)=11+ewx+b(2) P(Y=0|x)=11+ew⋅x+b(2)

其中 w w称为权重, b b称为偏置,其中的 wx+b w⋅x+b看成对 x x的线性函数。然后对比上面两个概率值,概率值大的就是x对应的类。有时候为了书写方便,会将 b b写入 w w,即 w=(w0,w1,,wn) w=(w0,w1,…,wn)其中 w0=b w0=b,并取 x0=1 x0=1。又已知一个事件发生的几率odds是指该事件发生与不发生的概率比值,二分类情况下即 P(Y=1|x)P(Y=0|x)=P(Y=1|x)1P(Y=1|x) P(Y=1|x)P(Y=0|x)=P(Y=1|x)1−P(Y=1|x)。取odds的对数就是上面提到的logit function, logit(P(Y=1|x))=logP(Y=1|x)1P(Y=1|x)=wx logit(P(Y=1|x))=logP(Y=1|x)1−P(Y=1|x)=w⋅x。从而可以得到一种对逻辑回归的定义,输出 Y=1 Y=1的对数几率是由输入 x x的线性函数表示的模型,即逻辑斯蒂回归模型(李航.《统计机器学习》)。而直接考察公式1可以得到另一种对逻辑回归的定义,线性函数的值越接近正无穷,概率值就越接近1;线性值越接近负无穷,概率值越接近0,这样的模型是逻辑斯蒂回归模型(李航.《统计机器学习》)。因此逻辑回归的思路是,先拟合决策边界(这里的决策边界不局限于线性,还可以是多项式),再建立这个边界与分类的概率联系,从而得到了二分类情况下的概率。这里有个非常棒的博文[6]推荐,阐述了逻辑回归的思路。

在推导多分类的问题时,是假设 wT1x+b1=P(Y=1|x)P(Y=K|x) w1Tx+b1=P(Y=1|x)P(Y=K|x) wT2x+b2=P(Y=2|x)P(Y=K|x) w2Tx+b2=P(Y=2|x)P(Y=K|x)…等,再推导出 P(Y=K|x)=11+K1k=1ewTkx P(Y=K|x)=11+∑k=1K−1ewkTx P(Y=1|x)=ewT1x1+K1k=1ewTkx P(Y=1|x)=ew1Tx1+∑k=1K−1ewkTx等。

有了上面的分类概率,就可以建立似然函数,通过极大似然估计法来确定模型的参数。设 P(Y=1|x)=hw(x) P(Y=1|x)=hw(x),似然函数为 [hw(xi)]yi[1hw(xi)](1yi) ∏[hw(xi)]yi[1−hw(xi)](1−yi),对数似然函数为

L(w)=i=1NlogP(yi|xi;w)=i=1N[yiloghw(xi)+(1yi)log(1hw(xi))](3) L(w)=∑i=1NlogP(yi|xi;w)=∑i=1N[yiloghw(xi)+(1−yi)log(1−hw(xi))](3)

3.解法

优化逻辑回归的方法有非常多[7],有python的不同实现[8],这里只谈谈梯度下降,牛顿法和BFGS。优化的主要目标是找到一个方向,参数朝这个方向移动之后使得似然函数的值能够减小,这个方向往往由一阶偏导或者二阶偏导各种组合求得。逻辑回归的损失函数是

minJ(w)=min1m[i=1myiloghw(xi)+(1yi)log(1hw(xi))](4) minJ(w)=min−1m[∑i=1myiloghw(xi)+(1−yi)log(1−hw(xi))](4)

先把 J(w) J(w) wj wj的一阶二阶偏导求出来,且分别用 g g H H表示。 g g是梯度向量, H H是海森矩阵。这里只考虑一个实例 yi yi产生的似然函数对一个参数 wj wj的偏导。

gj=J(w)wj=y(i)hw(x(i))hw(x(i))(1hw(x(i)))(x(i)j)+(1y(i))11hw(x(i))hw(x(i))(1hw(x(i)))x(i)j=(y(i)hw(x(i)))x(i)(5) gj=∂J(w)∂wj=y(i)hw(x(i))hw(x(i))(1−hw(x(i)))(−xj(i))+(1−y(i))11−hw(x(i))hw(x(i))(1−hw(x(i)))xj(i)=(y(i)−hw(x(i)))x(i)(5)

Hmn=2J(w)wmwn=hw(x(i))(1hw(x(i)))x(i)mx(i)n(6) Hmn=∂2J(w)∂wm∂wn=hw(x(i))(1−hw(x(i)))xm(i)xn(i)(6)

这几种方法一般都是采用迭代的方式来逐步逼近极小值,需要给定参数 w0 w0作为起点,并且需要一个阈值 ϵ ϵ来判断迭代何时停止。

3.1 梯度下降法

梯度下降是通过 J(w) J(w) w w的一阶导数来找下降方向,并且以迭代的方式来更新参数,更新方式为 wk+1j=wkj+αgj wjk+1=wjk+αgj k k为迭代次数。每次更新参数后,可以通过比较 ||J(wk+1)J(wk)|| ||J(wk+1)−J(wk)||或者 ||wk+1wk|| ||wk+1−wk||与某个阈值 ϵ ϵ大小的方式来停止迭代,即比阈值小就停止。

3.2 牛顿法

牛顿法的基本思路是,在现有极小点估计值的附近对f(x)做二阶泰勒展开,进而找到极小点的下一个估计值[9]。假设 wk wk为当前的极小值估计值,那么有

φ(w)=J(wk)+J(wk)(wwk)+12J′′(wk)(wwk)2(7) φ(w)=J(wk)+J′(wk)(w−wk)+12J″(wk)(w−wk)2(7)

然后令 φ(w)=0 φ′(w)=0,得到了 w=wkJ(wk)J′′(wk) w=wk−J′(wk)J″(wk)。因此有迭代更新式,

wk+1=wkJ(wk)J′′(wk)=wkH1kgk(8) wk+1=wk−J′(wk)J″(wk)=wk−Hk−1⋅gk(8)

此方法中也需要一个阈值 ϵ ϵ,当 ||gk||<epsilon ||gk||时停止迭代。此外,这个方法需要目标函数是二阶连续可微的,本文中的 J(w) J(w)是符合要求的。

3.3 BFGS

由于牛顿法中需要求解二阶偏导,这个计算量会比较大,而且有时目标函数求出的海森矩阵无法保持正定,因此提出了拟牛顿法。拟牛顿法是一些算法的总称,它们的目标是通过某种方式来近似表示森海矩阵(或者它的逆矩阵)。例如BFGS就是一种拟牛顿法,它是由四个发明人的首字母组合命名,是求解无约束非线性优化问题最常用的方法之一。目标是用迭代的方式逼近海森矩阵 H H,假设这个逼近值为 BkHk Bk≈Hk,那么希望通过计算 Bk+1=Bk+ΔBk Bk+1=Bk+ΔBk能够达到目的。并且假设 ΔBk=αuuT+βvvT ΔBk=αuuT+βvvT,而由3.2可知, Δw=wk+1wk=(H1)k+1(gk+1gk)=(H1)kΔg Δw=wk+1−wk=(H−1)k+1(gk+1−gk)=(H−1)kΔg,将 Bk+1 Bk+1的更新式代入,可以得到

Δg=BkΔg+(αuTΔw)u+(βvTΔw)v(9) Δg=BkΔg+(αuTΔw)u+(βvTΔw)v(9)

此处,直接令 αuTΔw=1 αuTΔw=1 βvTΔw=1 βvTΔw=−1 u=Δg u=Δg v=BkΔw v=BkΔw,那么可以求得 α=1(Δg)TΔw α=1(Δg)TΔw β=1(Δw)TBkΔw β=−1(Δw)TBkΔw。从而再代入求 ΔBk ΔBk的式子就可以得到更新的式子

ΔBk=Δg(Δg)T(Δg)TΔwBkΔw(Δw)TBk(Δw)TBkΔw(10) ΔBk=Δg(Δg)T(Δg)TΔw−BkΔw(Δw)TBk(Δw)TBkΔw(10)

这里还会对(10)进行变换,通过Sherman-Morrison公式直接求出 (B1)k+1 (B−1)k+1 (B1)k (B−1)k,用 Dk+1 Dk+1 Dk Dk来表。更新公式变成了

Dk+1=(IΔw(Δg)T(Δg)TΔw)Dk(IΔg(Δw)T(Δg)TΔw)+Δw(Δw)T(Δg)TΔw(11) Dk+1=(I−Δw(Δg)T(Δg)TΔw)Dk(I−Δg(Δw)T(Δg)TΔw)+Δw(Δw)T(Δg)TΔw(11)

用BFGS来更新参数的流程如下:

  1. 确定改变量, (Δw)k=Dkgk (Δw)k=−Dk⋅gk
  2. 更新参数, wk+1=wk+λ(Δw)k wk+1=wk+λ(Δw)k
  3. 求出 Δg=gk+1gk Δg=gk+1−gk
  4. 由(11)求出 Dk+1 Dk+1

式子的系数 λ=argminJ(wk+λ(Δw)k) λ=argminJ(wk+λ(Δw)k),即在求得下降方向上来从很多值中搜索最优的下降大小,这里我觉得可以用学习率替代。因此,这个更新方法跟牛顿法的区别是,它是在更新参数 w w之后更新一下近似森海矩阵的值,而牛顿法是在更新 w w之前完全的计算一遍森海矩阵。还有一种从计算上改进BFGS的方法称为L-BFGS,不直接存储森海矩阵,而是通过存储计算过程中产生的部分 Δw(g)km+1,km+2,,k Δw(g)k−m+1,k−m+2,…,k,从而减少了参数存储所需空间。

4.正则化

正则化不是只有逻辑回归存在,它是一个通用的算法和思想,所以会产生过拟合现象的算法都可以使用正则化来避免过拟合,在谈正则化之前先聊聊什么是过拟合。

4.1 过拟合

之前的模型介绍和算法求解可以通过训练数据集(图2中的三角形和星形)将分类模型训练好,从而可以预测一个新数据(例如图2中的粉色圆圈)的分类,这种对新数据进行预测的能力称为泛化能力。而对新数据预测的结果不好就是泛化能力差,一般来说泛化能力差都是由于发生了过拟合现象。过拟合现象是指对训练数据预测很好但是对未知数据预测不行的现象,通常都是因为模型过于复杂,或者训练数据太少。即当 complexityofthemodeltrainingsetsize complexityofthemodeltrainingsetsize比值太大的情况下会发生过拟合。模型复杂体现在两个方面,一是参数过多,二是参数值过大。参数值过大会导致导数非常大,那么拟合的函数波动就会非常大,即下图所示,从左到右分别是欠拟合、拟合和过拟合。

图4 同样数据下欠拟合,拟合和过拟合(图片来源[12])

在模型过于复杂的情况下,模型会学习到很多特征,从而导致可能把所有训练样本都拟合到,就像上图中一样,拟合的曲线将每一个点都正确的分类了。举个例子,假如要预测一个房子是贵还是便宜,房子的面积和所属的地区是有用的特征,但假如训练集中刚好所有贵的房子都是开发商A开发,便宜的都是开发商B开发,那么当模型变复杂能学习到的特征变多之后,房子是哪个开发商的会被模型认为是个有用特征,但是实际上这点不能成为判断的标准,这个现象就是过拟合。因此在这个例子中可以看到,解决的方法有两个,一个是减少学习的特征不让模型学到开发商的特征,一是增加训练集,让训练集有贵房子是B开发的样本。

从而,解决过拟合可以从两个方面入手,一是减少模型复杂度,一是增加训练集个数。而正则化就是减少模型复杂度的一个方法。

4.2 正则化的两种方法

由于模型的参数个数一般是由人为指定和调节的,所以正则化常常是用来限制模型参数值不要过大,也被称为惩罚项。一般是在目标函数(经验风险)中加上一个正则化项 Φ(w) Φ(w)

J(w)=1m[i=1myiloghw(x

你可能感兴趣的:(机器学习)