阅读 534

【打破砂锅问到底】你说的那个逻辑回归,它有逻辑吗

找着找着工作就发现算法这东西平常只学了个皮毛,面试官问的深一点就啥都不会了,所以在这里把看过的学过的全部仔细打磨一遍,刨根问底,因为总有一些东西是平常书上或者博客上没有仔细写一笔带过的,而亲爱的面试官就喜欢问这些一笔带过的,反正就是得先会从头到尾造个火箭,你才能进来拧螺丝。

这里写的东西基本上是给自己做个总结,因为我记性不好过一阵不用肯定就忘,所以不会上来就罗列公式,那样我自己都看不下去。但是也不会不涉及公式,因为面试官就是要你手推公式啊喂!所以我会尽量用相互融合的方式把算法的道理讲清楚,也把公式弄明白。

*引言

假设我们拿到了一家大厂的offer,然后为了看看真实的工资情况我们找神奇的海螺获取到了公司的很多员工的工资,可是光看也看不出什么,这时我们听到HR说工资和工龄以及绩效有关,恰好神奇的海螺又给了我们这些员工的工龄和绩效。这下我们可就开心了,我们隐约觉得好像可以用个什么科学的方法把我们未来的工资算出来,然后就升职加薪排队出现在我们面前了……等等,这只有工资,升职又是靠什么呢?神奇的海螺感觉到了我们的疑问,又给了我们这些员工的升职情况。嗯,拿着手里沉甸甸的数据,看着海螺远去的背影,我们知道升职和加薪的秘密就在我们手中了。

*线性回归

我们先从线性回归说起,因为这个逻辑回归是线性模型,无论如何也是绕不过线性回归的。我们拿到手的数据显然应该是这样

工资 工龄 绩效
5k 2 3.5
10k 5 3.5
15k 6 3.75
…… …… ……

我们把工资视为y,工龄和绩效视为{x}_{1}x_2,如果使用线性方程表示的话有

y=f(x)=\omega_1x_1+\omega_2x_2+b

写的更一般一点

y=f(x)=\omega^Tx_i+b

这里的\omegax就都是向量形式了。那么我们有了这样的一个方程(其实就是模型),我们需要知道的是里面的参数\omegab该如何求出。等等,都已经是向量了,我们为什么不把b写进参数\omega中呢?我们人为的对数据增加一列,即

工资 工龄 绩效 无实义
5k 2 3.5 1
10k 5 3.5 1
15k 6 3.75 1
…… …… …… 1

然后把b收入\omega中,就有

\omega=(\omega_1,\omega_2,\omega_3,…,\omega_n)^T 这里的\omega_n=b

然后对于x就是

X=(X_1,X_2,X_3,…,X_n)

那么模型就可以表示为

\hat{y}=X\cdot\omega

现在考虑如何求呢\omega?我们假设我们已知了一个参数向量\omega,那么我们起码知道如何评价它————也就是看他算的准不准。我们用我们真实的工资y来和模型的输出\hat{y}做一个对比,要是差的不多就说明他好,差的多就说明不好。那么我们选均方根误差作为这个评价函数(也就是损失函数),有

L=\sum_{i=1}^{m} (y_i-\hat{y})^2

我们发现选MSE作为损失函数的话就可以把预测值与真值之间的差转换到[0,+\infty),那显然这个结果越接近0就越好。所以不妨我们把损失函数展开,就有

(ps,这里不知道会不会有面试官怼人问为什么MSE不用MAE,这应该和MAE不处处可导有关,延申下去可能还有L1和L2范数,以及为什么L1有稀疏作用……能够牵出太多了,标记一下下次解释)

L(y,X)=(y-X\omega)^T(y-X\omega)

再展开有

L(y,X)=\omega^TX^TX\omega-2(X\omega)^Ty+y^Ty

求个导数

\frac{\partial L}{\partial \omega}=2X^TX\omega-2X^Ty

令他们等于零得到

\omega^*=(X^TX)^{-1}X^Ty

于是我们知道了参数\omega如何计算,有了参数,也就有了模型,我们的线性模型就这样出来啦。
我们小小总结一下线性回归的这一套流程。①我们先定了模型的样式(线性的),②然后就知道了我们需要求出的参数是什么(\omega),③接下来我们找了一个评价函数用于评价我们的模型到底好不好(MSE),④把我们的模型带入MSE里面,通过数学的方式解出了我们的参数,从而完成了我们的模型。

