logistic回归原理解析及Python应用实例

logistic回归,又叫对数几率回归。首先强调,这是一个分类模型而不是一个回归模型!

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

既然logistic回归名字中都带有“回归”二者,所以二者是有联系的。
首先给出线性回归模型:
在这里插入图片描述
写成向量形式为:
在这里插入图片描述
同时“广义线性回归”模型为:
在这里插入图片描述
注意,其中g(~)是单调可微函数。
下面我们便从线性回归的回归模型引出logistic回归的分类模型!!!

我们知道上述线性回归模型只能够进行回归学习,但是若要是做分类任务如何做!答案便是在“广义线性回归”模型中:只需找一个单调可微函数将分类任务的真实标记y与线性回归模型的预测值联系起来便可以了!

logistic回归是处理二分类问题的,所以输出的标记y={0,1},并且线性回归模型产生的预测值z=wx+b是一个实值,所以我们将实值z转化成0/1值便可,这样有一个可选函数便是“单位阶跃函数”:
logistic回归原理解析及Python应用实例_第1张图片
这种如果预测值大于0便判断为正例,小于0则判断为反例,等于0则可任意判断!
但是单位阶跃函数是非连续的函数,我们需要一个连续的函数,“Sigmoid函数”便可以很好的取代单位阶跃函数:
在这里插入图片描述
sigmoid函数在一定程度上近似单位阶跃函数,同时单调可微,图像如下所示:
logistic回归原理解析及Python应用实例_第2张图片
这样我们在原来的线性回归模型外套上sigmoid函数便形成了logistic回归模型的预测函数,可以用于二分类问题:
在这里插入图片描述
对上式的预测函数做一个变换为:
在这里插入图片描述
观察上式可得:若将y视为样本x作为正例的可能性,则1-y便是其反例的可能性。二者的比值便被称为“几率”,反映了x作为正例的相对可能性,这也是logistic回归又被称为对数几率回归的原因!
这里我们也便可以总结一下线性回归模型和logistic回归的关系:
**logistic回归分类模型的预测函数是在用线性回归模型的预测值的结果去逼近真实标记的对数几率!**这样也便实现了上面说的将线性回归的预测值和分类任务的真实标记联系在了一起!

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

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

from numpy import *
import matplotlib.pyplot as plt

#从文件中加载数据:特征X,标签label
def 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.001
    num=500
    for i in range(num):
        error=sigmoid(matMatrix*w)-matLabel
        w=w-alpha*matMatrix.transpose()*error
    return w


#随机梯度上升算法的实现,对于数据量较多的情况下计算量小,但分类效果差
#每次参数迭代时通过一个数据进行运算
def stocGraAscent(dataMatrix,matLabel):
    m,n=shape(dataMatrix)
    matMatrix=mat(dataMatrix)

    w=ones((n,1))
    alpha=0.001
    num=20  #这里的这个迭代次数对于分类效果影响很大,很小时分类效果很差  
    for i in range(num):
        for j in range(m):
            error=sigmoid(matMatrix[j]*w)-matLabel[j]
            w=w-alpha*matMatrix[j].transpose()*error        
    return 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.01

            dataIndex=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()*error    
    return 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)

结果:
logistic回归原理解析及Python应用实例_第3张图片
原文:https://blog.csdn.net/feilong_csdn/article/details/64128443 仅摘了部分。

你可能感兴趣的:(python)