逻辑回归

本次作业的目的是建立一个逻辑回归模型,用于预测一个学生是否应该被大学录取。

简单起见,大学通过两次考试的成绩来确定一个学生是否应该录取。你有以前数届考生的成绩,可以做为训练集学习逻辑回归模型。每个训练样本包括了考生两次考试的成绩和对应的录取决定。

你的任务是建立一个分类模型,根据两次考试的成绩来估计考生被录取的概率。
本次实验需要实现的函数

  • plot_data 绘制二维的分类数据。
  • sigmoid函数
  • cost_function 逻辑回归的代价函数
  • cost_gradient 逻辑回归的代价函数的梯度,无正则化
  • predict 逻辑回归的预测函数
  • cost_function_reg 逻辑回归带正则化项的代价函数
  • cost_gradient_reg 逻辑回归的代价函数的梯度,带正则化
# Python2 兼容于Python3的指令
from __future__ import print_function# 导入需要用到的库
import numpy as np
import scipy.optimize as op
import matplotlib.pyplot as plt

数据可视化

在实现机器学习算法前,可视化的显示数据以观察其规律通常是有益的。本次作业中,你需要实现 plot_data 函数,用于绘制所给数据的散点图。你绘制的图像应如下图所示,两坐标轴分别为两次考试的成绩,正负样本分别使用不同的标记显示。

def plot_data(X, y):"""This function plots the data points X and y into a new figure.It plots the data points with red + for the positive examples,and blue o the negative examples. X is assumed to be a Mx2 matrix.X: shape:nx2 y: shape:nx1"""plt.figure()# ====================== YOUR CODE HERE ======================mask = (y == 1)plt.plot(X[mask,0], X[mask,1], 'r+', label = "Admitted")mask = (y == 0)plt.plot(X[mask,0], X[mask,1], 'bo', label = "Not admitted")# ============================================================plt.xlabel("Exam 1 Score")plt.ylabel("Exam 2 Score")plt.legend(loc='upper right')

调用 plot_data,可视化第一个文件LR_data1数据。绘制的图像如下:‘

# 加载数据 注意使用 !ls 或 !find 命令确定数据文件所在的目录 dataXXXX 。
data = np.loadtxt("LR_data1.txt", delimiter=",")
X, y = data[:, :2], data[:, 2]
# 可视化数据
# ====================== YOUR CODE HERE ================
X = np.insert(X, 0, values=1, axis=1)   # 需要新增一行X0,对应于W0,便于下面计算
plot_data(X[:, 1:], y)
# ======================================================
plt.show()

绘制分类面

def plot_decision_boundary(theta, X, y):"""绘制分类面。"""plot_data(X[:, 1:], y)_, d = X.shapeif d <= 3:plot_x = np.array([np.min(X[:, 1])-2, np.max(X[:, 1])+2])plot_y = -1.0 / theta[2]*(theta[1]*plot_x + theta[0])plt.plot(plot_x, plot_y, 'm-', label="Decision Boundary")plt.xlim([30, 100])plt.ylim([30, 100])else:n_grid = 50u = np.linspace(-1, 1.5, n_grid)v = np.linspace(-1, 1.5, n_grid)z = np.zeros((n_grid, n_grid))for i in range(n_grid):for j in range(n_grid):uu, vv = np.array([u[i]]), np.array([v[j]])z[i, j] = np.dot(map_feature(uu, vv), theta)z = z.TCS = plt.contour(u, v, z, linewidths=2, levels=[0.0], colors=['m'])CS.collections[0].set_label('Decision boundary')plt.legend()

热身练习:Sigmoid函数

逻辑回归的假设模型为:
hθ(x)=g(θTx)h_{\theta}(x) = g(\theta^{\mathrm{T}} x)hθ​(x)=g(θTx)

