【机器学习实战笔记】Logistic回归

Sigmoid函数

我们想定义一个函数,即能够接受所有特征输入(自变量)然后预测出类别(因变量)。在二分类的情况下,可以定义输出为0和1。比如要预测一个动物是不是鸟类,是则为1,不是则为0。具有这种性质的函数,比较简单的就是单位阶跃函数(Heaviside step function)。但是该函数在x=0x=0x=0处从0瞬间跳变到1,这样就很难处理。换句话讲,阶跃函数在x=0x=0x=0处不可微,这就不利于后面使用梯度上升或下降的方法。此时另一个函数就满足类似的性质,即可以输出0或1,这就是Sigmoid函数,如下
σ(z)=11+e−z sigma(z)=frac{1}{1+mathrm{e}^{-z}} σ(z)=1+ez1
如图5-1,当x=0x=0x=0时,Sigmoid函数值为0.5,随着xxx增大,对应的值将逼近于1;而随着xxx减小,Sigmoid值将逼近于0。如果横坐标刻度足够大,如图5-1下图,Sigmoid函数看起来就很像一个阶跃函数。
在这里插入图片描述

Logistic回归

而Logistic回归就是上面Sigmoid函数的输入zzz定义为以下形式:
z=b+w1x1+w2x2+...+wnxn z=b+w_1x_1+w_2x_2+...+w_nx_n z=b+w1x1+w2x2+...+wnxn
其中x1,x2,...,xnx_1,x_2,...,x_nx1,x2,...,xn是输入的特征即自变量,w1,w2,...wnw_1,w_2,...w_nw1,w2,...wn就是特征对应的权重,或者叫回归系数,而通常b=w0x0b=w_0x_0b=w0x0是偏移量设为1,上面公式可以简写为:
z=wTx+b z=w^Tx+b z=wTx+b
即Logistic回归的模型,剩下的我们只需要求出参数wwwbbb

梯度上升法

怎么求出参数wwwbbb呢?书中给出了梯度上升法,随机梯度上升以及改进的随机梯度上升,梯度上升跟下降类似,只不过前者就局部最大值,后者求的是最小值。原理的雏形可结合导数与极值的关系,比较容易理解,参考:
在这里插入图片描述
在这里插入图片描述

wiki:随机梯度下降

随机梯度下降(Stochastic gradient descent)和 批量梯度下降(Batch gradient descent )的公式对比、实现对比

如何理解随机梯度下降

需要理解批量梯度,也就是书中给出了第一种梯度上升,以及mini-batch梯度下降,和随机梯度下降,简单来讲就是随机梯度一次仅用一个样本点来更新回归系数,mini-batch使用一小部分,批量梯度则是全部,这样的话训练速度更新会很慢,所以随机梯度比较流行。并且随机梯度是一个在线算法,可以在新数据到来时就完成参数更新,而不需要重新读取整个数据集来进行批处理运算。

代码

以下是基于梯度上升的Logistic回归算法,其中alpha就是机器学习中常讲的学习率,也就是机器学习实战这本书所讲的步长。

import numpy as np

def sigmoid(inX):
    '''sigmoid函数
    '''
    return 1.0/(1+np.exp(-inX))

def gradAscent(dataMat,labelMat):
    '''批量梯度上升
    '''
    dataMat=np.mat(dataMat)
    labelMat=np.mat(labelMat).transpose()
    m,n=np.shape(dataMat) # m cannot be deleted
    alpha=0.001
    maxCycles=500
    weights=np.ones((n,1)) #weights[3*1]
    for k in range(maxCycles):
        h=sigmoid(dataMat*weights)
        error=(labelMat-h) #error[100*1]
        weights=weights+alpha*dataMat.transpose()*error
    print(weights)
    return weights

def stocGradAscent0(dataMat,labelMat):
    '''随机梯度上升
    '''
    m,n=np.shape(dataMat) #dataMat[100*3]
    alpha=0.01
    weights=np.ones(n) #weights[1*3]
    dataArr=np.array(dataMat)
    for i in range(m):
        h=sigmoid(sum(dataMat[i]*weights)) # dataMat[i]表示一个样本
        error=labelMat[i]-h
        weights=weights+alpha*error*dataArr[i]
    return weights

def stocGradAscent1(dataMat,labelMat,iteration=150):
    '''改进的随机梯度上升
    '''
    m,n=np.shape(dataMat)
    weights=np.ones(n)
    dataArr=np.array(dataMat)
    for j in range(iteration):
        dataIndex=dataMat.copy() # initially dataIndex=range(m),but a range cannot be operated by del() at line 75
        for i in range(m):
            alpha=4/(1.0+j+i)+0.01 #apha decreases with iteration, does not
            randIndex=int(np.random.uniform(0,len(dataIndex))) #go to 0 because of the constant
            h=sigmoid(sum(dataMat[randIndex]*weights))
            error=labelMat[randIndex]-h
            weights=weights+alpha*error*dataArr[randIndex]
            del(dataIndex[randIndex])
    return weights

def classifyVector(inX,weights):
    prob=sigmoid(sum(inX*weights))
    if prob>0.5: return 1.0
    else: return 0.0

相关问题

以下问题提供思考:

  • Logistic回归与多重线性回归的区别?
原文地址:https://www.cnblogs.com/hzcya1995/p/13281663.html