是不是感觉有点轻松哈,这么容易一个模型就被我们算出来了,总算知道那些专攻数学的人的快感在哪里了。都不用做实验,通过证明就直接宣告了结论的正确

*逻辑回归

该开始上硬菜了,现在我们知道我们的薪资了,那我们什么时候升职呢?假设我们拿到的数据是这样的

一年内是否升职 工龄 绩效
2 3.5
5 3.5
6 3.75
…… …… ……

那我们怎么去算我们一年之内升职的概率呢?不如照葫芦画瓢先来一套线性回归,那么我们先上一个线性方程吧。等等,不太对,我们如果要用线性方程去拟合我们一年之内是否升职的概率,那么我们的数据的第一列应该是一年内升职的概率,而不是一个确定的结果。那咋办呢?而我们的模型要输出概率,我们得到的最终结果却是结果,那又要怎么将这两个结合从而评价我们的模型呢?我们这里用一个sigmoid函数来帮助我们。

Sigmoid=\theta(z)=\frac{1}{1+e^{-z}}

这个函数大家肯定都熟悉了,图像就不展示了,它有两个性质是重要且会用到的这里提一下

  • \theta(-z)=1-\theta(z)
  • \theta'(z)=\theta(z)(1-\theta(z))

这个函数的好处是可以把实数域的值映射到(0,1),那么这个输出就可以看作是一个概率,而输入是什么呢,就是我们最原始的线性模型的输出。光说可能不好理解,我们整个公式吧,假设我们有个线性模型

z=f(x)=\omega_1x_1+\omega_2x_2+b

写成向量形式

\hat{z}=X\cdot\omega

诶有点熟悉啊,这不就是前面刚提过的线性回归嘛。行了别讲了,这题我会,接下来要找损失函数,MSE,然后带入,求解,齐活

然而并不是这样的,假设我们是一维的数据,比如说我们不知道每个人的绩效,只知道工龄,然后把他们的升职与否画在图上,有

这样的数据如何优美的用一条直线拟合呢?很明显不合适的

这里也是我曾经疑惑的一个点,为什么非要用sigmoid,直接的线性回归为什么不能做,其实有时候自己动手做一步,答案就摆在眼前了。后期我会把这里的图片更详细的画一下,这里先这样

那么我们还是乖乖的求助sigmoid吧,我们把上面的输出z整合到sigmoid中,有

h(X)=\theta(X\omega)= \frac{1}{1+e^{-X\omega}}

这里面z=X\cdot\omega是逻辑回归里面的线性部分,然后将这个线性部分通过一个sigmoid函数之后,我们就得到了最后的概率,代表预测类别为1类的概率。那接下来要做第二步,找出我们要求的模型参数————还是\omega,多好。那么第三步,我们该评价我们的模型了,得找出一个损失函数才行,那么这个函数用什么呢?用我们的老朋友MSE?这里我们先顺序往下推,然后再回头看我们的讨论MSE在这里是否合适

**概率分布推导

由于我们预测的是类别,比如1类和0类,那我们就可以定义一个样本属于1类或0类的概率,这是分类问题下才能够有的假设,在回归问题下,不存在回归结果为某一值的概率,这一点想来各位看到这里的都清楚哈。我们假设类别为1的概率是\hat p,则

P(y|X)=\hat p
P(y=0|X)=1-\hat p

这个等式代表当我们得到一个数据特征向量X的时候,其属于正类(1)的概率是\hat p,属于负类(0)的概率是1-\hat p。通过相乘我们可以将这个概率整合到一个等式中,即

P(y|X)=\hat p^y \ast (1-\hat p)^{(1-y)}

可以发现当y取1和0的时候正好就是分开的两个等式。这个时候,在别的Blog里面就会说需要使这个P(y|X)取最大值,那么为什么呢?

想象目前我们拿到一个数据特征向量X,我们这个时候偷偷看了一眼答案,发现这个X实际上是正样本,也就是标签为1,那么我们这个时候是不是就要祈祷我们的模型预测其为1的概率越靠近1越好,如果等于1就最好了!而这个时候的概率是\hat p,也就是\hat p越大越好。OK,那么反过来,假设我们偷看了答案,发现X实际上是负样本,标签为0,那么我们需要我们的模型预测它为0的概率越大越好,此时概率是(1-\hat p),所以\hat p越小越好。

