从线性回归函数到逻辑回归函数
逻辑回归是线性分类器,其本质是由线性回归通过一定的数学变化而来的。要理解逻辑回归,得先理解线性回归。线性回归是构造一个预测函数来映射输入的特性矩阵和标签的线性关系。线性回归使用最佳的拟合直线(也就是回归线)在因变量(
)和一个或多个自变量(
)之间建立一种关系。在这种技术中,因变量是连续的,自变量可以是连续的也可以是离散的,回归线的性质是线性的。
类比线性方程
:
可以用矩阵的形式表示该方程,其中 x 与 w 均可以被看作一个列矩阵:
通过函数
,线性回归使用输入的特征矩阵
来输出一组连续型的标签值 y_pred
,以完成各种预测连续型变量的任务。若标签是离散型变量,尤其是满足0-1分布的离散型变量,则可以通过引入联系函数(link function),将线性回归方程
变换为
,并且令
的值分布在 (0,1) 之间,且当
接近0时样本的标签为类别0,当
接近1时样本的标签为类别1,这样就得到了一个分类模型。而这个联系函数对于逻辑回归来说,就是Sigmoid
函数:
Sigmoid
函数是一个
型的函数,当自变量
趋近正无穷时,因变量
趋近于1,而当
趋近负无穷时,
趋近于0,它能够将任何实数映射到(0,1) 区间,使其可用于将任意值函数转换为更适合二分类的函数。
因为这个性质,Sigmoid
函数也被当作是归一化的一种方法,与我们之前学过的MinMaxSclaer
同理,是属于数据预处理中的"缩放"功能,可以将数据压缩到[0,1]之内。区别在于MinMaxScaler
归一化之后,是可以取到0和1的,但Sigmoid
函数只是无限趋近于0和1。
线性回归中
带入到Sigmoid
函数中,即得到二元逻辑回归模型的一半形式:
其中
为逻辑回归的返回的标签值。假设已经训练好一组权值向量
。只要把我们需要预测的特征矩阵
带入到
方差中,得到输出值就是标签为类别1的概率,于是就能判断输入特征矩阵是属于哪个类别。
因此逻辑回归是不直接预测标签值,而是去预测标签为类别1的概率。一般地如果标签为类别1的概率大于0.5,就认为其为类别1,否在为类别2。
Logistic 分布
Logistic distribution
定义:设
是连续随机变量,
服从逻辑分布是指
具有下列分布函数和密度函数:
式中,
为位置参数,
为形状参数。
逻辑回归等分布函数(左)和密度函数(右)
二元逻辑回归模型
分类问题(Classification)
逻辑回归模型一般处理二分类问题,而二分类问题就是给定输入特征矩阵
,判断输出的标签是类别1还是类别2。二分类问题是最简单的分类问题。多分类问题也可以通过一定的方法转化成一组二分类问题。比如最简单的是OVA(One-vs-all)方法,如一个6分类问题,可以判断输入是特征矩阵
否属于某个类,其余的判断属于其他类,依次类推,从而转化为一组6个二分类问题。
逻辑回归模型(Logistic Regression)
二项逻辑回归模型是一种分类模型,由条件概率分布
表示,形式为参数化的逻辑回归。随机变量
取值为实数,随机变量
取值为1或0。通过监督学习的方法估计模型参数。
定义:二项逻辑回归模型如下回归模型是如下的条件概率分布:
其中,
是输入,
是输出。
和
是参数,
称为权值向量,
,
称为偏置,
为
和
的内积。
一个事件发生的几率(
odds
) 指该事件发生的概率与该事件不发生的概率大比值。如果事件发生的概率是
,那么该事件的几率是
,该事件的对数几率(log odds
)或logit
函数是
对于逻辑回归,对数几率(log odd
)为:
在逻辑回归模型中,输出
的对数几率是输入
的线性函数。
形似几率取对数的本质就是线性回归,实际上是在对线性回归模型的预测结果取对数几率来让其的结果无限逼近0和1。因此,其对应的模型被称为"对数几率回归"(Logistic Regression
),即逻辑回归。
逻辑回归的损失函数
"损失函数"这个评估指标,来衡量参数为
的模型拟合训练集时产生的信息损失的大小,即衡量模型的输出与真实输出的差别。并以此衡量参数
的优劣。
基于极大似然法来推导二元逻辑回归的损失函数
二元逻辑回归的标签服从伯努利分布(即0-1分布),因此我们可以将一个特征向量为
,参数为
的模型中的一个样本
的预测情况表现为如下形式将样本特征线性表示
,然后输入到 Sigmoid
函数,输出结果在0-1之间,并且输出结果表征了分类结果为1的概率。
样本
在由特征向量
和参数
组成的预测函数中,样本标签被预测为1的概率为:
样本
在由特征向量
和参数
组成的预测函数中,样本标签被预测为0的概率为:
当
被的值为1的时候,代表样本
的标签被预测为1,当
的值为1的时候,代表样本
的标签被预测为0。
两种取值整合:
这个等式代表同时代表了
和
。当样本
的真实标签
时,则
, 即
,所以
,若
非常接近于1,模型的效果就很好,损失就很小。同理,当样本
的真实标签
时, 则
,所以
,若
非常接近于1,模型的效果就很好,损失就很小。因此为了达成让模型拟合好,损失小的目的,则
需达到最大值1。这就将模型拟合中的"最小化损失"
问题,转换成了对函数求解极值的问题。
对一个训练集的
个样本,假设
个样本独立同分布:
对概率对
极大似然估计得交叉熵函数:
为了数学上的便利以及更好地定义"损失"的含义,我们希望将极大值问题转换为极小值问题,因此取负并让参数
作为函数的自变量,得到损失函数
:
似然与概率 似然与概率是一组非常相似的概念,它们都代表着某件事发生的可能性,但它们在统计学和机器学习中有着微妙的不同。以样本
i
为例,我们有表达式:
对这个表达式而言,如果参数
是已知的,特征向量
是未知的,我们便称
是在探索不同特征取值下获取所有可能的
的可能性,这种可能性就被称为概率,研究的是自变量和因变量之间的关系
。
如果特征向量
是已知的,参数
是未知的,我们便称P是在探索不同参数下获取所有可能的
的可能性,这种可能性就被称为似然,研究的是参数取值与因变量之间的关系
。
在逻辑回归的建模过程中,特征矩阵是已知的,参数是未知的,因此讨论的所有"概率"其实严格来说都应该是"似然"。因此求最大值即为求"极大似然",所以逻辑回归的损失函数的推导方法叫做"极大似然法"。则"极大似然函数"为
梯度下降求解逻辑回归
逻辑回归的损失函数是一个连续的凸函数(conveiently convex)。凸函数的特征是它只会有一个全局最优的点,不存在局部最优。对于GD与SGD的最大问题是其可能会陷入局部最优。因此使用梯度下降法收敛后得到的极值点就一定是全局最优点。
数学基础知识准备
一元函数的导数与泰勒级数
在微积分中,函数
在点
上的导数定义:
其几何意义为函数
在点
上的切线方向
导数定义
为了计算某个函数
的极值(最大值或者最小值),通常方法令其导数为零
,就可以得到函数的临界点
,进一步判断这些临界点是否是极值。但是临界点并不一定是全局极值,甚至不是局部的极值。
例如函数
,它的导数是
, 因此
是临界点,然而函数在
处的取值不是函数
的局部极值,因为
且
。
函数
在
附近泰勒级数展开得到:
临界点
满足条件
。当
时,可以得到
是函数
的局部最小值。相反,当
时,可以得到
是函数
的局部最大值。
对于
,临界点
的二阶导数
,因此使用上面的方法则无法判断临界点
是否是局部极值。
泰勒公式
泰勒公式泰勒公式是一个用函数在某点的信息描述其附近取值的公式。数学家们在柯西中值定理的基础上,推导出了泰勒中值定理(泰勒公式)。
若函数
在包含
的某个开区间
上具有
阶的导数,那么对于任一
, 有
一般情况下,泰勒公式在
处展开。这样可以简化了泰勒公式得到
在
处为的
阶泰勒公式,也称麦克劳林(Maclaurin)公式
由于
为
与
之间的某个值,可令
则其余项写为
泰勒公式的几何意义是利用多项式函数来逼近原函数。
梯度下降法(GD, Gradient Descent)
从数学上的角度来看,梯度的方向是函数增长速度最快的方向,那么梯度的反方向就是函数减少最快的方向。那么,如果想计算一个函数的最小值,就可以使用梯度下降法的思想来做。假设希望求解目标函数
的最小值,可以从一个初始点
开始,基于学习率
构建一个迭代过程。
当
时:
其中
一旦达到收敛条件,迭代即结束 。从梯度下降法的迭代公式来看,下一个点的选择与当前点的位置和它的梯度相关。
迭代过程中构建迭代关系
:
即对于所有
都满足迭代关系
随机梯度下降法(SGD, Stochastic Gradient Descent)
随机梯度下降是在每次更新过程中,加入噪声扰动,这可能会更加快速地逼近最优值。因此采用一个输出为随机变量的替代函数
,满足期望值等于
,相当于这个函数围绕着
的输出值随机波动。因此迭代过程中构建的关系为:
图解梯度下降
如上图所示的三维图像上随机放一个小球,当松手时,小球就会顺着三维平面滚落,直到滚到深红色的区域——损失函数的最低点。可以设置小球每次滚动的距离,不让他一次性滚到最低点,并且最多只允许它滚动有限步,还要记下它每次滚动的方向,直到它滚到图像上的最低点。
可见,小球从高处滑落,在红色的区域中来回震荡,最终停留在了图像凹陷处的某个点上。可以观察到几个现象:
- 首先,小球并不是一开始就直向着最低点去的,它先一口气冲到了红色区域边缘,后来又折回来,前面已经规定了小球是多次滚动,且小球每次滚动的方向都是不同的。
- 另外,小球在进入红色区域后,并没有直接找到某个点,而是在红色区域中来回震荡了数次才停下。这有两种可能:
- 小球已经滚到了图像的最低点,所以停下了,
- 由于我设定的步数限制,小球还没有找到最低点,但在有限步的时候停下了。即小球不一定滚到了图像的最低处。
但无论如何,小球停下的就是我们在现有状况下可以获得的唯一点了。如果够幸运,这个点就是图像的最低点,若找到这个点的对应坐标,就可以获取能够让损失函数最小的参数取值了。如此,梯度下降的过程就已经完成。
梯度下降中的步长
下图为二维平面的求导三角型图。类比损失函数和梯度概念,图中的抛物线就是损失函数
,
就是小球最初在的位置,
就是一次滚动后小球移动到的位置。从
到
的方向就是梯度向量的反方向,指向损失函数在
点下降最快的方向。而梯度向量的大小是点
在图像上对求
导后的结果,也是点A切线方向的斜率。
步长示意图
梯度下降每迭代一步,损失函数减小的量
,即是损失函数在变化之后的取值的变化 ,这是二维 平面的求导三角型中的"对边"。
梯度下降每迭代一步,参数向量的变化
,根据参数向量的迭代公式,即得到步长 * 梯度向量
的大小,记作 ,这是二维平面的求导三角形中的"邻边"。
梯度下降每迭代一步,下降的距离是
,是对边和邻边的根号下平方和,是二维平 面的求导三角型中的"斜边"。
所以,步长
不是任何物理距离,它甚至不是梯度下降过程中任何距离的直接变化,它是梯度向量的大小上的一个 比例,影响着参数向量每次迭代后改变的部分。
步长调节损失函数下降的速率
参数迭代是靠梯度向量的大小
* 步长
来实现的,而
的降低又是靠
调节来实现的,所以步长可以调节损失函数下降的速率。在损失函数降低的方向上,步长越长,
的变动就越大。相对的,步长如果很短,
的每次变动就很小。具体地说,如果步长太大,损失函数下降得就非常快,需要的迭代次数就很少,但梯度下降过程可能跳过损失函数的最低点,无法获取最优值。而步长太小,虽然函数会逐渐逼近我们需要的最低点,但迭代的速度却很缓慢,迭代次数就需要很多。
下降的速率
逻辑回归的特点
线性回归对数据的要求很严格,比如标签必须满足正态分布,特征之间的多重共线性需要消除等等,而现实中很多真实情景的数据无法满足这些要求,因此线性回归在很多现实情境的应用效果有限。逻辑回归是由线性回归变化而来,因此它对数据也有一些要求,而我们之前已经学过了强大的分类模型决策树和随机森林,它们的分类效力很强,并且不需要对数据做任何预处理。
逻辑回归的原理其实并不简单。一个人要理解逻辑回归,必须要有一定的数学础,必须理解损失函数,正则化,梯度下降,海森矩阵等等这些复杂的概念,才能够对逻辑回归进行调优。在面试中,尽量不要那逻辑回归出来举例,因为其设计到的点实在太多。其涉及到的数学理念,不比支持向量机少多少。况且,要计算概率,朴素贝叶斯可以计算出真正意义上的概率,要进行分类,机器学习中能够完成二分类功能的模型简直多如牛毛。因此,在数据挖掘,人工智能所涉及到的医疗,教育,人脸识别,语音识别这些领域,逻辑回归没有太多的出场机会。
但是,逻辑回归依然是一个受工业商业热爱,使用广泛的模型,因为它有着不可替代的优点。
逻辑回归对线性关系的拟合极好
特征与标签之间的线性关系极强的数据,比如金融领域中的信用卡欺诈,评分卡制作,电商中的营销预测等等相关的数据,都是逻辑回归的强项。虽然现在有了梯度提升树GDBT
,其效果比逻辑回归更好,也被许多数据咨询公司启用,但逻辑回归在金融领域,尤其是银行业中的统治地位依然不可动摇(相对的,逻辑回归在非线性数据的效果非常糟糕)。
逻辑回归计算快
对于线性数据,逻辑回归的拟合和计算都非常快,计算效率优于SVM
和随机森林
,且在大型数据上尤其能够看得出区别。
逻辑回归返回类概率数字
逻辑回归返回的分类结果不是固定的0,1,而是以小数形式概率数字呈现的。因此可以把逻辑回归返回的结果当成连续型数据来利用。比如在评分卡制作时,我们不仅需要判断客户是否会违约,还需要给出确定的"信用分",而这个"信用分"的计算就需要使用类概率计算出的对数几率,而决策树和随机森林这样的分类器,可以产出分类结果,却无法帮助我们计算分数(当然,在sklearn
中,决策树也可以产生概率,使用接口predict_proba
调用就好,但一般来说,正常的决策树没有这个功能)。
逻辑回归的可解释性强
逻辑回归的本质,在线性数据上表现优异的分类器,它是一个返回对数几率的,且可以获得一组
维的权值向量
和偏差
。其数学目的是求解能够让模型对数据拟合程度最高的权值向量
的值,以此构建预测函数
,然后将特征矩阵输入预测函数来计算出逻辑回归的结果
。根据逻辑回归的权值向量
的值在每个特征上面的大小,就能够对每个特征的重要程度有一个量化的认识。
另外,逻辑回归还有抗噪能力强的优点。福布斯杂志在讨论逻辑回归的优点时,甚至有着技术上来说,最佳模型的AUC面积低于0.8时,逻辑回归非常明显优于树模型
的说法。并且,逻辑回归在小数据集上表现更好,在大型的数据集上,树模型有着更好的表现。
总结
逻辑回归是一种广义线性回归模型,是Sigmoid
函数归一化后的线性回归模型,常用来解决二元分类问题,可解释性强。它假设数据服从伯努利分布,通过梯度下降法对其损失函数(极大似然函数)求解,以达到数据二分类的目的。
逻辑回归是用来计算"事件=Success"
和"事件=Failure"
的概率。逻辑回归不要求自变量和因变量是线性关系。它可以处理各种类型的关系,因为它对预测的相对风险指数或使用了一个非线性的
转换。它广泛的用于分类问题。
基本原理
其函数表达式为对数几率函数,通过Sigmoid
函数将线性回归方程转化,将任何实数映射到(0,1)之间。
优化目标
通过观测样本的极大似然估计值来选择参数。
损失函数
表征模型预测值与真实值的不一致程度。LR损失函数为负的对数损失函数。逻辑回归,假设样本服从伯努利分布(0-1分布),然后求得满足该分布的似然函数,接着取对数求极值最小化负的似然函数 应用极大似然估计法估计模型参数,从而得到逻辑回归模型。逻辑回归的损失函数求最小值,就是根据最大似然估计的方法来的。
最大似然估计
让总体分布尽量与样本的分布趋同,就是总体的分布与样本分布具有最大的相似性,然后再来求取模型中的参数
,这样就可以得到比较符合最大似然估计的模型。
算法求解
梯度下降法
评估指标
混淆矩阵:AUC Recall Precision
逻辑回归和朴素贝叶斯区别
朴素贝叶斯
贝叶斯公式
是后验概率,
是似然函数,
在这里是代表“特征”的集合,
是"类别"。
二分类问题最总目的是判断为1的概率比判断为0的概率比大于1即可,于是
为了避免浮点数下溢,两边同时取
函数:
左边公式称逻辑发生比,又称作logit,逻辑发生比大于0就说明是好瓜的概率较大 。
在朴素贝叶斯里有一个很强的假设,就是 条件独立假设 。条件独立假设特征之间都是相互独立的,没有耦合的,互不干扰的。
贝叶斯公式 条件独立假设 = 朴素贝叶斯方法
逻辑回归
逻辑回归实际上是用线性回归模型的预测结果去逼近后验概率的逻辑发生比
为特征权重和,
为特征值,可以是连续变量,也可以是离散变量。
二者联系和区别
表达式相似。但两种方法求出的权重是不一样的。
- 朴素贝叶斯方法是条件独立的,因为条件独立假设,朴素贝叶斯可以不使用梯度下降法,而直接通过统计每个特征的逻辑发生比当权重。
- 逻辑回归,条件独立假设并不成立,通过梯度下降方得到特征间的耦合信息,从而得到相应的权重。
- 朴素贝叶斯是生成模型,逻辑回归是判别模型;朴素贝叶斯运用的贝叶斯理论,逻辑回归是最大化对数似然,这是两种概率哲学的区别。
附代码
sigmoid图
代码语言:javascript复制x = np.linspace(-10,10)
y1 = 1/(1 np.e ** -x)
y2 = (np.e ** -x )/((1 np.e ** -x ) **2)
y = [y1, y2]
L = ['F (x)', 'f (x)']
fig = plt.figure(figsize=(15,5))
for i in range(0, len(y)):
ax = fig.add_subplot(1,2,i 1)
plt.plot(x,y[i],label=L[i],color='orange')
plt.xticks(np.arange(-10,11,2))
plt.xlabel(L[i], fontsize=15)
ax=plt.gca() #gca:get current axis得到当前轴
#设置图片的右边框和上边框为不显示
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
#挪动x,y轴的位置,也就是图片下边框和左边框的位置
ax.spines['bottom'].set_position(('data',0))
#data表示通过值来设置x轴的位置,将x轴绑定在y=0的位置
ax.spines['left'].set_position(('axes',0.5))
#axes表示以百分比的形式设置轴的位置,即将y轴绑定在x轴50%的位置,也就是x轴的中点;
三维图
代码语言:javascript复制
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d
plt.figure(figsize=(10,8))
a,b = np.mgrid[-2:2:100j,-2:2:100j]
#测试数据
c=a*np.exp(-a**2-b**2)
#三维图形
ax = plt.subplot(111, projection='3d')
ax.plot_surface(a,b,c,rstride=2, cstride=1, cmap=plt.cm.Spectral)
#设置坐标轴标签
# ax.set_xlabel('A')
# ax.set_ylabel('B')
# ax.set_zlabel('C')
plt.show