验证性实验 - 逻辑回归

news/2024/11/9 5:17:49/

练习2:逻辑回归


介绍

在本练习中,您将实现逻辑回归并将其应用于两个不同的数据集。还将通过将正则化加入训练算法,来提高算法的鲁棒性,并用更复杂的情形来测试模型算法。

在开始练习前,需要下载如下的文件进行数据上传

  • ex2data1.txt -前半部分的训练数据集
  • ex2data2.txt -后半部分的训练数据集

在整个练习中,涉及如下的必做作业

  • 绘制2D分类数据的函数----(3分)
  • 实现Sigmoid函数--------(5分)
  • 实现Logistic回归代价函数和梯度函数—(60分)
  • 实现回归预测函数--------(5分)
  • 实现正则Logisitic回归成本函数-------(27分)

1 Logistic回归

在该部分练习中,将建立一个逻辑回归模型,用以预测学生能否被大学录取。

假设你是大学某个部门的负责人,你要根据两次考试的结果来决定每个申请人的入学机会。目前已经有了以往申请者的历史数据,并且可以用作逻辑回归的训练集。对于每行数据,都包含对应申请者的两次考试分数和最终的录取结果。

在本次练习中,你需要建立一个分类模型,根据这两次的考试分数来预测申请者的录取结果

1.1 数据可视化

在开始实施任何算法模型之前,最好先对数据进行可视化,这将会更加直观的获取数据特征。

现在,你需要编写代码来完成数据的绘图

要点

  • 导入需要使用的python库,并将从文件ex2data1.txt中读取数据,并显示前5行
  • x-y轴分别为两次考试的分数
  • 正负示例需要用不同的标记显示(不同的颜色)

In [1]:

###在这里填入代码###
###主要实现要点1###
import numpy as np
import pandas as pd
import matplotlib.pyplot as pltpath = 'ex2data1.txt'
data = pd.read_csv(path, header=None, names=['Exam 1', 'Exam 2', 'Admitted'])
print(data.head())

Out[1]:

Exam 1Exam 2Admitted
034.62366078.0246930
130.28671143.8949980
235.84740972.9021980
360.18259986.3085521
479.03273675.3443761

In [2]:

###在这里填入代码###
###绘制数据散点图###
positive = data[data['Admitted'].isin([1])]
negative = data[data['Admitted'].isin([0])]fig, ax = plt.subplots(figsize=(12,8))
ax.scatter(positive['Exam 1'], positive['Exam 2'], s=50, c='b', marker='o', label='Admitted')
ax.scatter(negative['Exam 1'], negative['Exam 2'], s=50, c='r', marker='x', label='Not Admitted')
ax.legend()
ax.set_xlabel('Exam 1 Score')
ax.set_ylabel('Exam 2 Score')
plt.show()

在这里插入图片描述

1.2 实现

在前部分练习中所绘制的数据分布图中可以看出,在不同标识的数据点间,有一个较为清晰的决策边界。现在需要实现逻辑回归,并使用逻辑回归来训练模型用以预测分类结果。

1.2.1 Sigmoid函数

你需要编写代码实现Sigmoid函数,编写后试着测试一些值,如果x的正值较大,则函数值应接近1;如果x的负值较大,则函数值应接近0。而对于x等于0时,则函数值为0.5。

In [3]:

###在这里填入代码###
def sigmoid(z):return 1 / (1 + np.exp(-z))

In [4]:

###请运行并测试你的代码###
nums = np.arange(-10, 10, step=1)fig, ax = plt.subplots(figsize=(12,8))
ax.plot(nums, sigmoid(nums), 'r')
plt.show()

在这里插入图片描述

1.2.2 代价函数和梯度

1.2.2.1 代价函数

你需要编写代码实现代价函数以进行逻辑回归的成本计算,并且经过所给数据测试后,初始的成本约为0.693。

要点

  • 实现cost函数,参数为theta,X,y.
  • 返回计算的成本值。
  • 其中theta为参数,X为训练集中的特征列,y为训练集的标签列,三者均为矩阵。

In [5]:

###在这里填入代码###
def cost(theta,X,y):theta = np.matrix(theta)X = np.matrix(X)y = np.matrix(y)first = np.multiply(-y,np.log(sigmoid(X* theta.T)))second = np.multiply((1-y),np.log(1-sigmoid(X*theta.T)))return np.sum(first-second)/(len(X))