这个时候有点晕,一会需要\hat p越大越好,一会需要越小越好,那我们如何衡量呢?实际上这就是把两个式子合二为一的优点。当我们的样本标签为1的时候,我们的P(y|X)会变成P(y=1|X),此时我们希望P(y=1|X)越大越好,因而P(y|X)越大越好;
当我们的样本标签为0,我们的P(y|X)会变成P(y=0|X),此时我们希望P(y=0|X)越大越好,同样P(y|X)越大越好,那么我们就发现了无论什么情况下,P(y|X)越大越好。

这里这么多废话就是想说清楚一句:令每个样本属于其真实标签的概率越大越好

这样我们就有了目标,然后就能先把损失函数写出来,对概率P(y|X)取对数并且取反,有

L(y,X)=-[y\ln(\hat p)+(1-y)\ln(1-\hat p)]

在这里我们进行了取对数的操作,这样不改变原函数的单调性,另外对原函数进行了取反(加负号)的操作,这样我们的目标就从让原函数最大变为了新函数的最小,毕竟“最小”更符合“损失”,所以我们的损失函数就如上式所示,由两部分的对数组成,这个式子同时也称作交叉熵函数。还有要注意的一点是,损失函数的写法中没有显式写出的参数\omega,这实际上是因为\omega是存在于概率p中的,这里的概率p实际上就是sigmoid函数的预测概率输出。

这里的损失函数形式是针对单个样本的,对整体样本前面加上求和符号即可

此时有了损失函数,我们就可以求使得损失函数最小的那个参数\omega。那么在此我们先暂停一下,其实损失函数还有另外一种推导方式。

刚才我们是从概率的角度,从二分类问题的概率分布(实际上就是伯努利分布)不断的推导,然后找到了优化目标,也就定义了损失函数。现在我们从另外的角度,最大似然的角度来推导一遍损失函数。

这里的这个推导结果可能并不是常见的逻辑回归的损失函数的形式,但我觉得理解了多少有帮助,万一面试官就问了呢

**最大似然推导

这次我们从数据的角度分析,假设已有的数据是:

D=(x_1,1),(x_2,1),(x_3,1),……,(x_n,-1)

这里每个括号的第一项x_i代表了特征数据向量,第二项代表了对应的标签,注意这里的正样本仍然是1,但是负样本我们此处定义为了-1

负样本的标签不再是0,这一点很重要

这些数据的产生是相互独立的,所以获得D这笔数据的概率就是

P(x_1,1)\ast P(x_2,1)\ast P(x_31,1)\ast …… \ast P(x_n,-1)

改写为条件概率的形式

P(x_1)P(1|x_1)\ast P(x_2)P(1|x_2)\ast P(x_3)P(1|x_3)\ast …… \ast P(x_n)P(-1|x_n)

这里面的P(y_i|x_i)可以理解为是模型在输入特征数据x_i之后得到其属于y_i的概率,而P(x_i)可能无法找到一个实际的物理含义的释义,因为我们这里是通过数学的方法直接拆分的,但是我们继续推下去可以发现这个P(x_i)其实并不影响我们的推导。我们这里假设每笔数据的概率分布为

P(y_i|x_i)=
\begin{cases}
f(x_i)& {y=+1}\\
1-f(x_i)& {y=-1}
\end{cases}

改写我们上面的条件概率

P(x_1)f(x_1)\ast P(x_2)f(x_2)\ast P(x_3)f(x_3)\ast …… \ast P(x_n)(1-f(x_n))

此时我们就可以理解为我们得到的数据的概率是上面这个表达式,那么应用最大似然的思想,我既然得到了这笔数据,就一定程度上说明这笔数据可能就是这样的;真实的“特征数据”与其对应的“标签”之间的关系就是这样的;在真实的数据中,我得到这样的一个数据D的概率就是最大的。那么我们现在就是要求这样的一个f(x),去使得上面这个概率结果最大。而在这个概率中,P(x_i)是与标签无关的,也就意味着我们使得这个概率结果最大主要要求的还是f(x),由于连乘的关系,我们只需将f(x)的乘积最大即达到了整体的最大,也就是说使得

f(x_1)\ast f(x_2)\ast f(x_3)\ast …… \ast (1-f(x_n))

最大。这时我们可以带入我们的模型,也就是

