发布时间:2022-08-18 18:27
我是机器学习的初学者,同时也是python的初学者,通过室友推荐吴恩达老师的机器学习,就随着课程找了csdn中的大神们的文章进行学习,自己摸索着做了一份,我会尽量把我所了解的解释清楚
如果不会在pycharm导入这三个包的可以去翻我上一篇文章,里面展示了俩种方法以及这过程中可能会出现的问题
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
此数据集可以去自行查找,很小的一个文件,包含了俩列数据
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设置为一个空的矩阵
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))
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的矩阵以及最后一个代价函数
想了解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()
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()