吴恩达《机器学习》学习笔记四——单变量线性回归(梯度下降法)代码
- 一、问题介绍
- 二、解决过程及代码讲解
- 三、函数解释
- 1. pandas.read_csv()函数
- 2. DataFrame.head()函数
- 3. Dataframe.insert()函数
课程链接: https://www.bilibili.com/video/BV164411b7dx?from=search&seid=5329376196520099118
之前介绍了吴恩达机器学习课程的第一个算法——线性回归,又可以分为一元和多元,优化参数的方法包含梯度下降和正规方程两种。今天用python来完成一下相关的练习,虽然吴恩达推荐使用Octave,但是用python上手个人感觉更通用。一元的代码掌握后推广到多元很简单,而且梯度下降的优化算法更通用,所以着重讲解一下单变量线性回归(梯度下降法)的代码。
这次笔记用到的数据集:https://pan.baidu.com/s/1h5Ygse5q2wkTeXA9Pwq2RA
提取码:ottq
一、问题介绍
使用一个单变量线性回归模型来预测食品卡车的利润。假设你是一个特许经营餐厅的CEO,并且正在考虑在不同城市开设新的出口。这个连锁店已经在各个城市有卡车,你有城市的利润和人口的数据。
你希望使用此数据来帮助您选择要扩展的下一个城市。文件ex1data1.txt包含线性回归问题的数据集。第一列是城市人口,第二列是那个城市里一辆食品卡车的利润,利润为负值时表示损失。
下图为数据集文件内容部分截图:
一句话说,就是利用城市的人口数据来预测在该城市的利润,可以采用单变量线性回归模型。
二、解决过程及代码讲解
首先导入需要使用的模块:numpy,pandas和matplotlib.pyplot。
# 导入必要的模块
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
读入数据集,若数据集和代码文件放在一个文件夹下可以使用相对路径,否则要使用绝对路径才能找到数据集。
# 读入数据集data1.txt
path = 'data/data42661/ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
data.head() #预览数据
结果如下:
查看一下数据集的统计信息,包括数据个数、均值、方差、最大最小值等。
data.describe()
也可以通过绘制散点图具体查看数据集分布。
data.plot(kind='scatter', x='Population', y='Profit', figsize=(12,8))
plt.show()
因为是单变量问题,读入的数据可以表示成这样:
而为了将假设函数变成如下形式,以便我们可以使用向量化的解决方案来计算代价和梯度:
X需要插入一列1:
代码是:
data.insert(0, 'Ones', 1)
# 变量初始化
# set X (training data) and y (target variable)
cols = data.shape[1]
X = data.iloc[:,0:cols-1]#X是所有行,去掉最后一列
y = data.iloc[:,cols-1:cols]#X是所有行,最后一列
# 观察下 X (训练集) and y (目标变量)是否正确.
X.head() #head()是观察前5行
y.head()
但此时X和y是DataFrame形式,需要转换为矩阵才方便运算:
# 代价函数是应该是numpy矩阵,所以我们需要转换X和Y,然后才能使用它们。 我们还需要初始化theta,即把theta所有元素都设置为0.
X = np.matrix(X.values)
y = np.matrix(y.values)
theta = np.matrix(np.array([0,0]))
# 查看一下各自的维度
X.shape, theta.shape, y.shape
定义代价函数:
def computeCost(X, y, theta):inner = np.power(((X*theta.T) - y),2)
return np.sum(inner)/(2*len(X))
# 计算初始代价函数 (theta初始值为0).
computeCost(X, y, theta)
然后就是定义梯度下降算法函数:
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) - yfor j in range(parameters):term = np.multiply(error, X[:,j])temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term))theta = tempcost[i] = computeCost(X, y, theta)return theta, cost
# 初始化学习率和迭代次数,这个是可以手动调节的
alpha = 0.01
iters = 1000
# 调用梯度下降,得到两个参数的最优值
g, cost = gradientDescent(X, y, theta, alpha, iters)
# 并看一下最优的代价函数值
computeCost(X, y, g)
# 可以看一下此时的假设函数的拟合程度,从图中看拟合程度还算可以。
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, 'r', label='Prediction')
ax.scatter(data.Population, data.Profit, label='Traning Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
plt.show()
还可以通过看代价函数的变化曲线来判断是否正确工作。
fig, ax = plt.subplots(figsize=(12,8))
ax.plot(np.arange(iters), cost, 'r')
ax.set_xlabel('Iterations')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')
plt.show()
三、函数解释
1. pandas.read_csv()函数
read_csv()函数是用来读取csv文件的内容进而转化为易于操作的数据结构dataframe的常用函数,具有十分强大的功能。
各参数详解参考:
pandas.read_csv()函数
2. DataFrame.head()函数
在用Pandas读取数据之后,我们往往想要观察一下数据读取是否准确,这就要用到Pandas里面的head( )函数,但是head( )函数只能读取前五行数据。
3. Dataframe.insert()函数
在Dataframe的指定列中插入数据。各参数详解参考:Dataframe.insert()函数