吴恩达《机器学习》学习笔记四——单变量线性回归(梯度下降法)代码

吴恩达《机器学习》学习笔记四——单变量线性回归(梯度下降法)代码


课程链接: 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) - 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
# 初始化学习率和迭代次数,这个是可以手动调节的
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()函数

猜你喜欢

转载自blog.csdn.net/qq_40467656/article/details/107183103