In [6]:

###请运行并测试你的代码###
#增加一列值为1,这和我们在练习1中的操作很相似
data.insert(0, 'Ones', 1)# 定义X为训练数据,y为目的变量
cols = data.shape[1]
X = data.iloc[:,0:cols-1]
y = data.iloc[:,cols-1:cols]# 将X,y转换为numpy数组,并初始化theta值为0
X = np.array(X.values)
y = np.array(y.values)
theta = np.zeros(3)cost(theta, X, y)

Out[6]:

0.6931471805599453
1.2.2.2 梯度下降

接下来,我们需要编写代码实现梯度下降用来计算我们的训练数据、标签和一些参数的梯度

要点

  • 代码实现gradient函数,参数为theta,X,y.
  • 返回计算的梯度值。
  • 其中theta为参数,X为训练集中的特征列,y为训练集的标签列,三者均为矩阵。

In [7]:

###在这里填入代码###
def gradient(theta, X, y):theta = np.matrix(theta)X = np.matrix(X)y = np.matrix(y)parameters = int(theta.ravel().shape[1])grad = np.zeros(parameters)error = sigmoid(X * theta.T) - yfor i in range(parameters):term = np.multiply(error, X[:,i])grad[i] = np.sum(term) / len(X)return grad

In [8]:

###请运行并测试你的代码###
gradient(theta, X, y)

Out[8]:

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

1.2.3 寻找最优参数

现在可以用SciPy’s truncated newton(TNC)实现寻找最优参数。

In [9]:

###请运行并测试你的代码###
import scipy.optimize as opt
result = opt.fmin_tnc(func=cost, x0=theta, fprime=gradient, args=(X, y))
result

Out[9]:

(array([-25.16131872,   0.20623159,   0.20147149]), 36, 0)

让我们看看在这个结论下代价函数的值:

In [10]:

###请运行并测试你的代码###
cost(result[0], X, y)

Out[10]:

0.20349770158947425

1.2.4 评估逻辑回归

接下来,我们需要编写代码实现预测函数,用所学的最优参数𝜃�来为数据集X输出预测结果。然后,可以使用这个函数来给我们定义的分类器的训练精度进行打分。

要点

  • 代码实现predict函数,参数为theta,X.
  • 返回X中的每行数据对应的预测结果。
  • 其中theta为参数,X为训练集中的特征列。

In [11]:

###在这里填入代码###
def predict(theta, X):probability = sigmoid(X * theta.T)return [1 if x >= 0.5 else 0 for x in probability]

In [14]:

###请运行并测试你的代码###
theta_min = np.matrix(result[0])
predict(theta_min, X)

Out[14]:

[0,0,0,1,1,0,1,0,1,1,1,0,1,1,0,1,0,0,1,1,0,1,0,0,1,1,1,1,0,0,1,1,0,0,0,0,1,1,0,0,1,0,1,1,0,0,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,0,0,1,0,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,1,1,0,1]

In [12]:

###请运行并测试你的代码###
#theta_min = np.matrix(result[0])
predictions = predict(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)]
accuracy = (sum(map(int, correct)) % len(correct))
print ('accuracy = {0}%'.format(accuracy))
accuracy = 89%

2 正则化逻辑回归

在本部分练习中,我们将要通过加入正则项提升逻辑回归算法。

正则化是成本函数中的一个术语,它使算法更倾向于“更简单”的模型。这个理论助于减少过拟合,提高模型的泛化能力。

设想你是工厂的生产主管,你有一些芯片在两次测试中的测试结果。对于这两次测试,你想决定芯片是要被接受或抛弃。为了帮助你做出艰难的决定,你拥有过去芯片的测试数据集,从其中你可以构建一个逻辑回归模型

2.1 数据可视化

与第一部分的练习类似,首先对数据进行可视化:

In [25]:

path =  'ex2data2.txt'
data2 = pd.read_csv(path, header=None, names=['Test 1', 'Test 2', 'Accepted'])
data2.head()

Out[25]:

Test 1Test 2Accepted
00.0512670.699561
1-0.0927420.684941
2-0.2137100.692251
3-0.3750000.502191
4-0.5132500.465641

In [16]:

positive = data2[data2['Accepted'].isin([1])]
negative = data2[data2['Accepted'].isin([0])]fig, ax = plt.subplots(figsize=(12,8))
ax.scatter(positive['Test 1'], positive['Test 2'], s=50, c='b', marker='o', label='Accepted')
ax.scatter(negative['Test 1'], negative['Test 2'], s=50, c='r', marker='x', label='Rejected')
ax.legend()
ax.set_xlabel('Test 1 Score')
ax.set_ylabel('Test 2 Score')
plt.show()

在这里插入图片描述

对于这部分数据,我们可以看出不同类别的数据点之间没有明显的线性决策界限用于划分两类数据。

因此,逻辑回归无法在此数据集上得到较好的效果,因为逻辑回归只能知道线性决策边界。

2.2 特征映射

一种能够更好地拟合数据的方法是构造从原始特征的多项式中得到的特征,即特征映射。

在这个高维特征向量上训练的逻辑回归分类器将具有更复杂的决策边界,并在二维图中绘制时呈现非线性的划分曲线。

虽然特征映射允许我们构建一个更具有表现力的分类器,但它也更容易过拟合。接下来,你需要实现正则化逻辑回归用于拟合数据,并使用正则化来帮助解决过拟合问题

我们通过创建一组多项式特征来开始!

In [26]:

# 设定映射深度
degree = 5
# 分别取两次测试的分数
x1 = data2['Test 1']
x2 = data2['Test 2']data2.insert(3, 'Ones', 1)# 设定计算方式进行映射
for i in range(1, degree):for j in range(0, i):data2['F' + str(i) + str(j)] = np.power(x1, i-j) * np.power(x2, j)# 整理数据列
data2.drop('Test 1', axis=1, inplace=True)
data2.drop('Test 2', axis=1, inplace=True)print("特征映射后具有特征维数:%d" %data2.shape[1])
data2.head()
特征映射后具有特征维数:12

Out[26]:

AcceptedOnesF10F20F21F30F31F32F40F41F42F43
0110.0512670.0026280.0358640.0001350.0018390.0250890.0000070.0000940.0012860.017551
111-0.0927420.008601-0.063523-0.0007980.005891-0.0435090.000074-0.0005460.004035-0.029801
211-0.2137100.045672-0.147941-0.0097610.031616-0.1024120.002086-0.0067570.021886-0.070895
311-0.3750000.140625-0.188321-0.0527340.070620-0.0945730.019775-0.0264830.035465-0.047494
411-0.5132500.263426-0.238990-0.1352030.122661-0.1112830.069393-0.0629560.057116-0.051818

2.3 代价函数和梯度

接下来,你需要编写代码来实现计算正则化逻辑回归的代价函数和梯度,并返回计算的代价值和梯度

In [32]:

###在这里填入代码###
def costReg(theta, X, y, learningRate):theta = np.matrix(theta)X = np.matrix(X)y = np.matrix(y)first = np.multiply(-y, np.log(sigmoid(X * theta.T)))second = np.multiply((1 - y), np.log(1 - sigmoid(X * theta.T)))reg = (learningRate / (2 * len(X))) * np.sum(np.power(theta[:,1:theta.shape[1]], 2))return np.sum(first - second) / len(X) + reg

接下来,我们需要实现正则化梯度函数,使用梯度下降法使得代价函数最小化。

In [28]:

###在这里填入代码###
def gradientReg(theta, X, y, learningRate):theta = np.matrix(theta)X = np.matrix(X)y = np.matrix(y)parameters = int(theta.ravel().shape[1])grad = np.zeros(parameters)error = sigmoid(X * theta.T) - yfor i in range(parameters):term = np.multiply(error, X[:,i])if (i == 0):grad[i] = np.sum(term) / len(X)else:grad[i] = (np.sum(term) / len(X)) + ((learningRate / len(X)) * theta[:,i])return grad

接下来,类似于第一部分的练习中,进行变量的初始化。

In [30]:

# 从数据集中取得对应的特征列和标签列
cols = data2.shape[1]
X2 = data2.iloc[:,1:cols]
y2 = data2.iloc[:,0:1]# 转换为Numpy数组并初始化theta为零矩阵
X2 = np.array(X2.values)
y2 = np.array(y2.values)
theta2 = np.zeros(11)# 设置初始学习率为1,后续可以修改
learningRate = 1