其中函数 g(⋅)g(\cdot)g(⋅) 是Sigmoid函数,定义为:
g(z)=11+exp⁡(−z)g(z) = \frac{1}{1+\exp(-z)}g(z)=1+exp(−z)1​

本练习中第一步需要你实现 Sigmoid 函数。在实现该函数后,你需要确认其功能正确。对于输入为矩阵和向量的情况,你实现的函数应当对每一个元素执行Sigmoid 函数。

def sigmoid(z):"""Compute sigmoid function"""z = np.asarray(z)g = np.zeros_like(z)# ====================== YOUR CODE HERE ======================if z.ndim == 0:g = 1 / (1+np.exp(-z))elif z.ndim == 1:for i in range(z.size):g[i] = 1 / (1+np.exp(-z[i]))else : for i in range((z.shape)[0]):for j in range((z.shape)[1]):g[i,j] = 1 / (1+np.exp(-z[i,j]))# ============================================================return g
# 测试 sigmoid 函数
z = np.array([-10.0, -5.0, 0.0, 5.0, 10.0])
g = sigmoid(z)
print("Value of sigmoid at [-10, -5, 0, 5, 10] are:\n", g)
Value of sigmoid at [-10, -5, 0, 5, 10] are:[4.53978687e-05 6.69285092e-03 5.00000000e-01 9.93307149e-019.99954602e-01]

代价函数与梯度

现在你需要实现逻辑回归的代价函数及其梯度。补充完整cost_function函数,使其返回正确的代价。补充完整cost_gradient函数,使其返回正确的梯度。

逻辑回归的代价函数为:
J(θ)=1m∑i=1m[−y(i)log⁡(hθ(x(i)))−(1−y(i))log⁡(1−hθ(x(i)))]J(\theta) = \frac{1}{m} \sum_{i=1}^{m} \Big[ -y^{(i)} \log \big( h_{\theta}(x^{(i)}) \big) - (1-y^{(i)}) \log \big( 1-h_{\theta}(x^{(i)}) \big) \Big]J(θ)=m1​i=1∑m​[−y(i)log(hθ​(x(i)))−(1−y(i))log(1−hθ​(x(i)))]

对应的梯度向量各分量为
∂J(θ)∂θj=1m∑i=1m(hθ(x(i))−y(i))xj(i)\frac{\partial J(\theta)}{\partial \theta_{j}} = \frac{1}{m} \sum_{i=1}^{m} \big( h_{\theta}(x^{(i)}) - y^{(i)} \big) x_{j}^{(i)}∂θj​∂J(θ)​=m1​i=1∑m​(hθ​(x(i))−y(i))xj(i)​

def cost_function(theta, X, y):"""逻辑回归的代价函数,无正则项。"""J = 0.0# ====================== YOUR CODE HERE ======================# 这里没有使用矩阵,直接循环计算m = 1.0*len(y)for i in range(len(y)):J += ( -y[i] * np.log(sigmoid(np.dot(theta,X[i].T))) -(1-y[i]) * np.log(1-sigmoid(np.dot(theta,X[i].T))))J /= m# ============================================================return J
def cost_gradient(theta, X, y):"""逻辑回归的代价函数的梯度,无正则项。"""m = 1.0*len(y)grad = np.zeros_like(theta)# ====================== YOUR CODE HERE ======================# 这里没有使用矩阵,直接循环计算for j in range(len(grad)):for i in range(len(y)):grad[j] += (sigmoid(np.dot(theta,X[i].T)) - y[i]) * X[i, j]grad[j] /= m# ============================================================return grad

预测函数

在获得模型参数后,你就可以使用模型预测一个学生能够被大学录取。如果某学生考试一的 成绩为45,考试二的成绩为85,你应该能够得到其录取概率约为0.776。

你需要完成 predict 函数,该函数输出“1”或“0”。通过计算分类正确的样本百分数, 我们可以得到训练集上的正确率。

