吴恩达机器学习作业(逻辑回归)---maxchet

博客围绕构建逻辑回归模型预测学生是否被大学录取展开。先导入库、读取数据,创建散点图并进行特征缩放,得到特征和目标值。接着介绍sigmoid函数、代价函数和梯度下降,使用高级优化算法计算参数,最后用相关函数显示分类指标、进行预测并得出精准度。
部署运行你感兴趣的模型镜像

题目描述:在训练的初始阶段,我们将要构建一个逻辑回归模型来预测,某个学生是否被大学录取。设想你是大学相关部分的管理者,想通过申请学生两次测试的评分,来决定他们是否被录取。现在你拥有之前申请学生的可以用于训练逻辑回归的训练样本集。对于每一个训练样本,你有他们两次测试的评分和最后是被录取的结果。为了完成这个预测任务,我们准备构建一个可以基于两次测试评分来评估录取可能性的分类模型。

1.导入相应的库

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.optimize as opt  #用来寻找最优参数的
from sklearn.metrics import classification_report#这个包是评价报告

2.读取相关数据

df = pd.read_csv('D:\machine learning\logistic learning\ex2data1.csv',names = ['考试1','考试2','录取结果'])
df.head()

output:
考试1 考试2 录取结果
0 34.623660 78.024693 0
1 30.286711 43.894998 0
2 35.847409 72.902198 0
3 60.182599 86.308552 1
4 79.032736 75.344376 1

3.创建两个分数的散点图(本部分参考黄海广先生代码)

sns.set(context='notebook',style='whitegrid') 
sns.lmplot('考试1','考试2',data=df,
            hue='录取结果',                    
           size=6,                             #定义子图中每一格尺寸的高度,单位应为英寸
           fit_reg=False,                      #不画拟合直线
           scatter_kws={"s": 50}  
           #附加的关键字参数以字典的形式传递给plt.scatter()函数
           #将plt.scatter()的参数s的值改为50,默认值为20 ,参数s代表散点的大小
          )
plt.show()

output:
在这里插入图片描述

4.特征缩放

df = (df - df.main())/df.std()
df.head()

output:

考试1 考试2 录取结果
0 -1.594216 0.635141 -1.218606
1 -1.817101 -1.201489 -1.218606
2 -1.531325 0.359483 -1.218606
3 -0.280687 1.080923 0.812404
4 0.688062 0.490905 0.812404

5.得到特征X,和y

df.insert(0,'ONE',1)  #在第0列插入表头为“ONE”的列,数值为1
df.head()
X = df.iloc[:,0:3]                 #从数据中得到X
X.head()
x1 = df.iloc[:,2:3]
x2 = df.iloc[:,3:4]
x1.head()
x2.head()
y = df.iloc[:,3:4]
y.head()

容易漏掉的一步

X = np.matrix(X.values)
y = np.matrix(y.values)
theta = np.matrix(np.array([0,0,0]))

6.sigmoid函数

def sigmoid(z):  
    return 1/(1+np.exp(-z))

这一部分借鉴黄海广先生代码

#检查一下sigmoid函数是否正常可用
nums = np.arange(-10, 10, step=1)  #以-10为起点,10为终点,步长为1的列表
fig, ax = plt.subplots(figsize=(12,8))#以其他关键字参数**fig_kw来创建图
#figsize=(a,b):figsize 设置图形的大小,b为图形的宽,b为图形的高,单位为英寸
ax.plot(nums, sigmoid(nums), 'r')   
plt.show()

output:
在这里插入图片描述

7.代价函数
代价函数:
J(θ)=1m∑i=1m[−y(i)log⁡(hθ(x(i)))−(1−y(i))log⁡(1−hθ(x(i)))]J\left( \theta \right)=\frac{1}{m}\sum\limits_{i=1}^{m}{[-{{y}^{(i)}}\log \left( {{h}_{\theta }}\left( {{x}^{(i)}} \right) \right)-\left( 1-{{y}^{(i)}} \right)\log \left( 1-{{h}_{\theta }}\left( {{x}^{(i)}} \right) \right)]}J(θ)=m1i=1m[y(i)log(hθ(x(i)))(1y(i))log(1hθ(x(i)))]

def computecost(X,y,theta):
    cost = np.multiply(-y,np.log(sigmoid(X*theta.T))) - np.multiply(1-y,np.log(1 - sigmoid(X*theta.T)))
    J = np.sum(cost) / (len(X))                 #!!!本人再次忘记取和即np.sum,导致结果出现矩阵
    
    return J
computecost(X,y,theta)

output:
0.69314718055994529

8.梯度下降

  • 转化为向量化计算: 1mXT(Sigmoid(Xθ)−y)\frac{1}{m} X^T( Sigmoid(X\theta) - y )m1XT(Sigmoid(Xθ)y)
    ∂J(θ)∂θj=1m∑i=1m(hθ(x(i))−y(i))xj(i)\frac{\partial J\left( \theta \right)}{\partial {{\theta }_{j}}}=\frac{1}{m}\sum\limits_{i=1}^{m}{({{h}_{\theta }}\left( {{x}^{(i)}} \right)-{{y}^{(i)}})x_{_{j}}^{(i)}}θjJ(θ)=m1i=1m(hθ(x(i))y(i))xj(i)
