吴恩达机器学习作业Python实现(一):线性回归

单变量线性回归

题目

在本部分的练习中,您将使用一个变量实现线性回归,以预测食品卡车的利润。假设你是一家餐馆的首席执行官,正在考虑不同的城市开设一个新的分店。该连锁店已经在各个城市拥有卡车,而且你有来自城市的利润和人口数据。
您希望使用这些数据来帮助您选择将哪个城市扩展到下一个城市。

数据

6.1101,17.592
5.5277,9.1302
8.5186,13.662
7.0032,11.854
5.8598,6.8233
8.3829,11.886
7.4764,4.3483
8.5781,12
6.4862,6.5987
5.0546,3.8166
5.7107,3.2522
14.164,15.505
5.734,3.1551
8.4084,7.2258
5.6407,0.71618
5.3794,3.5129
6.3654,5.3048
5.1301,0.56077
6.4296,3.6518
7.0708,5.3893
6.1891,3.1386
20.27,21.767
5.4901,4.263
6.3261,5.1875
5.5649,3.0825
18.945,22.638
12.828,13.501
10.957,7.0467
13.176,14.692
22.203,24.147
5.2524,-1.22
6.5894,5.9966
9.2482,12.134
5.8918,1.8495
8.2111,6.5426
7.9334,4.5623
8.0959,4.1164
5.6063,3.3928
12.836,10.117
6.3534,5.4974
5.4069,0.55657
6.8825,3.9115
11.708,5.3854
5.7737,2.4406
7.8247,6.7318
7.0931,1.0463
5.0702,5.1337
5.8014,1.844
11.7,8.0043
5.5416,1.0179
7.5402,6.7504
5.3077,1.8396
7.4239,4.2885
7.6031,4.9981
6.3328,1.4233
6.3589,-1.4211
6.2742,2.4756
5.6397,4.6042
9.3102,3.9624
9.4536,5.4141
8.8254,5.1694
5.1793,-0.74279
21.279,17.929
14.908,12.054
18.959,17.054
7.2182,4.8852
8.2951,5.7442
10.236,7.7754
5.4994,1.0173
20.341,20.992
10.136,6.6799
7.3345,4.0259
6.0062,1.2784
7.2259,3.3411
5.0269,-2.6807
6.5479,0.29678
7.5386,3.8845
5.0365,5.7014
10.274,6.7526
5.1077,2.0576
5.7292,0.47953
5.1884,0.20421
6.3557,0.67861
9.7687,7.5435
6.5159,5.3436
8.5172,4.2415
9.1802,6.7981
6.002,0.92695
5.5204,0.152
5.0594,2.8214
5.7077,1.8451
7.6366,4.2959
5.8707,7.2029
5.3054,1.9869
8.2934,0.14454
13.394,9.0551
5.4369,0.61705

先导入数据

'''
单变量线性回归
1.Prepare datasets
'''
path = 'ex1data1.txt'
# names添加列名,header用指定的行来作为标题,若原无标题且指定标题则设为None
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
data.head()
data.describe()
# print(data.head())#显示前五行
# print(data.describe())

在开始任何任务之前,通过可视化来理解数据通常是有用的。对于这个数据集,您可以使用散点图来可视化数据,因为它只有两个属性(利润和人口)。

# 展示散点图,可视化理解数据
# data.plot(kind='scatter', x='Population', y='Profit', figsize=(8,5))
# plt.title("Scatter plot of training data") #添加描述信息
# plt.xlabel("population of city")
# plt.ylabel("profit")
# plt.show()

现在让我们使用梯度下降来实现线性回归,以最小化成本函数。 以下代码示例中实现的方程在“练习”文件夹中的“ex1.pdf”中有详细说明。

首先,我们将创建一个以参数θ为特征函数的代价函数
函数计算代价函数 J ( θ )

'''
作用:计算代价函数,向量化来计算参数
:param X: 输入矩阵
:param y: 输出目标
:param theta: parameters
:return:
'''
def computeCost(X, y, theta):

    inner = np.power(((X * theta.T) - y), 2)
    # print(inner)
    return np.sum(inner) / (2 * len(X))

让我们在训练集中添加一列,以便我们可以使用向量化的解决方案来计算代价和梯度。

data.insert(0, 'Ones', 1)       # 增加一条第一列,全部数值为1
# print(data)

现在我们来做一些变量初始化。
取最后一列为 y,其余为 X
观察下 X (训练集) and y (目标变量)是否正确.

# 变量初始化:set X (training data) and y (target variable)
cols = data.shape[1]  # 列数
X = data.iloc[:, 0:cols - 1]        # 取前cols-1列,即输入向量
y = data.iloc[:, cols - 1:cols]     # 取最后一列作为目标向量
# print(X.head()) # 观察下 X (训练集) and y (目标变量)是否正确.
# print(y.head())

