机器学习基础算法

一、验证线性回归

1、介绍

在本练习中,您将实现线性回归并了解其在数据上的工作原理。

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

ex1data1.txt -单变量的线性回归数据集
ex1data2.txt -多变量的线性回归数据集
在整个练习中,涉及如下的必做作业,及标号*的选做作业:

实现简单示例函数----------(5分)
实现数据集显示的函数-------(5分)
计算线性回归成本的函数-----(40分)
运行梯度下降的功能函数-----(50分)
数据标准化*
多变量线性回归的梯度下降功能实现*
必做作业为实现单变量的线性回归;选做作业为实现多变量线性回归。

1 实现简单示例函数
在该部分练习中,将通过代码实现返回一个5*5的对角矩阵。输出与如下相同:

1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1

1.1 提交解决方案
在以下代码框中进行如上的实现,完成部分练习后,得到如上的相同结果即为通过。

###在这里填入代码###
import numpy as np
a = np.eye(5)
a
array([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])

2、 单变量线性回归

在该部分练习中,将实现单变量线性回归并用来预测餐车的利润。

假设你是一家餐厅的领导,正在考虑在不同的城市开设新的分店。该连锁店已经在不同的城市有了餐车,并且你能够获得每个城市的人口和利润数据。

现在需要使用这些数据来帮助你选择下一个被扩展的城市。

文件ex1data1.txt包含线性回归问题的数据集。第一列数据对应城市人口,第二列数据对应那座城市的餐车的利润。利润为负时表示亏损。

2.1 绘制数据
在开始进入练习之前,对数据进行可视化通常很有用。对于该数据集,可以使用散点图进行可视化,因为它只有两个属性(人口、利润)。

引入所需要的库文件
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os

%matplotlib inline
数据存储路径
path = ‘ex1data1.txt’

读入相应的数据文件
data = pd.read_csv(path, header=None,names=[‘Population’,‘Profit’])

查看数据的前五条
data.head(5)
Population Profit
0 6.1101 17.5920
1 5.5277 9.1302
2 8.5186 13.6620
3 7.0032 11.8540
4 5.8598 6.8233
接下来需要实现数据可视化的代码,该部分数据绘制出的图像应与如下相同。

要点:

实现散点图可视化
数据分布为红色点
标清横纵坐标名称

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jYdJ8ErW-1686477631850)(1-1.png)]
###在这里填入代码###
data.plot(kind=‘scatter’, x=‘Population’, y=‘Profit’,c=‘red’, figsize=(12,8))
<matplotlib.axes._subplots.AxesSubplot at 0x7fcfd2c12470>

2.2 梯度下降
在该部分中,将使用梯度下降来选择合适的线性回归参数θ用以拟合给定数据集。

2.2.1 更新公式
线性回归的目的是最小化成本函数:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gkBvOa37-1686477631851)(1-2.png)]
假设 h θ ( X ) h_{\theta}(X) hθ(X)由以下线性模型给出:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y7xwwj0F-1686477631852)(1-3.png)]

回顾一下,模型的参数是𝜃𝑗
的值,这些将用来调整以最小化成本𝐽(𝜃)

其中一种方法是使用批量梯度下降算法,在批量梯度下降中,每次迭代地执行更新,随着梯度下降的每一步计算,参数𝜃𝑗
越来越接近能够使得成本𝐽(𝜃)
达到最低的最佳值。

