首页 > 编程知识 正文

logistic回归模型预测,二元logistic回归分类协变量

时间:2023-05-05 10:06:59 阅读:12357 作者:4156

logistic回归又称对数概率回归。 首先,请强调这是分类模型,而不是回归模型! 以下从多个方面说明了logistic回归的原理,然后分别采用梯度上升算法和随机梯度上升算法将logistic回归算法应用于实例。

一、logistic回归与线性回归的关系

我想大家也有疑问,既然logistic回归的名字附有“回归”,那么它和回归模型没有任何关系吗? 是的。 两者有联系。 现在谈谈吧。

首先给出线性回归模型。

用矢量格式写的话,如下所示。

同时,“广义线性回归”模型如下

其中,g(~)是单调可微函数。

从线性回归的回归模型中引出logistic回归的分类模型吧!

我知道上诉线性回归模型只能进行回归学习,但如何做分类任务! 答案在“广义线性回归”模型中。 只要找到将分类任务的真正标记y和线性回归模型的预测值联系起来的单调的可微函数就可以了。

因为logistic回归处理二分类问题,所以输出的标记y={ 0,1 }和线性回归模型的预测值z=wx b是实数值,所以将实数值z变换为0/1的值即可。 这样,一个可选函数是“单位阶跃函数”。

这样的预测值大于0则判断为正例,小于0则判断为反例,如果等于0则可以任意判断!

然而,由于单位阶跃函数是非连续的函数,所以需要连续的函数,“Sigmoid函数”可以很好地替换单位阶跃函数。

sigmoid函数在某种程度上与单位阶跃函数近似的同时,可以单调微调。 示意图如下:

因此,我们可以在原始线性回归模型的外套上加sigmoid函数,形成logistic回归模型的预测函数,用于二分类问题:

将上式的预测函数转换为:

由上式可知,假设将y视为样本x为正例的可能性,则1-y为其反例的可能性。 两者之比被称为“概率”,反映了x作为正例的相对可能性。 这就是logistic回归也被称为对数概率回归的理由

这里还总结了线性回归模型与logistic回归的关系。

logistic回归分类模型的预测函数使用线性回归模型预测值的结果与真实标签的对数概率近似! 因此,如上所述,我们将线性回归的预测值与分类任务的真正表述联系起来了!

二、梯度上升算法求解logistic回归模型参数w

上一个主题得到了logistic回归的预测函数:

在此,如果将式中的y设为类后验概率估计p(y=1|x ),则上式可以改写为如下。

求解上述公式如下

首先给出求解参数w的思路,以下按照该思路求解参数w :

1、为了求解参数w,需要定义基准函数j(w ),使用基准函数求解参数w

2、我们用最大似然估计法定义基准函数j(w )

3、接下来可以通过最大化基准函数j(w )求出参数w反复式

4、为了成功使用数据求参数w,对步骤3中获得的w进行迭代时向量化。 至此,参数w的推导过程完成。 现在可以应用实例了。

步骤一、求解基准函数j(w )

(3) (4)的两个公式组合如下。

在式(5)中,y={ 0,1 }是两个分类问题,因此y只是取两个值0或1。

由式(5)得到的似然函数如下

取式(6)对数,则如下

因此,定义标准函数如下:

最终,我们的目标是使似然函数,即最大化基准函数最大化:

第二步,梯度上升算法求解参数w

在此,由于使用梯度上升算法求解参数w,所以参数w的反复式如下。

其中是正比例因子,用于设定步长的“学习率”

其中对基准函数j(w )进行微分可以得到以下结果。

因此,得到最终参数w的迭代公式如下。

上式即使去除(1/m )也不会影响结果,因此与下式等价。

至此,w的迭代公式已经出来了,本来可以在导入数据的状态下进行w的计算,并进一步分类! 但是,由于数据基本上是以矩阵和向量的形式引入的,因此必须对上面w的迭代时间进行向量化,以便于在实例APP应用程序中使用。

步骤3,w迭代式矢量化

首先,对于引入的数据集x,它被引入为矩阵,如下所示:

其中m数据的

个数,n是数据的维度,也就是数据特征的数量!

 

再者便是标签y也是以向量的形式引入的: 


参数w向量化为: 


在这里定义M=x*w,所以: 

 

定义上面说的sigmoid函数为: 


所以定义估计的误差损失为: 


在此基础上,可以得到步骤二中得到的参数迭代时向量化的式子为: 

 

至此我们便完成了参数w迭代公式的推导,下面便可以在实例中应用此迭代公式进行实际的分析了!下面我们便以简单的二分类问题为例来分析logistic回归算法的使用!!

三、logistic回归算法的实例应用(pyhton)

此实例便是在二维空间中给出了两类数据点,现在需要找出两类数据的分类函数,并且对于训练出的新的模型,如果输入新的数据可以判断出该数据属于二维空间中两类数据中的哪一类!

在给出Python实现的示例代码展示之前,先介绍一下两种优化准则函数的方法: 
1、梯度上升算法 
2、随机梯度上升算法

梯度上升算法: 
梯度上升算法和我们平时用的梯度下降算法思想类似,梯度上升算法基于的思想是:要找到某个函数的最大值,最好的方法是沿着这个函数的梯度方向探寻!直到达到停止条件为止! 
梯度上升算法的伪代码: 

 