h(x)=\frac{1}{1+e^{-z}}=\frac{1}{1+e^{-X\omega}}

得到

h(x_1)\ast h(x_2)\ast h(x_3)\ast …… \ast (1-h(x_n))

结合sigmoid函数性质,有

h(x_1)\ast h(x_2)\ast h(x_3)\ast …… \ast h(-x_n)

则优化目标为

\min_{\omega} -\prod_{i=1}^n h(y_ix_i)

这里把y_i放进sigmoid函数中,正好可以表达出所有的情况,要注意这里的y的正负类的标志是+1-1。对上式取对数,得

\min_{ \omega} - \sum_{i=1}^{n} \ln h(y_ix_i)

这样我们就化连乘为相加,通过展开h(x)的表达式即可得到我们的损失函数,即

L(y,\boldsymbol{X}) = \sum_{i=1}^{n} \ln (1+e^{-y_i\boldsymbol{X} \omega})

这样我们就推导出来了逻辑回归的另一个损失函数的表达形式,可以看出两个表达式并不一样,那么它们都是逻辑回归的损失函数吗?他们实际上是一个等式还是说他们确实是两种损失函数?

这里其实我也不知道,感觉论文原文中应该有描述,但是还没来的看论文,先按照自己的推导猜一猜吧,如果有大神看到了知道他们之间关系的不妨给我也点拨一下…

把两种形式的损失函数统统罗列于此,分别都取一个样本的情况下,有

L_1(y,X)=-[y_1\ln(\hat p)+(1-y_1)\ln(1-\hat p)] \tag{1}
L_2(y,X) = \ln (1+e^{-y_2X \omega})=-\ln (\theta(y_2X\omega)) \tag{2}

\hat p展开,则有\hat p=\frac{1}{1+e^{-X\omega}}=\theta(X\omega), 对\omega求导,有

\frac{\partial L_1}{\partial \omega}=(\hat p-y_1)X =(\theta(X\omega)-y_1)X
\frac{\partial L_2}{\partial \omega}=(\theta(y_2Xw)-1)y_2X

这里能看出两者的求导结果好像并不一致,这其实和两种情况下的标签y的取值不同有关,第一种的标签取值为\{1,0\},而第二种的标签取值为\{+1,-1\},我们发现,当标签为正,即在两种情况下都取y=1时,两者的求导结果是一样的,那么我们关注一下标签为负的时候,此时y_1=0,对L_1的导数有

\frac{\partial L_1}{\partial \omega}=(\theta(X\omega)-y_1)X=\theta(X\omega)X

对于L_2,其标签取y_2=-1,有

\frac{\partial L_2}{\partial \omega}=-(\theta(-Xw)-1)X=(1-\theta(-Xw))X= \theta(X\omega)X

以上的设计公式推导的部分会经常的使用到sigmoid函数的两个性质,这两个性质在上文中已经提及

至此我们发现两种形式的损失函数的导数(梯度)是一致的,所以我认为这两种形式的损失函数是同一实质的两种形式,这个结论的得出并不严谨,因为导数相同并不代表原函数相同,但是我也没看论文,所以就这么猜测了,另外,常见的梯度下降法计算时不就是要梯度么,他们梯度一样应该就是一个东西XD

***损失函数的小总结

在继续之前,先小总结一下逻辑回归的损失函数,以一个样本为例,我们依次得到了

因为两种形式的损失函数是一样的,这里就以第一种为例

\hat{z}=X\cdot\omega \tag*{线性回归部分}
\hat p = h(X)=\theta(X\omega) \tag*{通过sigmoid函数输出概率}
P(y|X)=\hat p^y \ast (1-\hat p)^{(1-y)}  \tag*{针对不同类别样本的预测概率}
L(y,X)=-[y\ln(\hat p)+(1-y)\ln(1-\hat p)] \tag*{损失函数}

至此我们就从头到尾推导了一遍逻辑回归,哦不,还没到尾,我们到这里只是推导到了损失函数,而知道了损失函数我们还需要求解,找到能够使损失函数达到最小的取值,这样才算完成了全部的逻辑回归。

**优化求解