[外链图片转存失败,源站可能有防盗链机(同时更新所有的$𝜃𝑗
\th###2 实现

在上部分的练习中,我们已经将所需要用到的数据加载至变量data中,并为其列分别进行命名。

接下来,我们在数据中添加了一个维度来拟合截距项𝜃0
。并将初始参数值设为0,学习率𝛼
设为0.01。

#在列索引为0处添加数据列,该列值均为1
data.insert(0, ‘Ones’, 1)

#获取数据列数
cols = data.shape[1]

#对变量X和y进行初始化,并将其数据类型转换为矩阵
X = data.iloc[:,0:cols-1]
y = data.iloc[:,cols-1:cols]
X = np.matrix(X.values)
y = np.matrix(y.values)

#学习率、迭代次数的初始化
alpha = 0.01
iterations = 1500
2.2.3 计算成本J(θ)
在执行梯度下降最小化成本函数𝐽(𝜃)
时,通过计算成本来监视收敛状态是有帮助的。

在该部分练习任务中,你需要实现一个计算成本𝐽(𝜃)
的函数computeCost,用于检查梯度下降实现的收敛性。

其中,X和y不是标量值,而是矩阵,其行代表训练集中的示例。

要点: 完成该函数后,将𝜃
值初始化为0并进行成本的计算,将得到的成本值打印出来。

如果结果为32.07,则计算通过。

###在这里填入代码###

def computeCost(X, y, theta):
inner = np.power(((X * theta.T) - y), 2)
return np.sum(inner) / (2 * len(X))

theta = np.matrix(np.array([0,0]))
computeCost(X, y, theta)
32.072733877455676
2.2.4 梯度下降
接下来,我们将实现梯度下降,给出的代码已经实现了循环结构,你只需要在每次的迭代中提供𝜃
的更新。

在进行代码实现时,请确保你了解要优化的内容,和正在更新的内容。

请记住,成本𝐽(𝜃)
为参数-被向量𝜃
终止,而不是𝑋
和𝑦
。也就是说,我们将𝐽(𝜃)
的值最小化通过改变矢量𝜃
的值,而不是通过改变𝑋
或𝑦

验证梯度下降是否正常工作的一种好方法是查看𝐽(𝜃)
的值,并检查该值每步是否减小。每次迭代时,代码都会调用computeCost函数并打印成本。假设你实现了梯度下降,正确地计算成本,𝐽(𝜃)
值永远不会增加,并且应该在算法结束时收敛到稳定值。

要点:

实现梯度下降后,需要使用最终的参数值将线性回归的拟合结果进行可视化,绘图结果需要类似如下图所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KlqAf9ir-1686477631853)(1-5.png)]

###在这里填入代码###

def gradientDescent(X, y, theta, alpha, iters):
temp = np.matrix(np.zeros(theta.shape))
parameters = int(theta.ravel().shape[1])
cost = np.zeros(iters)

for i in range(iters):
    error = (X * theta.T) - y
    
    for j in range(parameters):
        term = np.multiply(error, X[:,j])
        temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term))
        
    theta = temp
    cost[i] = computeCost(X, y, theta)
    
return theta, cost


g, cost = gradientDescent(X, y, theta, alpha, iterations)
g
matrix([[-3.63029144, 1.16636235]])
计算最终的参数所得到的成本值
computeCost(X, y, g)
4.483388256587726
###在这里填入代码###
#对拟合曲线进行绘制
x = np.linspace(data.Population.min(), data.Population.max(), 100)
f = g[0, 0] + (g[0, 1] * x)

fig, ax = plt.subplots(figsize=(12,8))
ax.plot(x, f, ‘b’, label=‘Prediction’)
ax.scatter(data.Population, data.Profit, c=‘red’,label=‘Traning Data’)
ax.legend(loc=2)
ax.set_xlabel(‘Population’)
ax.set_ylabel(‘Profit’)
ax.set_title(‘Predicted Profit vs. Population Size’)
Text(0.5, 1.0, ‘Predicted Profit vs. Population Size’)

2.3 可视化成本函数
为了更好地理解成本函数的迭代计算,将每一步计算的cost值进行记录并绘制。

fig, ax = plt.subplots(figsize=(12,8))
ax.plot(np.arange(iterations), cost, ‘r’)
ax.set_xlabel(‘Iterations’)
ax.set_ylabel(‘Cost’)
ax.set_title(‘Error vs. Training Epoch’)
Text(0.5, 1.0, ‘Error vs. Training Epoch’)

选做练习

3 、多变量线性回归

在该部分中,将使用多个变量来实现用线性回归预测房屋价格。假设你目前正在出售房屋,想知道什么是好的市场价格。

一种方法是首先收集最近出售房屋的信息,其次是建立房屋价格模型。

文件ex1data2.txt包含俄勒冈州波特兰市的房屋价格及相关信息。第一列是房屋的大小(以平方英尺为单位),第二列是卧室的个数,第三列是房屋的价格。

3.1 特征标准化
以下代码将从文件ex1data2.txt文件中加载并显示该数据集。