但是matrix的优势就是相对简单的运算符号,比如两个矩阵相乘,就是用符号*,但是array相乘不能这么用,得用方法.dot()
array的优势就是不仅仅表示二维,还能表示3、4、5…维,而且在大部分Python程序里,array也是更常用的。

两者区别:

对应元素相乘:matrix可以用np.multiply(X2,X1),array直接X1X2
点乘:matrix直接X1
X2,array可以 X1@X2 或 X1.dot(X2) 或 np.dot(X1, X2)
代价函数是应该是numpy矩阵,所以我们需要转换X和Y,然后才能使用它们。 我们还需要初始化theta。

X = np.matrix(X.values)
y = np.matrix(y.values)
theta = np.matrix([0,0]) # theta 是一个(1,2)矩阵
computeCost(X, y, theta)
# print(X.shape, y.shape, theta.shape)  # 查看各自的行列数
# print(computeCost(X, y, theta)) # 32.072733877455676

batch gradient decent(批量梯度下降)

a
初始化一些附加变量 - 学习速率α和要执行的迭代次数。并开始计算合适的theta,写出梯度下降算法的函数。
asd

alpha = 0.01 # 学习速率α
epoch = 1000 # 要执行的迭代次数
'''
2.作用:获得最终梯度下降后的theta值以及cost
:param X:
:param y:
:param theta:
:param alpha:
:param epoch:
:return:
'''
def gradientDescent(X, y, theta, alpha, epoch):
    # 变量初始化,储存数据
    np.matrix(np.zeros(theta.shape)) # 初始化一个临时矩阵(1, 2)
    # flatten()降维 即返回一个折叠成一维的数组。但是该函数只能适用于numpy对象,即array或者mat,普通的list列表是不行的。
    parameters = int(theta.flatten().shape[1]) # 参数theta的数量 2
    # print(parameters)
    cost = np.zeros(epoch)  # 初始化一个ndarray, 包含每次训练后的cost #1000个0的矩阵
    # print(cost)
    counterTheta = np.zeros((epoch, 2)) #1000 * 2的数组
    m = X.shape[0]  # 样本参数 97行

    for i in range(epoch):
        '''
        使用 vectorization同时更新所有的θ,可以大大提高效率,此处都是相对应的进行计算
        X.shape, theta.shape, y.shape, X.shape[0]
        ((97, 2), (1, 2), (97, 1), 97)
        '''
        # 相当于theta1 theta2不停做偏导并且更新 theta[theta1, theta2] temp是临时的theta
        temp = theta - (alpha / m) * (X * theta.T - y).T * X
        theta = temp
        counterTheta[i] = theta
        cost[i] = computeCost(X, y, theta)
        pass
    return counterTheta, theta, cost

调用梯度下降函数

counterTheta, final_theta, cost = gradientDescent(X, y, theta, alpha, epoch)
computeCost(X, y, final_theta)
# print(computeCost(X, y, final_theta)) # 4.515955503078912

画图

x = np.linspace(data.Population.min(), data.Population.max(), 100)  # xlabel start:返回样本数据开始点 stop:返回样本数据结束点 num:生成的样本数据量,默认为50
f = final_theta[0, 0] + (final_theta[0, 1] * x)  # ylabel profit
print(final_theta)


fig1, ax = plt.subplots(figsize=(6, 4)) # 尺寸
ax.plot(x, f, 'r', label='Predictionnnnnn') # 横坐标 纵坐标 颜色 标签
ax.scatter(data.Population, data.Profit, label='Training Data') # 点的离散值
ax.legend(loc=2) # 2表示在左上角
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')

fig2, ax = plt.subplots(figsize=(8, 4))
ax.plot(np.arange(epoch), cost, 'r') # 横坐标 纵坐标 颜色
ax.set_xlabel('Iteration')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')
plt.show()

完整代码

# Kyrie Irving
# !/9462...
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

'''
作用:计算代价函数,向量化来计算参数
:param X: 输入矩阵
:param y: 输出目标
:param theta: parameters
:return:
'''
def computeCost(X, y, theta):

    inner = np.power(((X * theta.T) - y), 2)
    # print(inner)
    return np.sum(inner) / (2 * len(X))

