如何理解在logis回归中求解最优回归系数用梯度上升或者下降法:
梯度下降或者上升法的更新公式如何理解?
sigmoid计算过程中遇到了溢出问题:
RuntimeWarning:overflow encountered in exp
主要是当x<0时
e
−
x
e^{-x}
e−x会变的很大而造成溢出
关于np.getA()用法:
实验证明:
梯度上升法代码如下:
import numpy as np
import matplotlib.pyplot as plt
def DataLoader(root):
dataMat=[]
labelMat=[]
f=open(root)
for line in f.readlines():
a=line.strip().split()
dataMat.append([1.0,float(a[0]),float(a[1])])
labelMat.append(int(a[2]))
return dataMat,labelMat
def sigmoid(x):
n,m=x.shape
# print(n)
res=[]
for i in range(n):
if x[i,0]>=0:
res.append(1.0/(1+np.exp(-x[i,0]))) ##这里用math.exp不行,因为是处理矩阵
if x[i,0]<0:
res.append(np.exp(x[i,0])/(1+np.exp(x[i,0])))
return np.mat(res)
def gradAscent(dataMat,labelMat):
dataMatrix=np.mat(dataMat)
labelMatrix=np.mat(labelMat)
m,n=dataMatrix.shape
weights=np.ones((n,1))
label=labelMatrix.transpose()
maxround=500
alpha=0.001
for i in range(maxround):
h = sigmoid(dataMatrix * weights)
# print(h)
error = (label-h.transpose()) ##这里的顺序一定不能颠倒
weights=weights+alpha*dataMatrix.transpose()*error ##更新权重,用梯度上升法
return weights.getA() ##转为array
def Plot_final(weights,dataMat,labelMat):
dataArray=np.array(dataMat)
n,m=np.shape(dataArray)
x1=[]
y1=[]
x2=[]
y2=[]
for i in range(n):
if int(labelMat[i])==1:
x1.append(dataArray[i,1])
y1.append(dataArray[i,2])
else:
x2.append(dataArray[i,1])
y2.append(dataArray[i,2])
fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(x1,y1,s=30,c='red',marker='s')
ax.scatter(x2,y2,s=30,c='green')
x=np.arange(-3.0,3.0,0.1) ##等差数列
y=(-weights[0][0]-weights[1][0]*x)/weights[2][0]
ax.plot(x,y)
plt.xlabel('x1')
plt.ylabel('x2')
plt.show()
if __name__=='__main__':
root='F:\机器学习实战源代码和数据\machinelearninginaction\Ch05\\testSet.txt'
dataMat,labelMat=DataLoader(root)
weights=gradAscent(dataMat,labelMat)
print(weights)
Plot_final(weights,dataMat,labelMat)
结果图:
随机梯度上升法如下:
import random
import logisticRegred
import numpy as np
import matplotlib as plt
##随机梯度上升法(改进)
def stocGradAscent1(dataMat,labelMat,numInter=150): ##默认设定为循环150次
m,n=len(dataMat),len(dataMat[0])
weights=np.ones(n)
for i in range(numInter):
dataIndex=range(m) ##产生的是列表
for j in range(m):
randIndex=int(random.uniform(0,len(dataIndex)))
alpha=4.0/(1.0+i+j)+0.01
h=sigmoid1(sum(dataMat[randIndex]*weights))
error=labelMat[randIndex]-h
# print(type(dataMat[randIndex]))
weights=weights+alpha*error*np.array(dataMat[randIndex])
res=[]
for w in range(len(weights)):
res.append([weights[w]])
return res
def sigmoid1(x):
# print(n)
if x>=0:
return (1.0/(1+np.exp(-x))) ##这里用math.exp不行,因为是处理矩阵
if x<0:
return (np.exp(x)/(1+np.exp(x)))
if __name__=='__main__':
root='F:\机器学习实战源代码和数据\machinelearninginaction\Ch05\\testSet.txt'
dataMat,labelMat=logisticRegred.DataLoader(root)
weights=stocGradAscent1(dataMat,labelMat)
print(type(weights))
logisticRegred.Plot_final(weights,dataMat,labelMat)
结果:
参考网址:
https://www.zhihu.com/question/24658302
https://www.zhihu.com/question/57747902