通过观察这些数据,可以发现房屋的大小大约是卧室数量的1000倍。而当不同的特征值之间相差几个数量级时,将特征进行缩放可以使梯度下降收敛得更快。

path = ‘ex1data2.txt’
data2 = pd.read_csv(path, header=None, names=[‘Size’, ‘Bedrooms’, ‘Price’])
data2.head()
Size Bedrooms Price
0 2104 3 399900
1 1600 3 329900
2 2400 3 369000
3 1416 2 232000
4 3000 4 539900
在该部分练习中,你的任务是编写代码并实现数据集中的数据标准化。

要点:

从数据集中减去每个特征的平均值。
减去平均值后,再将新的特征值除以各自的“标准差”
标准差是一种衡量特定特征的值的范围内有多大变化的方法(大多数数据点将位于平均值的两个标准差内);这是取值范围的替代方法。

当标准化特征时,需要存储用于标准化的值——平均值和标准差。从模型中学习参数后,经常需要预测新的房屋的价格。此时给定一个新的𝑥
值(房屋面积和卧室数量),必须首先使用先前从训练集中计算的平均值和标准差来对新的数据进行标准化。

###在这里填入代码###
data2 = (data2 - data2.mean()) / data2.std()
data2.head()
Size Bedrooms Price
0 0.130010 -0.223675 0.475747
1 -0.504190 -0.223675 -0.084074
2 0.502476 -0.223675 0.228626
3 -0.735723 -1.537767 -0.867025
4 1.257476 1.090417 1.595389
3.2 梯度下降
在之前的练习中,我们使用单变量线性回归实现了梯度下降的问题。在该部分联系中,唯一的区别是,此时我们的数据变为矩阵𝑋

假设函数和批次梯度下降的更新规则保持不变,你的任务是代码实现多变量线性回归的成本函数和梯度下降。

要点:

确保你的代码中可以支持任何大小的数据,并且数据均已被向量化。
代码实现成本函数和梯度下降后,最终的成本值应大约为0.13。
请依照单变量线性回归练习中要求,绘制成本的变化曲线。
###在这里填入代码###
add ones column
data2.insert(0, ‘Ones’, 1)

set X (training data) and y (target variable)
cols = data2.shape[1]
X2 = data2.iloc[:,0:cols-1]
y2 = data2.iloc[:,cols-1:cols]

convert to matrices and initialize theta
X2 = np.matrix(X2.values)
y2 = np.matrix(y2.values)
theta2 = np.matrix(np.array([0,0,0]))

perform linear regression on the data set
g2, cost2 = gradientDescent(X2, y2, theta2, alpha, iterations)

get the cost (error) of the model
computeCost(X2, y2, g2)
0.13068670606095903
fig, ax = plt.subplots(figsize=(12,8))
ax.plot(np.arange(iterations), cost2, ‘r’)
ax.set_xlabel(‘Iterations’)
ax.set_ylabel(‘Cost’)
ax.set_title(‘Error vs. Training Epoch’)
Text(0.5, 1.0, ‘Error vs. Training Epoch’)

二、验证逻辑回归

1、介绍

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

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

ex2data1.txt -前半部分的训练数据集
ex2data2.txt -后半部分的训练数据集
在整个练习中,涉及如下的必做作业:

绘制2D分类数据的函数----(3分)
实现Sigmoid函数--------(5分)
实现Logistic回归代价函数和梯度函数—(60分)
实现回归预测函数--------(5分)
实现正则Logisitic回归成本函数-------(27分)
1 Logistic回归
在该部分练习中,将建立一个逻辑回归模型,用以预测学生能否被大学录取。

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

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

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

现在,你需要编写代码来完成数据的绘图,显示如下所示的图形。

要点:

导入需要使用的python库,并将从文件ex2data1.txt中读取数据,并显示前5行
x-y轴分别为两次考试的分数
正负示例需要用不同的标记显示(不同的颜色)
###在这里填入代码###
###主要实现要点1###
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