def predict(theta, X):"""Predict whether the label is 0 or 1using learned logistic regression parameters theta.input: theta:model's parametersX: input samplesoutput:0 or 1"""m, _ = X.shapepred = np.zeros((m, 1), dtype=np.bool)# ====================== YOUR CODE HERE ======================# 这里必须为列向量,否则影响后续准确率计算pred = (np.dot(X, theta.T) > 0.5)# ============================================================return pred

使用scipy.optimize.fmin_cg学习模型参数

在本次作业中,希望你使用 scipy.optimize.fmin_cg 函数实现代价函数 J(θ)J(\theta)J(θ) 的优化,得到最佳参数 θ∗\theta^{*}θ∗ 。

使用该优化函数的代码已经在程序中实现,调用方式示例如下:

ret = op.fmin_cg(cost_function,theta,fprime=cost_gradient,args=(X, y),maxiter=400,full_output=True)
theta_opt, cost_min, _, _, _ = ret

其中cost_function为代价函数, theta 为需要优化的参数初始值, fprime=cost_gradient 给出了代价函数的梯度, args=(X, y) 给出了需要优化的函数与对应的梯度计算所需要的其他参数, maxiter=400 给出了最大迭代次数, full_output=True 则指明该函数除了输出优化得到的参数 theta_opt 外,还会返回最小的代价函数值 cost_min 等内容。

对第一组参数,得到的代价约为 0.203 (cost_min)。

def logistic_regression():"""针对第一组数据建立逻辑回归模型。"""# 加载数据data = np.loadtxt("LR_data1.txt", delimiter=",")X, y = data[:, :2], data[:, 2]# 计算代价与梯度m, _ = X.shapeX = np.hstack((np.ones((m, 1)), X))# 初始化参数theta_initial = np.zeros_like(X[0])# 计算并打印初始参数对应的代价与梯度cost = cost_function(theta_initial, X, y)grad = cost_gradient(theta_initial, X, y)print("Cost at initial theta (zeros): ", cost)print("Gradient at initial theta (zeros): \n", grad)# 使用 scipy.optimize.fmin_cg 优化模型参数args = (X, y)maxiter = 200# ====================== YOUR CODE HERE ======================ret = op.fmin_cg(cost_function,theta_initial,fprime=cost_gradient,args=(X, y),maxiter=400,full_output=True)# ============================================================theta_opt, cost_min, _, _, _ = retprint("Cost at theta found by fmin_cg: ", cost_min)print("theta_op: \n", theta_opt)# 绘制分类面plot_decision_boundary(theta_opt, X, y)plt.show()# 预测考试一得45分,考试二得85分的学生的录取概率x_test = np.array([1, 45, 85.0])prob = sigmoid(np.dot(theta_opt, x_test))print('For a student with scores 45 and 85, we predict an admission probability of: ', prob)# 计算在训练集上的分类正确率p = predict(theta_opt, X)print("Train Accuracy: ", np.mean(p == y)*100.)logistic_regression()
Cost at initial theta (zeros):  0.6931471805599458
Gradient at initial theta (zeros): [ -0.1        -12.00921659 -11.26284221]/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/ipykernel_launcher.py:11: RuntimeWarning: divide by zero encountered in log# This is added back by InteractiveShellApp.init_path()
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/ipykernel_launcher.py:11: RuntimeWarning: invalid value encountered in double_scalars# This is added back by InteractiveShellApp.init_path()Optimization terminated successfully.Current function value: 0.203498Iterations: 40Function evaluations: 96Gradient evaluations: 96
Cost at theta found by fmin_cg:  0.2034977015906936
theta_op: [-25.16136665   0.20623215   0.20147168]
For a student with scores 45 and 85, we predict an admission probability of:  0.7762895195156367
Train Accuracy:  89.0

正则化的逻辑回归

数据可视化

调用函数plot_data可视化第二组数据 LR_data2.txt
正确的输出如下:

# 加载数据
data = np.loadtxt("LR_data2.txt", delimiter=",")
X, y = data[:, :2], data[:, 2]# 可视化数据
# ====================== YOUR CODE HERE ================
X = np.insert(X, 0, values=1, axis=1)   # 需要新增一行X0,对应于W0,便于下面计算
plot_data(X[:, 1:], y)
# ======================================================
plt.show()

特征变换

创建更多的特征是充分挖掘数据中的信息的一种有效手段。在函数 map_feature 中,我们将数据映射为其六阶多项式的所有项。

def map_feature(X1, X2, degree=6):"""Feature mapping function to polynomial features."""m = len(X1)assert len(X1) == len(X2)n = int((degree+2)*(degree+1)/2)out = np.zeros((m, n))idx = 0for i in range(degree+1):for j in range(i+1):# print i-j, j, idxout[:, idx] = np.power(X1, i-j)*np.power(X2, j)idx += 1return out

代价函数与梯度

逻辑回归的代价函数为

J(θ)=1m∑i=1m[−y(i)log⁡(hθ(x(i)))−(1−y(i))log⁡(1−hθ(x(i)))]+λ2m∑j=1nθj2J(\theta) = \frac{1}{m} \sum_{i=1}^{m} \left [ -y^{(i)} \log \left (h_{\theta}(x^{(i)}) \right) - (1-y^{(i)}) \log \left ( 1- h_{\theta}(x^{(i)}) \right ) \right ] + \frac{\lambda}{2m} \sum_{j=1}^{n} \theta_{j}^{2}J(θ)=m1​i=1∑m​[−y(i)log(hθ​(x(i)))−(1−y(i))log(1−hθ​(x(i)))]+2mλ​j=1∑n​θj2​

对应的梯度向量各分量为:

完成以下函数:

  • cost_function_reg()
  • cost_gradient_reg()
def cost_function_reg(theta, X, y, lmb):"""逻辑回归的代价函数,有正则项。"""m = 1.0*len(y)J = 0# ====================== YOUR CODE HERE ======================# 这里试下直接使用矩阵计算hx = np.log(sigmoid(np.dot(theta,X.T)))     # 行向量 J = 1/m * ( -y*(np.log(hx).T) - (1-y)*(np.log(1-hx).T) ).sum() + \lmb/(2*m) * (theta**2).sum()# ============================================================return Jdef cost_gradient_reg(theta, X, y, lmb):"""逻辑回归的代价函数的梯度,有正则项。"""m = 1.0*len(y)grad = np.zeros_like(theta)# ====================== YOUR CODE HERE ======================hx = np.log(sigmoid(np.dot(theta,X.T)))     # 行向量for j in range(len(theta)):if j == 0:grad[0] = 1/m * ((hx.T - y)*X[:,0]).sum()else:grad[j] = 1/m * ((hx.T - y)*X[:,j]).sum() + lmb/m * theta[j]# ============================================================return grad

模型训练

如果将参数θ\thetaθ 初始化为全零值,相应的代价函数约为 0.693。可以使用与前述无正则化项类似的方法实现梯度下降,
获得优化后的参数 θ∗\theta^{*}θ∗ 。
你可以调用 plot_decision_boundary 函数来查看最终得到的分类面。建议你调整正则化项的系数,分析正则化对分类面的影响!