'''
2.作用:获得最终梯度下降后的theta值以及cost
:param X:
:param y:
:param theta:
:param alpha:
:param epoch:
:return:
'''
def gradientDescent(X, y, theta, alpha, epoch):
    # 变量初始化,储存数据
    np.matrix(np.zeros(theta.shape)) # 初始化一个临时矩阵(1, 2)
    # flatten()降维 即返回一个折叠成一维的数组。但是该函数只能适用于numpy对象,即array或者mat,普通的list列表是不行的。
    parameters = int(theta.flatten().shape[1]) # 参数theta的数量 2
    # print(parameters)
    cost = np.zeros(epoch)  # 初始化一个ndarray, 包含每次训练后的cost #1000个0的矩阵
    # print(cost)
    counterTheta = np.zeros((epoch, 2)) #1000 * 2的数组
    m = X.shape[0]  # 样本参数 97行

    for i in range(epoch):
        '''
        使用 vectorization同时更新所有的θ,可以大大提高效率,此处都是相对应的进行计算
        X.shape, theta.shape, y.shape, X.shape[0]
        ((97, 2), (1, 2), (97, 1), 97)
        '''
        # 相当于theta1 theta2不停做偏导并且更新 theta[theta1, theta2] temp是临时的theta
        temp = theta - (alpha / m) * (X * theta.T - y).T * X
        theta = temp
        counterTheta[i] = theta
        cost[i] = computeCost(X, y, theta)
        pass
    return counterTheta, theta, cost







'''
单变量线性回归
1.Prepare datasets
'''
path = 'ex1data1.txt'
# names添加列名,header用指定的行来作为标题,若原无标题且指定标题则设为None
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
data.head()
data.describe()
# print(data.head())#显示前五行
# print(data.describe())

# 展示散点图,可视化理解数据
# data.plot(kind='scatter', x='Population', y='Profit', figsize=(8,5))
# plt.title("Scatter plot of training data") #添加描述信息
# plt.xlabel("population of city")
# plt.ylabel("profit")
# plt.show()

data.insert(0, 'Ones', 1)       # 增加一条第一列,全部数值为1
# print(data)

# 变量初始化:set X (training data) and y (target variable)
cols = data.shape[1]  # 列数
X = data.iloc[:, 0:cols - 1]        # 取前cols-1列,即输入向量
y = data.iloc[:, cols - 1:cols]     # 取最后一列作为目标向量
# print(X.head()) # 观察下 X (训练集) and y (目标变量)是否正确.
# print(y.head())

X = np.matrix(X.values)
y = np.matrix(y.values)
theta = np.matrix([0,0]) # theta 是一个(1,2)矩阵
computeCost(X, y, theta)
# print(X.shape, y.shape, theta.shape)  # 查看各自的行列数
# print(computeCost(X, y, theta)) # 32.072733877455676

alpha = 0.01 # 学习速率α
epoch = 1000 # 要执行的迭代次数
counterTheta, final_theta, cost = gradientDescent(X, y, theta, alpha, epoch)
computeCost(X, y, final_theta)
# print(computeCost(X, y, final_theta)) # 4.515955503078912

x = np.linspace(data.Population.min(), data.Population.max(), 100)  # xlabel start:返回样本数据开始点 stop:返回样本数据结束点 num:生成的样本数据量,默认为50
f = final_theta[0, 0] + (final_theta[0, 1] * x)  # ylabel profit
print(final_theta)


fig1, ax = plt.subplots(figsize=(6, 4)) # 尺寸
ax.plot(x, f, 'r', label='Predictionnnnnn') # 横坐标 纵坐标 颜色 标签
ax.scatter(data.Population, data.Profit, label='Training Data') # 点的离散值
ax.legend(loc=2) # 2表示在左上角
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')

fig2, ax = plt.subplots(figsize=(8, 4))
ax.plot(np.arange(epoch), cost, 'r') # 横坐标 纵坐标 颜色
ax.set_xlabel('Iteration')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')
plt.show()

多变量线性回归

练习1还包括一个房屋价格数据集,其中有2个变量(房子的大小,卧室的数量)和目标(房子的价格)。 我们使用我们已经应用的技术来分析数据集。

数据

2104,3,399900
1600,3,329900
2400,3,369000
1416,2,232000
3000,4,539900
1985,4,299900
1534,3,314900
1427,3,198999
1380,3,212000
1494,3,242500
1940,4,239999
2000,3,347000
1890,3,329999
4478,5,699900
1268,3,259900
2300,4,449900
1320,2,299900
1236,3,199900
2609,4,499998
3031,4,599000
1767,3,252900
1888,2,255000
1604,3,242900
1962,4,259900
3890,3,573900
1100,3,249900
1458,3,464500
2526,3,469000
2200,3,475000
2637,3,299900
1839,2,349900
1000,1,169900
2040,4,314900
3137,3,579900
1811,4,285900
1437,3,249900
1239,3,229900
2132,4,345000
4215,4,549000
2162,4,287000
1664,2,368500
2238,3,329900
2567,4,314000
1200,3,299000
852,2,179900
1852,4,299900
1203,3,239500