接下来,使用初始化的变量值来测试你实现的代价函数和梯度函数。

In [33]:

###请运行并测试你的代码###
costReg(theta2, X2, y2, learningRate)

Out[33]:

0.6931471805599454

In [34]:

###请运行并测试你的代码###
gradientReg(theta2, X2, y2, learningRate)

Out[34]:

array([0.00847458, 0.01878809, 0.05034464, 0.01150133, 0.01835599,0.00732393, 0.00819244, 0.03934862, 0.00223924, 0.01286005,0.00309594])

2.4 寻找最优参数

现在我们可以使用和第一部分相同的优化函数来计算优化后的结果。

In [35]:

result2 = opt.fmin_tnc(func=costReg, x0=theta2, fprime=gradientReg, args=(X2, y2, learningRate))
result2

Out[35]:

(array([ 0.53010248,  0.29075567, -1.60725764, -0.58213819,  0.01781027,-0.21329508, -0.40024142, -1.37144139,  0.02264304, -0.9503358 ,0.0344085 ]), 22, 1)

2.5 评估正则化逻辑回归

最后,我们可以使用第1部分中的预测函数来查看我们的方案在训练数据上的准确度。

In [36]:

theta_min = np.matrix(result2[0])
predictions = predict(theta_min, X2)
correct = [1 if ((a == 1 and b == 1) or (a == 0 and b == 0)) else 0 for (a, b) in zip(predictions, y2)]
accuracy = (sum(map(int, correct)) % len(correct))
print ('accuracy = {0}%'.format(accuracy))
accuracy = 78%

http://www.ppmy.cn/news/439240.html

相关文章

一点直播卡顿的处理思考

投屏软件有几个指标: 1,首屏过去的时间(T0)要尽可能短。 2,发送端与接收端的时间差(T1)要尽可能短。 3,如果T1值不断变大,要能及时纠正回去。目前的现象是&#xff0c…

rtmp投屏花屏卡顿原因分析

rtmp投屏花屏卡顿原因分析 1.丢失参考帧导致的 一般 H.264 码流有 I、B、P 三种帧类型,I 帧是关键帧,B 帧是双向预测内插编码帧,P 帧是前向预测编码帧。 I 帧由于是帧内压缩,因此可以独立解码播放,而 B 帧&#xff…

直播视频卡顿

某直播App问题分析 一. 出现问题 观看自己开播的直播间,经常出现卡顿,而且画面一卡6,7s,重新播放时会出现跳帧,卡顿频率也较高,导致该App可用性极低。 二. 分析 1. 直播架构分析 根据log与抓包分析&#xf…

《直播疑难杂症排查》:播放卡顿

原文来自七牛云,感谢原作者。 1、播放卡顿的表现 播放卡顿的表现总结下来包括但不限于以下这些: 频繁出现缓冲播放不够流畅,画面一卡一卡的 2、常见播放卡顿问题排查 从代码层面来看,什么是卡顿?其实是指播放器渲染…

live555 rtsp直播卡顿马赛克优化

最近搞了个rtsp直播,初步是能用了,但是最终效果不是很好,客户不接受要求我们一定要继续优化。 原因是他们体验的时候发现会概率性出现马赛克和画面卡顿情况,经过我们测试验证,确实是有这个问题存在。 从原理上分析可能…

video 拉流卡顿_【video】视频直播推流拉流慢、卡顿解决方案

一、摘要 视频直播类App当前已经普遍采用CDN来实现访问加速,但还是经常遇到推拉流慢、卡顿的问题,一般是由于调度不精准、域名劫持、终端手机接入网络动态切换等因素导致。结合使用CDN和HTTPDNS可以比较完美解决此类问题。 二、视频直播经典加速架构 当前视频直播类App经典加…

视频为什么会卡顿

视频为什么会卡顿,看看腾讯云如何解决这个问题的。 卡顿的原因无外乎三种情况: 原因 1:帧率太低 如果主播端手机性能较差,或者有很占 CPU 的后台程序在运行,可能导致视频的帧率太低。正常情况下每秒15FPS以上的视频流…

视频融合云平台视频播放卡顿的原因分析及解决办法

SkeyeVSS视频融合云平台可在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,平台支持多类型设备、多协议方式接入,包括主流标准协议国标GB/T28181、RTMP、RTSP/Onvif协议等,以及厂家私有协议,如海…