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+e−z1
如图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回归的模型,剩下的我们只需要求出参数www和bbb。
梯度上升法
怎么求出参数www和bbb呢?书中给出了梯度上升法,随机梯度上升以及改进的随机梯度上升,梯度上升跟下降类似,只不过前者就局部最大值,后者求的是最小值。原理的雏形可结合导数与极值的关系,比较容易理解,参考:
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回归与多重线性回归的区别?