完整代码

# Kyrie Irving
# !/9462...
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

path = 'ex1data2.txt'
data = pd.read_csv(path, names=['Size', 'Bedrooms', 'Price'])
# 数据归一化后,最优解的寻优过程明显会变得平缓,更容易正确的收敛到最优解。简而言之,归一化的目的就是使得预处理的数据被限定在一定的范围内(比如[0,1]或者[-1,1]),从而消除奇异样本数据导致的不良影响。
data = (data - data.mean()) / data.std() # data2.std()是标准差
data.head()
# print(data.head())
# add ones column
data.insert(0, 'Ones', 1)

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

# convert to matrices and initialize theta
X = np.matrix(X.values)
y = np.matrix(y.values)
theta = np.matrix(np.array([0, 0, 0])) # 此时theta的维度应该是3

'''
作用:计算代价函数,向量化来计算参数
:param X: 输入矩阵
:param y: 输出目标
:param theta: parameters
:return:
'''
def computeCost(X, y, theta):

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

'''
2.作用:获得最终梯度下降后的theta值以及cost
:param X:
:param y:
:param theta:
:param alpha:
:param epoch:
:return:
'''
def gradientDescent(X, y, theta, alpha, epoch):
    # 变量初始化,储存数据
    np.matrix(np.zeros(theta.shape)) # 初始化一个临时矩阵(1, 2)
    # flatten()降维 即返回一个折叠成一维的数组。但是该函数只能适用于numpy对象,即array或者mat,普通的list列表是不行的。
    parameters = int(theta.flatten().shape[1]) # 参数theta的数量 2
    # print(parameters)
    cost = np.zeros(epoch)  # 初始化一个ndarray, 包含每次训练后的cost #1000个0的矩阵
    # print(cost)
    counterTheta = np.zeros((epoch, 3)) #1000 * 3的数组
    m = X.shape[0]  # 样本参数 97行

    for i in range(epoch):
        '''
        使用 vectorization同时更新所有的θ,可以大大提高效率,此处都是相对应的进行计算
        X.shape, theta.shape, y.shape, X.shape[0]
        ((97, 2), (1, 2), (97, 1), 97)
        '''
        # 相当于theta1 theta2不停做偏导并且更新 theta[theta1, theta2] temp是临时的theta
        temp = theta - (alpha / m) * (X * theta.T - y).T * X
        theta = temp
        counterTheta[i] = theta
        cost[i] = computeCost(X, y, theta) # 记录每次的cost
        pass
    return counterTheta, theta, cost

'''
3.Run model and Plot
'''
alpha = 0.01
epoch = 3800
counterTheta, final_theta, cost = gradientDescent(X, y, theta, alpha, epoch)
computeCost(X, y, final_theta)
# print(computeCost(X, y, final_theta)) #0.13068648053904253

fig2, ax = plt.subplots(figsize=(8, 4))
ax.plot(np.arange(epoch), cost, 'r')
ax.set_xlabel('Iteration')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')
plt.show()
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
金微智能餐厅是一款基于Web网页管理的餐厅管理系统。 顾客使用自己的手机扫码二维码即可方便的点菜下单,全程无需服务员参与; 支持微信和支付宝结账,支持自动调用接口和扫描二维码支付两种方式; 支持官方接口和我司自行研发的金微免签支付接口平台,可实现0费率; 创新的店面管理模式,店员及后厨均使用手机或平板操作,无需打印小票传单; 自带外卖派送平台,可实现外卖退单派送; 完善的数据统计,每日营销情况一目了然。 低成本投入,只需要一台电脑和一台小票打印机即可,无需购置其他设备。 金微智能餐厅分为两种模式:正餐模式和快餐模式。商户可根据自己的店铺规模和业务类型灵活选择部署相应的模式。 正餐模式:即先用餐后买单,流程为:顾客到店→点餐下单→制作送餐→顾客用餐→结账付款→顾客离开。 快餐模式:即先买单后用餐,流程为:顾客到店→点餐下单→手机支付→商家收单→制作送餐→顾客用餐。 快餐模式下设子项外卖点餐模式,可将外卖点餐集成进商户自己的微信公众号,顾客关注商户公众号后可由公众号内叫外卖点餐并自助结账。 金微智能餐厅v0.8.2E更新: 公众号版最后一次更新,主要修复一些bug和漏洞 此后将改版为小程序版,小程序版使用全新数据结构,数据库只有两个表,与公众号版不兼容,小程序版使用蓝牙打印,不再需要安装Lodop控件,小程序顾客端和管理段合二为一,微信自动登录,自动鉴权。 本次已打包小程序版v1.0.5b版,请选择合适的版本安装!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值