开始学习机器学习有一段时间了,只是大部分精力都用在看视频和看书上面,反而忽略了动手编程的重要性,最近开始陆续把欠下的债给补回来,今天就是把Logistic回归的应用代码实现了一下,话说好记性不如烂笔头,还是写下来的好
首先,对于逻辑回归问题实际也就是分类问题,数据的label只有是或否(即1或0)
因此我们在找假设函数时,希望这个函数最后的输出值能分布在0-1之间,并且预测值表示的是P(y=1),也就是label=1的概率大小。这时,sigmoid函数就派上大用场,该函数可以实现非线性映射,使得结果落在(0,1)中。
对于逻辑回归模型(Logistic Regression, LR)的详细介绍可以参考这个博文,讲解的比较全面。https://blog.csdn.net/weixin_39910711/article/details/81607386
对于上述无约束优化问题,有多种优化方法,包括梯度下降法,随机梯度下降法,牛顿法,共轭梯度法等等。详细的优化方法介绍可以自己查阅,本次结合一个作业练习,实现根据学生的两门考试成绩来预测能否被学校录取。数据集可以在这里下载。代码使用python编写,使用的时Jupyter Notebook,在结果展示中通过动态绘制收敛的效果图,可以清晰的看出算法的迭代过程直至收敛。具体代码如下所示:
%matplotlib qt5
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
data=pd.read_csv('ex4Data\ex4x.dat', names=['exam1', 'exam2'],sep='\s+')
label=pd.read_csv('ex4Data\ex4y.dat',names=['admitted'],sep='\s+')
#label.head() 查看数据集的前五行
data.insert(0,'ones',1)
is_ipython = 'qt5' in matplotlib.get_backend()
if is_ipython:
from IPython import display
plt.ion()
dataArr=np.array(data)
labelArr=np.array(label)
n=np.shape(dataArr)[0]
xcord0=[]
ycord0=[]
xcord1=[]
ycord1=[]
for i in range(n):
if int(labelArr[i])==1:
xcord1.append(dataArr[i,1]);ycord1.append(dataArr[i,2])
else:
xcord0.append(dataArr[i,1]);ycord0.append(dataArr[i,2])
fig = plt.figure()
fig.set_size_inches(12,6)
ax = fig.add_subplot(121)
ax.scatter(xcord0,ycord0,s=30,c='red',marker='+', label='Not Admitted')
ax.scatter(xcord1,ycord1,s=30,c='green',label='Admitted')
ax.legend(loc=1) #设置图标在右上角
x = np.linspace(1, 100, 2)
def plotFit(W):
ax.set_xlim(1, 100)
ax.set_ylim(1, 100)
ax.set_xlabel('Exam 1 Score')
ax.set_ylabel('Exam 2 Score')
ax.set_title('Decision Boundary')
y=(-W[0]-W[1]*x)/W[2]
lines = ax.plot(x,y,'b')
plt.pause(0.1)
ax.lines.remove(lines[0])
def plotloss(ilist,loss_list):
ax = fig.add_subplot(122)
ax.set_xlabel('iteration')
ax.set_ylabel('loss')
ax.set_title('loss trend')
ax.plot(np.array(ilist),np.array(loss_list),'r.-')
plt.pause(0.1) # pause a bit so that plots are updated
if is_ipython:
display.clear_output(wait=True)
display.display(plt.gcf())
def main():
X=np.array(data)
Y=np.array(label).reshape(-1,1) #不管有多少行,变成一列
# W=np.random.randn(3,1).reshape((-1,1))
W=np.zeros((3,1))
m=len(X)
loss_list=[]
ilist=[]
rate=0.001
for i in range(200):
z=np.dot(X,W)
h_x=1/(1+np.exp(-z))
loss=(-Y)*np.log(h_x)-(1-Y)*np.log(1-h_x)
loss=np.sum(loss)/m
dW=X.T.dot(h_x-Y)/m #实现求梯度
W=W-rate*dW
#print("第%i次迭代后:%f"%(i,loss))
if(i%5==0):
plotFit(W)
loss_list.append(loss)
ilist.append(i)
plotloss(ilist,loss_list)
y=(-W[0]-W[1]*x)/W[2]
lines = ax.plot(x,y,'b')
print('W最优解:')
print(W)
print(loss)
if __name__ == '__main__':
main()
收敛至最终结果如下图