参考输出图像:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2MM8aZKs-1584200354366)(https://github.com/fredqi/fredqi.github.io/raw/master/teaching/PRML/LR_data2_boundary.png)]

def logistic_regression_reg(lmb=1.0):"""针对第二组数据建立逻辑回归模型。"""# 加载数据data = np.loadtxt("LR_data2.txt", delimiter=",")X, y = data[:, :2], data[:, 2]# 计算具有正则项的代价与梯度# 注意map_feature会自动加入一列 1X = map_feature(X[:, 0], X[:, 1])print(X.shape)# 初始化参数theta_initial = np.zeros_like(X[0, :])# 计算并打印初始参数对应的代价与梯度cost = cost_function_reg(theta_initial, X, y, lmb=lmb)grad = cost_gradient_reg(theta_initial, X, y, lmb=lmb)print("Cost at initial theta (zeros): ", cost)print("Gradient at initial theta (zeros): \n", grad)# 使用 scipy.optimize.fmin_cg 优化模型参数args = (X, y, lmb)maxiter = 200# ====================== YOUR CODE HERE ======================ret = op.fmin_cg(cost_function,theta_initial,fprime=cost_gradient,args=(X, y),maxiter=500,full_output=True)# ============================================================theta_opt, cost_min, _, _, _ = retprint("Cost at theta found by fmin_cg: ", cost_min)print("theta_op: \n", theta_opt)# 绘制分类面plot_decision_boundary(theta_opt, X, y)plt.title("lambda = " + str(lmb))plt.show()# 计算在训练集上的分类正确率pred = predict(theta_opt, X)print("Train Accuracy: ", np.mean(pred == y)*100)
# 可选:尝试不同正则化系数lmb = 0.0, 1.0, 10.0, 100.0对分类面的影响
# logistic_regression_reg(lmb=0.0)
logistic_regression_reg(lmb=1.0)
# logistic_regression_reg(lmb=10.0)
# logistic_regression_reg(lmb=100.0)
(118, 28)
Cost at initial theta (zeros):  nan
Gradient at initial theta (zeros): [-1.18467260e+00 -4.65712070e-02 -2.18389338e-01 -2.45049174e-014.18929852e-02 -3.21913457e-01 -5.30339806e-02 -2.92836513e-02-1.02804705e-02 -1.46368028e-01 -1.06857758e-01  8.50450038e-03-4.73137915e-02  1.62780518e-02 -1.64842881e-01 -4.20312326e-02-9.76338336e-03 -7.86743789e-03 -1.59698949e-02 -4.02588511e-04-1.07050637e-01 -6.24771115e-02  1.93592555e-03 -1.62746288e-022.44276793e-03 -1.96901780e-02  8.89544592e-03 -1.11215512e-01]/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/ipykernel_launcher.py:9: RuntimeWarning: invalid value encountered in logif __name__ == '__main__':Warning: Maximum number of iterations has been exceeded.Current function value: 0.277720Iterations: 500Function evaluations: 1817Gradient evaluations: 1817
Cost at theta found by fmin_cg:  0.27771999330049135
theta_op: [  2.75016446  -1.66965677   1.79490775 -11.48167045  -8.879176418.41935335   3.8301574   22.18611514  35.74398869   6.5899962745.12059365   7.77598413 -16.55679328  -9.60804506 -41.354419312.41734693  -8.13532007  -5.87078643 -16.47645334 -22.1064439712.57120674 -79.85716929 -40.98339518  -6.57946501  31.20930559-61.01206484 -40.58723581   3.50490949]Train Accuracy:  87.28813559322035

西电-机器学习-逻辑回归相关推荐

  1. [转载] 吴恩达机器学习逻辑回归练习题:逻辑回归及规则化(python实现)

    参考链接: 了解逻辑回归 Python实现 练习题背景:网易云课堂->吴恩达机器学习课程->逻辑回归练习题 对于练习题的详细内容,和课程中推荐的octave编程实现,请见:吴恩达机器学习逻 ...

  2. 机器学习——逻辑回归

    机器学习--逻辑回归 一.逻辑回归 logistic回归又称logistic回归分析,常用于数据挖掘,疾病自动诊断,经济预测等领域.它是一种广义的线性回归分析模型,因此与多重线性回归分析有很多相同之处 ...

  3. 机器学习 逻辑回归算法应用案例

    机器学习 逻辑回归算法应用案例 时间:2020.09.12 出处:https://www.kesci.com/home/project/5bfe39b3954d6e0010681cd1 注明:初学逻辑 ...

  4. 泰坦尼克(机器学习逻辑回归)

    泰坦尼克(机器学习逻辑回归) 原文链接 数据预处理 import pandas as pd train=pd.read_csv('C:/Users/Admin/Downloads/train.csv' ...

  5. 西电机器学习简答题核心考点汇总(期末真题,教材西瓜书)

    文章目录 前言 一.机器学习和深度学习区别以及原因 二.卷积核,池化层作用 三.SVM转化为对偶问题的优点 四.核函数的作用 五.特征的相似度定义,性质 六.预剪枝与后剪枝优缺点 七.密度直接可达,密 ...

  6. EduCoder 机器学习 逻辑回归

    逻辑回归是属于机器学习里面的监督学习,它是以回归的思想来解决分类问题的一种非常经典的二分类分类器.由于其训练后的参数有较强的可解释性,在诸多领域中,逻辑回归通常用作 baseline 模型,以方便后期 ...

  7. 机器学习算法平台alink_机器学习-逻辑回归算法

    1-逻辑回归算法原理推导 逻辑回归算法其实是一个分类算法,是非常经典,优秀的算法.一般我们不知道用哪个分类算法的时候,首先用逻辑回归算法试一试:它不仅可以实现二分类算法,还可以解决多分类问题 逻辑回归 ...

  8. 机器学习-逻辑回归-信用卡检测任务

    信用卡欺诈检测 基于信用卡交易记录数据建立分类模型来预测哪些交易记录是异常的哪些是正常的. 任务流程: 加载数据,观察问题 针对问题给出解决方案 数据集切分 评估方法对比 逻辑回归模型 建模结果分析 ...

  9. Coursera 机器学习 -- 逻辑回归 笔记 【第二周】

    Logistic Regression Model(逻辑回归模型) Cost Function 如下所示,本章讲述了如何拟合cost参数θ: hypothesis函数在图中复习一下,在图中我们的假设函 ...

最新文章

  1. 敏捷软件开发的12个原则
  2. Web运行控制台输出乱码解决总结
  3. NYOJ 920 Trees
  4. 科大星云诗社动态20210317
  5. Qt Creator定位项
  6. Unix 网络编程(四)- 典型TCP客服服务器程序开发实例及基本套接字API介绍
  7. 年轻人选择创业时,最好避开门槛低的行业
  8. GDAL升级到3.0之后遇到的坑
  9. 学土木结构考计算机等级考试,请教各位,我是学土木的,考计算机二级的哪个比较好?...
  10. mysql授权许可_分析MySQL的授权许可
  11. 使用广告终结者屏蔽页面的任意部分
  12. 自然语言处理之语料库
  13. python生词本查单词译文_Kindle 阅读器“生词本”功能详细使用说明
  14. 我的2014--菜鸟慢慢在长大
  15. vue table表格中只有表头加竖线分割
  16. 做题遇到的trick和想法
  17. 【ubuntu】——安装wps
  18. [*CTF2019]She buuctf
  19. 报错: java.lang.IllegalArgumentException: mapper [categoryName] of different type, current_type [text]
  20. 实时渲染:实时、离线、云渲染、混合渲染的区别

热门文章

  1. html中事件监听的使用,Vue.JS入门篇--事件监听
  2. 牛客错题集C++(一)
  3. 使用jsoup入门java爬虫 案例
  4. 小米华为抢占智能家居,智慧家庭时代到来?
  5. 什么是驱动?驱动程序的工作原理?
  6. LaTex环境下在TexStudio中使用minted插入高亮代码
  7. 牛客每日练习----调皮的孩纸,删除子串,哲哲的疑惑
  8. 物联网安全威胁与解决方案调研
  9. 一键装机linux_linux系统学习第十八天《搭建一键装机平台》终结篇-阿里云开发者社区...
  10. 查询建立连接的IP地址