def gradient(theta, X, y):
    theta=np.matrix(theta) #将theta转换为矩阵
    X=np.matrix(X) #将X转换为矩阵
    y=np.matrix(y) #将y转换为矩阵
    
    temp=np.matrix(np.zeros(theta.shape)) #np.zeros(theta.shape)=[0.,0.],然后将temp变为矩阵[0.,0.]
    parameters= int(theta.ravel().shape[1])  
    #theta.ravel():将多维数组theta降为一维,.shape[1]是统计这个一维数组有多少个元素
    #parameters表示参数
    grad = np.zeros(parameters)
    
    error = sigmoid(X * theta.T) - y
    
    for i in range(parameters):
        term = np.multiply(error, X[:,i]) #将误差与训练数据相乘,
        grad[i] = np.sum(term) / len(X)
    
    return grad

在以上部分中,其实并没有进行梯度下降,只是计算了梯度步长

gradient(theta, X, y)

output:
array([ -0.1 , -12.00921659, -11.26284221])

9.使用“fminunc”函数来优化函数来计算成本和梯度参数。
在之前的学习中,我们都是通过使用梯度下降算法来最小化代价函数J
在这里,我们使用高级优化算法,思路是:求导J,通过fminunc函数来最小化,得到此时的theta

import scipy.optimize as opt
result = opt.fmin_tnc(func=cost, x0=theta, fprime=gradient, args=(X, y))  #本函数具体用法见博客!!!
result  

fmin_tnc()函数使用:
有约束的多元函数问题,提供梯度信息,使用截断牛顿法。

调用:

scipy.optimize.fmin_tnc(func, x0, fprime=None, args=(), approx_grad=0, bounds=None, epsilon=1e-08, scale=None, offset=None, messages=15, maxCGit=-1, maxfun=None, eta=-1, stepmx=0, accuracy=0, fmin=0, ftol=-1, xtol=-1, pgtol=-1, rescale=-1, disp=None, callback=None)

最常使用的参数:
func:优化的目标函数
x0:初值
fprime:提供优化函数func的梯度函数,不然优化函数func必须返回函数值和梯度,或者设置approx_grad=True
approx_grad :如果设置为True,会给出近似梯度
args:元组,是传递给优化函数的参数
返回:
x : 数组,返回的优化问题目标值
nfeval : 整数,function evaluations的数目

在进行优化的时候,每当目标优化函数被调用一次,就算一个function evaluation。在一次迭代过程中会有多次function evaluation。这个参数不等同于迭代次数,而往往大于迭代次数。

rc : int,Return code, see below

cost(result[0], X, y)

ouput:0.20349770158947425

10.使用classification_report函数显示主要分类指标的文本报告(借鉴黄海广先生代码)

def predictA(x, theta):
    prob = sigmoid(x @ theta)
    return (prob >= 0.5).astype(int)  #.astype():将大于0.5的函数值转化为整型,即取整。
final_theta1 = result[0]  #取最优参数中优化问题目标值数组x
y_pred = predictA(X, final_theta1)

print(classification_report(y, y_pred))  #classification_report函数用于显示主要分类指标的文本报告

output:
precision recall f1-score support

      0       0.87      0.85      0.86        40
      1       0.90      0.92      0.91        60

avg / total 0.89 0.89 0.89 100

**

from sklearn.metrics import classification_report#这个包是评价报告

其中列表左边的一列为分类的标签名,右边support列为每个标签的出现次数.avg / total行为各列的均值(support列为总和).
precision recall f1-score三列分别为各个类别的精确度/召回率及 F1 F1值.**

11.预测
(1)
当sigmoid函数值>0.5,输出1
当sigmoid函数值<0.5,输出0

def predictB(theta, X):
    probability = sigmoid(X * theta.T)    #sigmoid函数
    return [1 if probability >= 0.5 else 0 for probability in probability]  #大于0.5的数取值为1,小于0.5的为0

(2)借鉴黄海广先生的代码
首先将之前使用funcmin函数优化好的theta值代入predict函数,让特征值X与之相乘得到sigmoid函数。
通过判断预测值和实际的y的正确率。
最终输出的是精准度

theta_min = np.matrix(result[0]) #将最优化最优参数中优化问题目标值数组x转化为矩阵
predictions = predictB(theta_min, X)
correct = [1 if ((a == 1 and b == 1) or (a == 0 and b == 0)) else 0 for (a, b) in zip(predictions, y)]
#predictions为预测值,y为实际值.zip为打包对象函数,将(predictions, y)打包成元组,并赋值为(a,b),然后判断正确的则返回1,判断错误的返回0
accuracy = (sum(map(int, correct)) % len(correct))
# map(int, correct):将crrect列表内容的类型映射成int型,原来应该布尔型.sum为求和函数,%为求模运算,计算除法的余数。
#实际是求1占数据总数的比例(√)
print ('accuracy = {0}%'.format(accuracy))  #format为格式化字符串的函数,{0}为设置指定位置.

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lorimmmm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值