【吴恩达】机器学习作业ex1-(线性回归) python

1.前言

我是机器学习的初学者,同时也是python的初学者,通过室友推荐吴恩达老师的机器学习,就随着课程找了csdn中的大神们的文章进行学习,自己摸索着做了一份,我会尽量把我所了解的解释清楚

2.所需内容

1.panda,matplotlib,numpy三个包

如果不会在pycharm导入这三个包的可以去翻我上一篇文章,里面展示了俩种方法以及这过程中可能会出现的问题

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

2.ex1data.txt 数据集

此数据集可以去自行查找,很小的一个文件,包含了俩列数据

3.数据准备以及转化

1.在第一列插入1的目的就是为了能和后面的theta矩阵进行矩阵的乘法,近而凑出一元线性的方程

2.iloc()的方法在逗号之前是对行的选取,逗号之后是对列的选取,注意是左闭又开的形式(  ]        

3.将x,y都转换成np.matrix的类型,也就矩阵,但是注意这里matrix类型的矩阵和ndarray类型的矩阵还是有些差异的,后面会提到

4.np.zeros()方法是用来设置m*n阶的零矩阵的,这里我们默认theta0和theta1都是从0,0开始的

# 将ex1data1里的内容取出来
data = pd.read_csv('ex1data1.txt', header=None, names=['population', 'profit'])
# 查询一下data是否取出
# print(data)
data.insert(0, 'ones', 1)  # 在第一列插入1,这样方便后面进行矩阵乘法的运算
x = data.iloc[:, 0:2]  # 取出第一列和第二列也就是人口的一列
y = data.iloc[:, 2:3]  # 取出最后一列也就是利润的一列(行全选)
x = np.matrix(x.values)  # 将x转换为矩阵
y = np.matrix(y.values)  # 将y也转换为矩阵
theta = np.zeros((2, 1))  # 将theta设置为一个空的矩阵

4.代价函数

1.这里利用矩阵乘法可以实现吴恩达老师的公式,在这里我也想过不用矩阵相乘,利用for循环来依次相乘,但是时间复杂度很高,需要耗费很长时间,矩阵乘法可以完美的处理这些数据(x为n*2阶矩阵,theta为2*1阶矩阵,相乘得到n*1阶矩阵cost_matrix),利用np.sum()方法默认求出列之和

# 接下来是代价函数
def cost_func(x, y, theta):
    # 这里需要注意‘@’是矩阵的相乘,‘*’是对应数值的相乘,他们完全不同,矩阵相乘还有'np.not(A,B)'
    cost_matrix = np.power((x @ theta - y), 2)  # 这个就是矩阵相乘得到一个n*1维的矩阵与n*1维的y矩阵进行相减的平方
    return np.sum(cost_matrix) / (2 * len(x))  # 返回一个从1到n的一个方差和再乘1/2m得到此时theta的代价函数

 2.可以检查一下第一次的代价函数

检验一下第一轮的代价函数
print(cost_func(x,y,theta))

5.下降梯度算法

1.这里theta[0],theta[1]分别是代表theta这个2*1阶矩阵的第一行数据以及第二行数据,也就是下面的theta0和theta1,然后需要实时更新他们俩个变量,这里注意需要同时更新,最后记录好每一次的代价函数 

2.这里需要用到点乘所以用到了np.multiply()这个方法,点乘和矩阵乘法的区别自行去查找,需要注意的部分是x,y是np.matrix矩阵的类型而不是ndarray矩阵的类型,他们一方面的区别就是在使用'*' 的时候功能不同,在matrix里‘*’代表的是矩阵的乘积,如果不是正规矩阵相乘的格式会爆出错误,在ndarray里‘*’代表的是点乘,所以这里使用了上面的方法,我们需要的是点乘

3.这里x要取到population那一列,然后俩个n*1阶的矩阵进行点乘

4.len(x)和x.shape[0]的功能是一样的,用哪个都可以,目的就是为了取得行数

