梯度下降算法拟合线性函数的python实现
梯度下降算法与线性回归算法的比较如下:
该问题便转换为求解凸函数即代价函数最小值的问题。
对于线性回归问题运用梯度下降法,关键在于求出代价函数的导数。
令代价函数为error_1=((my_y-y)**2)/2,不难发现其导数便是样本点与拟合点的残差。
构造目标数据集
import numpy as np
import matplotlib.pyplot as plt
#生成按照一定规律产生的数据
x=np.arange(30)
random_y=np.random.uniform(-5,5,30)
y=2*x+random_y+3
产生的数据集如下
构造目标凸函数
我们要构造的拟合函数是一次函数,因此有两个参数:my_y=theta1+theta2*x
构造差值凸函数:error_1=((my_y-y)**2)/2
利用梯度下降算法求解该凸函数
凸函数的构造与绘图:
#绘制误差函数三维可视图
s1=np.arange(-5,5,0.1)
s2=np.arange(-5,5,0.1)
S1,S2=np.meshgrid(s1,s2)
Z0=0
for i in x:
Zs=(S1+x[i]*S2-y[i])**2*0.5+Z0
Z0=Zs
plt.figure(1)
ax3 = plt.axes(projection='3d')
ax3.plot_surface(S1,S2,Zs,cmap='rainbow')
利用梯度下降算法求解凸函数
根据凸函数的表达式,我们可以看出目标点与真实值之间的残差即为该点的梯度值
#开始进入梯度下降算法主体部分
epsilon=0.001#迭代阈值
alpha=0.0001#学习率
#初始化参数
theta1=0
theta2=0
#损失函数
error0=0
error1=0
#拟合函数模型
#my_y=theta1+theta2*x
#误差函数error_1=sum(my_y-y)**2*0.5
#即(theta1+theta2*x[i]-y[i])**2*0.5
cnt=0#迭代次数
while True:
cnt=cnt+1
#计算残差,因为损失函数为二次方形式,因此计算残差来表示该点的梯度
#共有十个数据,为了避免矩阵维度的计算问题,我们使用一层for循环进行运算
for i in np.arange(30):
#计算残差,即拟合函数值减去真实值
cancha=theta1+theta2*x[i]-y[i]
theta1=theta1-alpha*cancha
theta2=theta2-alpha*cancha*x[i]
error1=0
for i in np.arange(30):
error1=error1+(theta1+theta2*x[i]-y[i])**2*0.5
c=error1-error0
if abs(c)<epsilon:
break
else:
error0=error1
print('theta1:%f,theta2:%f'%(theta1,theta2))
print('迭代次数:%d'%cnt)```
观察拟合效果
my_y=theta1+theta2*x
plt.figure(2)
plt.scatter(x,y)
plt.plot(x,my_y)