吴恩达机器学习 ex1 python实现及 超详细解释(可能是全网最详细的语法及机器学习知识点梳理)

由于对python其实很不熟悉(本科基本没怎么用过,只了解一点基本语法),所以解释会比较细~
也是在实现的过程中边学python啦~

零:简单练习

输出一个5*5的单位矩阵
A=np.eye(5)
#实际上np.identity(5)也可以
print(A)

一:单变量线性回归

整个2的部分需要根据城市人口数量,预测开小吃店的利润
数据在ex1data1.txt里,第一列是城市人口数量,第二列是该城市小吃店利润。
(一)导入需要的包
import numpy as np
# 主要对多维数组执行计算(矩阵、数组运算的基础)
# 便于数值计算
import pandas as pd
# 通常用途相当于excel,对数据进行变换
import matplotlib.pyplot as plt
# 用于绘图的一个库

以上这些库anaconda均有~
如果使用pip 逐个安装也可

(二)导入数据集

将数据导入,我们才可以进行可视化和预测。数据导入使用pandas这个包

path='ex1data1.txt'
data=pd.read_csv(path,header=None,names=['Population','Profit']
#header 设置几,则表头从数据中第几行开始抽取
#names 通常用于数据表没有表头的时候,手动指定表头
#实际上names赋值后header会自动赋none
data.head() #数据预览

注意:此处导入的数据格式为DataFrame形式(表格),dataframe的每一个单列为series格式

(三)数据可视化

我们将数据可视化,本质是帮助我们选择算法拟合
不过此处我们还只学了线性回归~

data.plot(kind='scatter',x='Population',y='Profit',figsize=(12,8))
# figsize设置图形的大小 a为图形的宽,b为图像的高
plt.show()

如下图:
数据可视化
由此可看出 数据集存在一定的线性关系

(四)创建代价函数
	代价函数:用来评判假设曲线和实际值误差的函数,是关于theta的函数
	目标函数:最小代价函数
	线性回归的代价函数:平方误差函数
	所以我们要找满足目标函数要求的参数theta_0,theta_1

在这里插入图片描述
其中m是指样本数,x是输入变量(特征)
在这里插入图片描述

def computeCost(X,y,theta):
	#注意这里的函数形参均为矩阵
	m=len(X) #计算样本数
	part=np.power((X*theta.T-y),2)
	return sum(part)/(2*m)
	#将公式翻译

对于上面的X*theta.T,我们使用了"*"运算符,进行了矩阵乘法操作。但是我们如果将*当作矩阵乘法,那么我们必须保证两边操作数类型是matrix矩阵类型。并要符合矩阵的运算法则。

(五)添加一个x_0参数全为1
	我们通常通过向量化的方式来减少计算机的运算时间
	即h(x)=theta.T*X
data.insert(0,'Ones',1,Fals)
(六)变量初始化
	此处我们需要X,y矩阵来进行运算,所以需要取出这两者series,并转换为matrix
cols=data.shape[1] # 获取列数,便于根据列数划分要取的数据
#shape[0]是获取行数
X=data.iloc[:,:-1]
#X是data里除去最后列,-1指最后一列,所以此处切片切到倒数第二列
y=data.iloc[:,cols-1:cols] #y是data最后一列
#关于python中冒号和逗号的使用会单独开篇

X=np.matrix(X) 
y=np.matrix(y)
theta=np.matrix(np.array([0,0]))
(七)梯度下降函数
	我们使用梯度下降函数来调整参数,最小化代价函数。原理是重复直至收敛,正常运行是代价会逐渐缩小

在这里插入图片描述
在这里插入图片描述
注意:此处就是我们要向量化的原因,简化公式,便于编程

def gradientDescent(X,y,theta,alpha,iters):
	# alpha是学习率,iters是迭代次数
	temp=np.matrix(np.zeros(theta.shape))
	# 此处是初始化,初始化theta的shape形状下全0,创建零值矩阵,用于暂存theta
	parameters=int(theta.ravel().shape[1])
	# 此处的ravel()主要是将矩阵向量化,即将多维数组降至一维
	# 后shape[1]得出参数个数
	cost=np.zeros(iters)
	# 存储代价的一个数组,共iters*1维度
	for i in range(iters): #进行迭代,共进行1500次,range()返回的是一个可迭代对象
		error = (X*theta.T) - y #获取差值,这是个差值矩阵
		for j in range(parameters): #根据参数个数来确定这个循环的次数
			term=np.multiply(error,X[:,j])
			# 取所有行第j列的元素
			#乘以x_i  因为x_0等于1,所以这个式包含theta_0,theta_1
			temp[0,j]=theta[0,j]-((alpha/len(X))*np.sum(term))
			# (1,2)的矩阵,一个坐标是0,0;一个是0,1
			# 更新theta_j

		theta=temp	#更新全部theta值
		cost[i]=computeCost(X,y,theta) #更新对应迭代次数,对应theta的代价
	return theta,cost	
	# 这种方式会直接将多个返回值封装成元组
(八)应用梯度下降优化参数
	ex1的文件要求写了学习率0.01,迭代次数 1500次
alpha = 0.01
iters = 1500
theta,cost=gradientDescent(X,y,theta,alpha,iters)
# 或者用两个参数接收函数返回值也可以
print(theta)
print(cost)

此处output:
在这里插入图片描述

(九)预测
	预测当35000人和70000人的城市开店的利润
predict1=[1,3.5]*theta.T
predict2=[1,7]*theta.T
print(predict1)
print(predict2)

output:

[[0.45197679]]
[[4.53424501]]
(十)绘制线性模型以及数据,观察拟合程度
x = np.linspace(data.Population.min(),data.Population.max(),100)
# 绘图的一种函数
# 在指定的间隔内返回均匀间隔的数字,此处是在[人口最少数,人口最多数]之间
# 100是返回的样本数
f = theta[0,0] + (theta[0,1] * x)
# 假设函数

fig,ax=plt.subplots(figsize=(12,8))
# plt.subplots(),返回一个包含figure和axes对象的元组
# figure是指当前图形,axes指当前的轴
# 使用fig,ax = plt.subplots()将元组分解为fig和ax两个变量。
# figsize指画板的宽和高
ax.plot(x,f,'r',label='Prediction')
# label是指图例处对这条曲线的解答
# 绘制假设函数
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()
#原始数据以及拟合的直线

如图:在这里插入图片描述
实际上代价在梯度下降后是不断降低的。
在这里插入图片描述

(十一)全部代码
'''线性回归
单变量线性回归'''

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


# 定义计算代价的函数
def computeCost(X,y,theta):
	m = len(X) #样本个数
	inner = np.power(X*theta.T-y,2)
	return np.sum(inner)/(2*m)

def gradientDescent(X,y,theta,alpha,iters):
	temp = np.matrix(np.zeros(theta.shape))
	# 参数个数
	parameters = int(theta.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]=temp[0,j] - (alpha*np.sum(term)/(len(X)))
		theta=temp
		cost[i]=computeCost(X,y,theta)
	return cost,theta

alpha = 0.01
iters = 1500
path = 'ex1data1.txt'
data = pd.read_csv(path,header=None,names=['Population','Profit'])

# 数据可视化
data.plot(kind='scatter',x='Population',y='Profit',figsize=(12,8))
plt.show()

data.insert(0,'Ones',1,False)
# 处理数据
cols = data.shape[1]
X = data.iloc[:,:-1]
y = data.iloc[:,cols-1:cols]

X = np.matrix(X)
y = np.matrix(y)
theta = np.matrix(np.array([0,0]))


cost,theta_final=gradientDescent(X,y,theta,alpha,iters)
print(cost)
print(theta_final)

predict1=[1,3.5]*theta.T
predict2=[1,7]*theta.T
print(predict1)
print(predict2)

# cost=computeCost(X,y,theta)
# print(cost)

# 绘图(原始数据及拟合后曲线)
x = np.linspace(data.Population.min(),data.Population.max(),100)
f = theta[0,0] + (theta[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()

二:多变量线性回归

ex1data2.txt里的数据,第一列是房屋大小(size),第二列是卧室数量(bedrooms),第三列是房屋售价
此处需要根据已有数据,建立模型,预测房屋的售价

gradient descent函数可以用单变量的线性回归(已经一般化)

(一)特征归一化
	特征归一化的目的是为了缩短梯度下降收敛的时间,提高速度。
	此处房屋的大小约为卧室数的1000倍。
	特征归一化有两种常用的手段:1)最大最小规范化  2)Z-score均值规范化

这里使用Z-score均值规范化
在这里插入图片描述

data2 = (data2 - data2.mean()) / data.std()
#std()求data2的标准差
(二)梯度下降
g2, theta2=gradientDescent(X,y,theta,alpha,iters)
print(theta2)

输出:

[[-1.03197592e-16  8.78503652e-01 -4.69166570e-02]]
(三)绘制损失函数
我们通常可以通过绘制损失函数和迭代的关系看梯度下降是否进行地正常。(正常会逐步收敛)
fig = plt.figure(figsize=(12,8))
pl.plot(iternum,g2,'g-',label=u'Dense_Unet(block layer=5)')
# ‘’g‘’代表“green”,表示画出的曲线是绿色,“-”代表画的曲线是实线,可自行选择,label代表的是图例的名称,一般要在名称前面加一个u,如果名称是中文,会显示不出来,目前还不知道怎么解决。
p2 = pl.plot(iternum, g2,'r-', label = u'RCSCA_Net')
pl.legend()
#显示图例
pl.xlabel(u'iters')
pl.ylabel(u'loss')
plt.title('Compare loss for different models in training')
plt.show()

图片如图:在这里插入图片描述

(四)正规方程
正规方程和梯度下降的区别,梯度下降需要迭代、耗费系统资源较多、需要选择学习率、适用性良好;正规方程法无需选择学习率、无需迭代计算、n很大的时候计算缓慢
def normalEqn(X,y):
	# A=np.linalg.inv(X.T*X)
	# theta=A*X.T*y
	theta = np.linalg.inv(X.T@X)@X.T@y#X.T@X等价于X.T.dot(X)
	return theta


final_theta2 = normalEqn(X,y)
print(final_theta2)

此处值和梯度下降值有区别

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值