# 下面是梯度算法
def gradient_descent(x, y, theta, alpha, update_times):  # 梯度算法的形参需要变化速率alpha,以及更新的次数update_times
    cost_list = []
    for i in range(update_times):
        theta[0] = theta[0] - alpha * (np.sum(x @ theta - y)) / len(x)  # 这俩行是吴恩达老师所写的推导之后的公式
        # 下面一行注意要先取x里的population那一列,利用multiply()的方法来进行点乘
        theta[1] = theta[1] - alpha * (np.multiply((x @ theta - y) , x[:,1]).sum()) / len(x)
        temp0 = theta[0]
        temp1 = theta[1]
        cost = cost_func(x, y, theta)  # 更新代价函数
        cost_list.append(cost)  # 将代价函数放进代价列表中
        pass
    return theta, cost # 返回theta的矩阵以及最后一个代价函数

 6.构图展示

想了解matplotlib画图方法的可以自行学习,我也只是照猫画虎了一部分

# 下面是matplotlib的画图工具知识,可自行了解
data.plot(kind="scatter", x="population", y="profit", figsize=(8, 5),)
x = np.linspace(data.population.min(), data.population.max(), 100)
y = theta[1]*x + theta[0]
plt.plot(x, y)
plt.show()

 7.theta0,theta1结果

8.所有代码

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 将ex1data1里的内容取出来
data = pd.read_csv('ex1data1.txt', header=None, names=['population', 'profit'])
# 查询一下data是否取出
# print(data)
data.insert(0, 'ones', 1)  # 在第一列插入1,这样方便后面进行矩阵乘法的运算
x = data.iloc[:, 0:2]  # 取出第一列和第二列也就是人口的一列
y = data.iloc[:, 2:3]  # 取出最后一列也就是利润的一列(行全选)
x = np.matrix(x.values)  # 将x转换为矩阵
y = np.matrix(y.values)  # 将y也转换为矩阵
theta = np.zeros((2, 1))  # 将theta设置为一个空的矩阵


# 接下来是代价函数
def cost_func(x, y, theta):
    # 这里需要注意‘@’是矩阵的相乘,‘*’是对应数值的相乘,他们完全不同,矩阵相乘还有'np.not(A,B)'
    cost_matrix = np.power((x @ theta - y), 2)  # 这个就是矩阵相乘得到一个n*1维的矩阵与n*1维的y矩阵进行相减的平方
    return np.sum(cost_matrix) / (2 * len(x))  # 返回一个从1到n的一个方差和再乘1/2m得到此时theta的代价函数


# # 检验一下第一轮的代价函数
# print(cost_func(x,y,theta))

# 下面是梯度算法
def gradient_descent(x, y, theta, alpha, update_times):  # 梯度算法的形参需要变化速率alpha,以及更新的次数update_times
    cost_list = []
    for i in range(update_times):
        theta[0] = theta[0] - alpha * (np.sum(x @ theta - y)) / len(x)  # 这俩行是吴恩达老师所写的推导之后的公式
        # 下面一行注意要先取x里的population那一列,利用multiply()的方法来进行点乘
        theta[1] = theta[1] - alpha * (np.multiply((x @ theta - y) , x[:,1]).sum()) / len(x)
        temp0 = theta[0]
        temp1 = theta[1]
        cost = cost_func(x, y, theta)  # 更新代价函数
        cost_list.append(cost)  # 将代价函数放进代价列表中
        pass
    return theta, cost # 返回theta的矩阵以及最后一个代价函数


theta_last,cost_last = gradient_descent(x,y,theta,0.02,1500)
print(theta_last)

# 下面是matplotlib的画图工具知识,可自行了解
data.plot(kind="scatter", x="population", y="profit", figsize=(8, 5),)
x = np.linspace(data.population.min(), data.population.max(), 100)
y = theta[1]*x + theta[0]
plt.plot(x, y)
plt.show()

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>