path = ‘ex2data1.txt’
data = pd.read_csv(path, header=None, names=[‘Exam 1’, ‘Exam 2’, ‘Admitted’])
data.head()
Exam 1 Exam 2 Admitted
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
###在这里填入代码###
###绘制数据散点图###
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函数。 我们还记得逻辑回归假设的定义是:
ℎ𝜃(𝑥)=𝑔(𝜃𝑇𝑋)
其中 g 代表一个常用的逻辑函数为S形函数(Sigmoid function),公式为:
𝑔(𝑧)=11+𝑒−𝑧
合起来,我们得到逻辑回归模型的假设函数:
ℎ𝜃(𝑥)=11+𝑒−𝜃𝑇𝑋
接下来,你需要编写代码实现Sigmoid函数,编写后试着测试一些值,如果x的正值较大,则函数值应接近1;如果x的负值较大,则函数值应接近0。而对于x等于0时,则函数值为0.5。

确保在进行调用你实现的Sigmoid函数后,以下代码会输出如下的图片:

###在这里填入代码###
def sigmoid(z):
return 1 / (1 + np.exp(-z))
###请运行并测试你的代码###
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 代价函数
我们知道逻辑回归的代价函数是: 𝐽(𝜃)=1𝑚∑𝑖=1𝑚[−𝑦(𝑖)log(ℎ𝜃(𝑥(𝑖)))−(1−𝑦(𝑖))log(1−ℎ𝜃(𝑥(𝑖)))]
现在,你需要编写代码实现代价函数以进行逻辑回归的成本计算,并且经过所给数据测试后,初始的成本约为0.693。

要点:

实现cost函数,参数为theta,X,y.
返回计算的成本值。
其中theta为参数,X为训练集中的特征列,y为训练集的标签列,三者均为矩阵。
###在这里填入代码###
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))
###请运行并测试你的代码###
#增加一列值为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)
0.6931471805599453
1.2.2.2 梯度下降
接下来,我们需要编写代码实现梯度下降用来计算我们的训练数据、标签和一些参数𝜃
的梯度。

要点:

代码实现gradient函数,参数为theta,X,y.
返回计算的梯度值。
其中theta为参数,X为训练集中的特征列,y为训练集的标签列,三者均为矩阵。
批量梯度下降转化为向量化计算: 1𝑚𝑋𝑇(𝑆𝑖𝑔𝑚𝑜𝑖𝑑(𝑋𝜃)−𝑦)
∂𝐽(𝜃)∂𝜃𝑗=1𝑚∑𝑖=1𝑚(ℎ𝜃(𝑥(𝑖))−𝑦(𝑖))𝑥(𝑖)𝑗
这里需要注意的是,我们实际上没有在这个函数中执行梯度下降,我们仅仅在计算一个梯度步长。由于我们使用Python,我们可以用SciPy的optimize命名空间来做同样的事情。

###在这里填入代码###
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) - 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)
array([ -0.1 , -12.00921659, -11.26284221])
1.2.3 寻找最优参数
现在可以用SciPy’s truncated newton(TNC)实现寻找最优参数。

###请运行并测试你的代码###
import scipy.optimize as opt
result = opt.fmin_tnc(func=cost, x0=theta, fprime=gradient, args=(X, y))
result
(array([-25.16131872, 0.20623159, 0.20147149]), 36, 0)
让我们看看在这个结论下代价函数的值:

###请运行并测试你的代码###
cost(result[0], X, y)
0.20349770158947425
1.2.4 评估逻辑回归
接下来,我们需要编写代码实现预测函数,用所学的最优参数𝜃
来为数据集X输出预测结果。然后,可以使用这个函数来给我们定义的分类器的训练精度进行打分。

逻辑回归的假设函数:

ℎ𝜃(𝑥)=11+𝑒−𝜃𝑇𝑋
当ℎ𝜃
大于等于0.5时,预测 y=1

当ℎ𝜃
小于0.5时,预测 y=0。

要点:

代码实现predict函数,参数为theta,X.
返回X中的每行数据对应的预测结果。
其中theta为参数,X为训练集中的特征列。
###在这里填入代码###
def predict(theta, X):
probability = sigmoid(X * theta.T)
return [1 if x >= 0.5 else 0 for x in probability]
###请运行并测试你的代码###
theta_min = np.matrix(result[0])
predict(theta_min, X)
[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]
###请运行并测试你的代码###
#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 数据可视化
与第一部分的练习类似,首先对数据进行可视化:

path = ‘ex2data2.txt’
data2 = pd.read_csv(path, header=None, names=[‘Test 1’, ‘Test 2’, ‘Accepted’])
data2.head()
Test 1 Test 2 Accepted
0 0.051267 0.69956 1
1 -0.092742 0.68494 1
2 -0.213710 0.69225 1
3 -0.375000 0.50219 1
4 -0.513250 0.46564 1
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 特征映射
一种能够更好地拟合数据的方法是构造从原始特征的多项式中得到的特征,即特征映射。如下图所示,作为这种映射的结果,我们的两个特征向量𝑥1,𝑥2
(两次质量保证测试的分数)已经被转换成了28维的向量。

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

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

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

设定映射深度
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
Accepted Ones F10 F20 F21 F30 F31 F32 F40 F41 F42 F43
0 1 1 0.051267 0.002628 0.035864 0.000135 0.001839 0.025089 0.000007 0.000094 0.001286 0.017551
1 1 1 -0.092742 0.008601 -0.063523 -0.000798 0.005891 -0.043509 0.000074 -0.000546 0.004035 -0.029801
2 1 1 -0.213710 0.045672 -0.147941 -0.009761 0.031616 -0.102412 0.002086 -0.006757 0.021886 -0.070895
3 1 1 -0.375000 0.140625 -0.188321 -0.052734 0.070620 -0.094573 0.019775 -0.026483 0.035465 -0.047494
4 1 1 -0.513250 0.263426 -0.238990 -0.135203 0.122661 -0.111283 0.069393 -0.062956 0.057116 -0.051818
2.3 代价函数和梯度
接下来,你需要编写代码来实现计算正则化逻辑回归的代价函数和梯度,并返回计算的代价值和梯度。

正则化逻辑回归的代价函数如下:
𝐽(𝜃)=1𝑚∑𝑖=1𝑚[−𝑦(𝑖)log(ℎ𝜃(𝑥(𝑖)))−(1−𝑦(𝑖))log(1−ℎ𝜃(𝑥(𝑖)))]+𝜆2𝑚∑𝑗=1𝑛𝜃2𝑗
其中𝜆
是“学习率”参数,其值会影响函数中的正则项值。且不应该正则化参数𝜃0

###在这里填入代码###
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
接下来,我们需要实现正则化梯度函数,使用梯度下降法使得代价函数最小化。

因为在代价函数的计算中我们未对𝜃0
进行正则化,所以梯度下降算法将分为两种情况:

𝑅𝑒𝑝𝑒𝑎𝑡 𝑢𝑛𝑡𝑖𝑙 𝑐𝑜𝑛𝑣𝑒𝑟𝑔𝑒𝑛𝑐𝑒 { 𝜃0:=𝜃0−𝑎1𝑚∑𝑖=1𝑚[ℎ𝜃(𝑥(𝑖))−𝑦(𝑖)]𝑥(𝑖)0 𝜃𝑗:=𝜃𝑗−𝑎1𝑚∑𝑖=1𝑚[ℎ𝜃(𝑥(𝑖))−𝑦(𝑖)]𝑥(𝑖)𝑗+𝜆𝑚𝜃𝑗 } 𝑅𝑒𝑝𝑒𝑎𝑡
对上面的算法中 j=1,2,…,n 时的更新式子进行调整可得: 𝜃𝑗:=𝜃𝑗(1−𝑎𝜆𝑚)−𝑎1𝑚∑𝑖=1𝑚(ℎ𝜃(𝑥(𝑖))−𝑦(𝑖))𝑥(𝑖)𝑗
###在这里填入代码###
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) - y

for 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

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

从数据集中取得对应的特征列和标签列
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
接下来,使用初始化的变量值来测试你实现的代价函数和梯度函数。

###请运行并测试你的代码###
costReg(theta2, X2, y2, learningRate)
0.6931471805599454
###请运行并测试你的代码###
gradientReg(theta2, X2, y2, learningRate)
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 寻找最优参数
现在我们可以使用和第一部分相同的优化函数来计算优化后的结果。

result2 = opt.fmin_tnc(func=costReg, x0=theta2, fprime=gradientReg, args=(X2, y2, learningRate))
result2
(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部分中的预测函数来查看我们的方案在训练数据上的准确度。

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%

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值