随机梯度上升算法: 
梯度上升算法在每次更新回归系数时都需要遍历整个数据集,该方法在处理小数据时还尚可,但如果有数十亿样本和成千上万的特征,那么该方法的计算复杂度太高了,改进方法便是一次仅用一个数据点来更新回归系数,此方法便称为随机梯度上升算法!由于可以在更新样本到来时对分类器进行增量式更新,因而随机梯度上升算法是一个“在线学习算法”。而梯度上升算法便是“批处理算法”!

改进的随机梯度上升算法: 
随机梯度上升算法虽然大大减少了计算复杂度,但是同时正确率也下降了!所以可以对随机梯度上升算法进行改进!改进分为两个方面: 
改进一、对于学习率alpha采用非线性下降的方式使得每次都不一样 
改进二:每次使用一个数据,但是每次随机的选取数据,选过的不在进行选择

在知道这些信息之后下面给出示例代码,其中有详细的注释:

#!/usr/zqdpkq/env python3# -*- coding: utf-8 -*-from numpy import *import matplotlib.pyplot as plt#从文件中加载数据:特征X,标签labeldef loadDataSet():dataMatrix=[]dataLabel=[]#这里给出了python 中读取文件的简便方式f=open('testSet.txt')for line in f.readlines():#print(line)lineList=line.strip().split()dataMatrix.append([1,float(lineList[0]),float(lineList[1])])dataLabel.append(int(lineList[2]))#for i in range(len(dataMatrix)):# print(dataMatrix[i])#print(dataLabel)#print(mat(dataLabel).transpose())matLabel=mat(dataLabel).transpose()return dataMatrix,matLabel#logistic回归使用了sigmoid函数def sigmoid(inX):return 1/(1+exp(-inX))#函数中涉及如何将list转化成矩阵的操作:mat()#同时还含有矩阵的转置操作:transpose()#还有list和array的shape函数#在处理矩阵乘法时,要注意的便是维数是否对应#graAscent函数实现了梯度上升法,隐含了复杂的数学推理#梯度上升算法,每次参数迭代时都需要遍历整个数据集def graAscent(dataMatrix,matLabel):m,n=shape(dataMatrix)matMatrix=mat(dataMatrix)w=ones((n,1))alpha=0.001num=500for i in range(num):error=sigmoid(matMatrix*w)-matLabelw=w-alpha*matMatrix.transpose()*errorreturn w#随机梯度上升算法的实现,对于数据量较多的情况下计算量小,但分类效果差#每次参数迭代时通过一个数据进行运算def stocGraAscent(dataMatrix,matLabel):m,n=shape(dataMatrix)matMatrix=mat(dataMatrix)w=ones((n,1))alpha=0.001num=20 #这里的这个迭代次数对于分类效果影响很大,很小时分类效果很差for i in range(num):for j in range(m):error=sigmoid(matMatrix[j]*w)-matLabel[j]w=w-alpha*matMatrix[j].transpose()*errorreturn w#改进后的随机梯度上升算法#从两个方面对随机梯度上升算法进行了改进,正确率确实提高了很多#改进一:对于学习率alpha采用非线性下降的方式使得每次都不一样#改进二:每次使用一个数据,但是每次随机的选取数据,选过的不在进行选择def stocGraAscent1(dataMatrix,matLabel):m,n=shape(dataMatrix)matMatrix=mat(dataMatrix)w=ones((n,1))num=200 #这里的这个迭代次数对于分类效果影响很大,很小时分类效果很差setIndex=set([])for i in range(num):for j in range(m):alpha=4/(1+i+j)+0.01dataIndex=random.randint(0,100)while dataIndex in setIndex:setIndex.add(dataIndex)dataIndex=random.randint(0,100)error=sigmoid(matMatrix[dataIndex]*w)-matLabel[dataIndex]w=w-alpha*matMatrix[dataIndex].transpose()*errorreturn w#绘制图像def draw(weight):x0List=[];y0List=[];x1List=[];y1List=[];f=open('testSet.txt','r')for line in f.readlines():lineList=line.strip().split()if lineList[2]=='0':x0List.append(float(lineList[0]))y0List.append(float(lineList[1]))else:x1List.append(float(lineList[0]))y1List.append(float(lineList[1]))fig=plt.figure()ax=fig.add_subplot(111)ax.scatter(x0List,y0List,s=10,c='red')ax.scatter(x1List,y1List,s=10,c='green')xList=[];yList=[]x=arange(-3,3,0.1)for i in arange(len(x)):xList.append(x[i])y=(-weight[0]-weight[1]*x)/weight[2]for j in arange(y.shape[1]):yList.append(y[0,j])ax.plot(xList,yList)plt.xlabel('x1');plt.ylabel('x2')plt.show()if __name__ == '__main__':dataMatrix,matLabel=loadDataSet()#weight=graAscent(dataMatrix,matLabel)weight=stocGraAscent1(dataMatrix,matLabel)print(weight)draw(weight)

上面程序运行结果为: 

其中: 
图(1)是使用梯度上升算法的结果,运算复杂度高; 
图(2)是使用随机梯度上升算法,分类效果略差吗,运算复杂度低; 
图(3)是使用改进后的随机梯度上升算法,分类效果好,运算复杂度低。

上述程序数据连接,提取密码为:1l1s

文中如有何问题,欢迎指正,谢谢!!!

参考文献:

https://blog.csdn.net/feilong_csdn/article/details/64128443

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。