我们想到求最小值,默认的想法都是求一阶导数,然后令其等于零从而求解,那么这个方法在这里是否适用呢?我们发现参数\omega是包含在sigmoid函数中的e的指数项的,这导致在多维特征的情况下,涉及复杂的矩阵运算,这显然是不方便求解的。因此我们选择另外一种思路,通过随机一个函数上的初始点,然后不断迭代,令其每次迭代时都尽可能使损失函数的结果变小,这样在多次的迭代之后,我们就可以得到令损失函数最小的那一组参数\omega

这里的关于优化的描述并不严谨,只是表达一个优化迭代的意思

常见的优化算法有很多,梯度下降法,牛顿法等,并且近年来在这些传统优化算法上有着很多的优化改进,这里不详细介绍优化算法(因为工程量太大了),仅简单提及一下梯度下降法的基本思路。

梯度下降法首先对参数\omega随机选取一个初始点,然后计算损失函数在该点的梯度(也就是导数),然后沿着梯度方向前进一个增量,从而得到新的\omega,不断循环这个过程,直到梯度为零(到达极值),或者梯度达到了阈值为止。用公式表示即

\omega=\omega - \alpha \frac{\partial{L(y,X)}}{\partial{\omega}}

这里的\alpha代表学习率,也就是当我们求出了梯度方向后,觉得我们沿着这个方向走多远的一个参数,这个参数不属于模型本身,需要人工设定。通过这样的思路,我们就能最终求得逻辑回归中的参数\omega的最优解,从而完成整个模型。
同样的,我们小小总结一下逻辑回归的这一套流程。①我们先定了模型的样式(线性的内核套一个sigmoid的外壳),②然后就知道了我们需要求出的参数是什么(\omega),③接下来我们分别用两种思路找到了能够评估模型的损失函数(交叉熵),④结合相关的优化算法,找到最优的参数\omega,从而完成了整个模型。

在我们完成了模型之后,我们想起来还有一个MSE被我们遗忘了,那么我们为什么在损失函数阶段不直接选择MSE呢?首先我们从结尾处看,如果我们选择MSE作为损失函数,那么对单个样本有

L=\frac{1}{2}(y-\hat p)^2

则梯度为

\frac{\partial{L}}{\partial{\omega}}=- |(y-\hat p)| h'(x)X

而交叉熵的梯度为

\frac{\partial L}{\partial \omega}=(\hat p-y)X

对比之下发现MSE的梯度相对于交叉熵的梯度多乘了一个系数h'(x),而这个系数就是sigmoid函数的导数,我们不妨画出sigmoid的导数图像,有

可以看到sigmoid的导数的最大值只有0.25,而在输入值较大或较小时都趋近于0。但是我们的优化目标就是在样本为正时输出趋近于+1,那么就要输入足够大,因此如果使用MSE作为损失函数的话,当接近优化目标时很可能出现梯度消失,无法继续逼近损失函数最小值。

此外,使用MSE作为损失函数会导致引入模型sigmoid后非凸,此时会有很多局部最优,影响优化算法寻找全局最优点。

*总结

至此算是把逻辑回归从头到尾过了一遍,用关键要点简单总结一下吧。

线性回归

  • 线性回归旨在用线性模型拟合数据点,可以用作回归问题中
  • 使用线性方程作为模型
  • 使用MSE作为损失函数
  • 将模型带入损失函数求解得到参数表达式

逻辑回归

  • 逻辑回归旨在训练一个分类模型,用于分类问题
  • 使用sigmoid作为外层。线性模型作为内层的模型
  • 使用交叉熵作为损失函数
  • 将模型带入损失函数后使用优化算法得到参数表达式
  • 交叉熵存在两种表达形式,但实际上是统一的,差别在于标签的设定值
  • 损失函数不使用MSE的原因有两点:①梯度消失,②局部最优



嗯,写到这里发现这个逻辑回归其实还挺有逻辑的XD

各位看官有什么问题或者发现我哪里写错了都欢迎讨论指出啊,毕竟我也是个菜鸡,难免有错的地方,可以多多讨论加深理解

参考博客

www.jianshu.com/p/b07f4cd32…
blog.csdn.net/weixin_4153…
www.cnblogs.com/shayue/p/10… 这个写的真的很好
www.cnblogs.com/shayue/p/10…
blog.csdn.net/weiweixiao3…
www.cnblogs.com/maybe2030/p…
blog.csdn.net/mzpmzk/arti…
blog.csdn.net/dpengwang/a…
blog.csdn.net/huwenxing08…
yq.aliyun.com/articles/66…
blog.csdn.net/alw_123/art…

*END