ML Practice2 Logistic Regression

梯度下降法

logistic回归假设 采用了sigmoid函数,因为预测值即代表该例被分类为1的概率,预测值应规范在0-1之间以计算与实际值1/0的差距(分类算法如只含两类通常将结果分为1和0)。


sigmoid function

与此同时,采用常用对数函数来计算代价,使得预测值越接近实际值代价就越小越远离实际值代价就越大。


cost function

继续采用梯度下降算法来逼近拟合参数theta。


theta更新

【代码】

import numpy as np
import matplotlib.pyplot as plt

filepath='/Users/husir/Desktop/ex2data1.txt'
datafile=open(filepath, 'r')
data=datafile.readlines()
#print(*data)
#print(len(data))

Exam1score=[float(x.split(',')[0]) for x in data]
Exam2score=[float(x.split(',')[1]) for x in data]
IfAdmit=[int(x.split(',')[2]) for x in data]
#print(*Exam1score)
#print(*IfAdmit)
#print(len(IfAdmit))

for i in range(len(IfAdmit)):
    plt.plot(Exam1score[i],Exam2score[i],'gx' if IfAdmit[i]==1 else 'ro')
plt.xlabel('Exam1score');
plt.ylabel('Exam2score');
# 绿叉是Admitted,红点是Not Admitted
散点图

两个特征的值域与分类值1/0相比太大,因此先进行特征缩放(之前忘了缩放所以theta参数变化的超慢超慢超慢,搞得我以为我过程写错了)

Exam1score=[p/100 for p in Exam1score]
Exam2score=[q/100 for q in Exam2score]
for i in range(len(IfAdmit)):
    plt.plot(Exam1score[i],Exam2score[i],'gx' if IfAdmit[i]==1 else 'ro')
plt.xlabel('Exam1score');
plt.ylabel('Exam2score');
缩放后的散点图
m=len(IfAdmit)
x=np.ones((m,3))
y=np.ones((m,1))
for i in range(m):
    x[i][1]=Exam1score[i]
    x[i][2]=Exam2score[i]
    y[i]=IfAdmit[i]

theta=np.ones((3,1))
alpha=1 #学习速率
iteration=1500 #迭代次数
h=np.zeros((m,1))
temp=np.zeros((m,3))

for k in range(iteration):
    for i in range(m):
        h[i]=1/(1+np.exp(-np.dot(theta.T,x[i]))) #这里的dot实际上是对一维数组(数组与矩阵不同)进行了点乘求和
        temp[i]=(h[i]-y[i])*x[i]
        
    theta-=alpha/m*(sum(temp).reshape(3,1))

print(theta)

得到theta值:

[[-13.25487861]
 [ 11.09447317]
 [ 10.48858765]]

最后绘制决策边界:

for i in range(len(IfAdmit)):
    plt.plot(Exam1score[i],Exam2score[i],'gx' if IfAdmit[i]==1 else 'ro')
plt.xlabel('Exam1score')
plt.ylabel('Exam2score')
a=np.linspace(min(Exam1score),max(Exam1score),5)
predicty=-(theta[0]+theta[1]*a)/theta[2]
plt.plot(a,predicty)
决策边界

由于只考虑了三种特征(包括一个常数1),最后画出来的决策边界是线性的,如果多考虑一些会画出更贴合的决策边界(如x1x2,x1^2, x2^2等)。

补充

  1. 特征缩放很重要
  2. 上一次末尾写的矩阵点乘和乘法,并不准确。今天发现python的numpy定义出来的矩阵和数组是不同的东西。如下图所示。
    不同的创建方法
    详细描述Python列表、Numpy数组与矩阵的区别,因此各种计算乘法的符号和函数也应细分分析。具体的叙述可见该贴 python中np.multiply()、np.dot()和星号(*)三种乘法运算的区别(转)
    因为两者混着用实在不明智,且array足以包含matrix的操作,所以推荐全部使用数组来处理。
    数组的点乘:np.multiply(a,b),a*b
    数组的乘法:np.dot(a,b)(仅对非一维数组有效
    数组的点乘求和:np.dot(a1,b1)(仅对一维数组有效)(其实最后结果跟1*n的向量乘上n*1的向量效果一样)

最近有点累,但是要快些自我调节!不断进步才是yyds!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容