An athlete’s performance and the number of his trainings are as follows:
1)Plot the data
2)Write a program to fit the linear regression parameters ? to the data using gradient descent
3)Predict his performance in the 47th and the 55th training
其实这个例子似乎是被阉割的,不知道在哪里看到过这个例子的多变量版本
好了,问题来了,我们一直说梯度下降法梯度下降法,那么什么是梯度下降法呢,为啥我们不能就用最小二乘法呢,勒让德和高斯的方法难道不对吗?答案当然是否定的,这两种方法各有优劣。只是因为当今计算机计算速度发展,应生了梯度下降法,这种新思路使得人们能从更多方面来看待问题解决问题。形象来说,这就好比最小二乘法是基于大量的思考的方法,而另者则是基于大量的尝试的方法。
我们用经典的数学书上 爬山/下山 例子来说明。
想象我们在下山,从我所在的位置出发可以从很多方向下山,而最陡的那个方向就是梯度方向。梯度方向是函数变化最快的方向,沿着梯度方向可以最快地找到函数的最大值,而我们要求误差的最小值,所以在梯度下降中我们要沿着梯度相反的方向。具体来说就是,以你当前的所处的位置为基准,寻找这个位置最陡峭的地方,然后朝着山的高度下降的地方走,同理,如果我们的目标是上山,也就是爬到山顶,那么此时应该是朝着最陡峭的方向往上走。然后每走一段距离,都反复采用同一个方法,最后就能成功的抵达山谷。
只有一个下坡时(传统凸优化)
凹凸不平时(非凸函数)
ok,现在我们已经知道不断沿着梯度可以找到极值点了(对于凸函数是最值点)!
下一步,我们来看看我们下山找最值点有什么实际意义呢
类似于最小二乘法,我们定义一个想要优化的函数(称为损失函数),当这个函数取得极值时,我们得到最佳的拟合参数。
这里就以本题为例,x可以视为单变量。但事实上,多变量矩阵形式对本式同样适用。
因为是对于梯度来说,我们需要对刚刚定义的损失函数进行求导,并且定义一个系数a,用a来控制每次更新theta的速度(下面其实是两步合并,第一步我们求出导并用a倍乘,第二步我们用刚刚的结果来更新手头视为theta,也就是下山一步后再环顾四周再考虑新的路线)
好,以上就是梯度下降法的简介与数学表达。
下面为了联系理论与实际,我们来一起看看这种思路是如何计算拟合开头给出的例子!
鲁迅说过,写博客不给实现代码,都是耍流氓
[雾 ٩( ‘ω’ )و
import numpy as np
import matplotlib.pyplot as plt
N = 8
x = np.array([30,33,35,37,39,44,46,50]).reshape(N,1)
y = np.array([30,34,37,39,42,46,48,51]).reshape(N,1)
plt.scatter(x,y,color="orange",linewidth=0.5)
ones = np.ones((N, 1))
x = np.hstack((x, ones))
def CostFunction(theta, x, y):
diff = np.dot(x, theta) - y
loss = (1./2*N)*(np.dot(np.transpose(diff), diff))
return loss
def CostGradient(theta, x, y):
diff = np.dot(x, theta) - y
gradient = (1./N)*(np.dot(np.transpose(x), diff))
return gradient
def Iteration():
alpha = 0.001
theta = np.array([1, -0.1]).reshape(2, 1)
gradient = CostGradient(theta, x, y)
epsilon = 0.001
while np.linalg.norm(gradient) > epsilon:
theta = theta - alpha * gradient
gradient = CostGradient(theta, x, y)
return theta
Right_theta = Iteration()
print('下降后θ值为:')
print('θ(0)=',Right_theta[1][0],'θ(1)=',Right_theta[0][0])
print('拟合函数为:')
print('y=',Right_theta[1][0],'+',Right_theta[0][0],'x')
print('预测第47次训练后,运动员表现:',Right_theta[1][0]+Right_theta[0][0]*47)
print('预测第55次训练后,运动员表现:',Right_theta[1][0]+Right_theta[0][0]*55)
x1 = np.linspace(25, 55, 100)
y1 = Right_theta[0]*x1 + Right_theta[1]
plt.plot(x1, y1,color="black",linewidth=0.5)
plt.rcParams['figure.figsize'] = (8.0, 8.0)
plt.show()
这里关于python的基础知识就不再赘叙了。matplotlib画图包和numpy的矩阵操作函数网上都有很详细的教程,唯一需要大家注意的就是矩阵运算时的复杂性,稍不注意就会出现逻辑错误(不要问我怎么知道)
如果有细节问题可以QQ
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
from scipy.optimize import leastsq
x = np.array([30,33,35,37,39,44,46,50])
y = np.array([30,34,37,39,42,46,48,51])
plt.scatter(x,y,color="orange",linewidth=0.5)
def func(p,x):
k,b=p
return k*x+b
def error(p,x,y):
return func(p,x)-y
p0=[1, -0.1]
Para=leastsq(error,p0,args=(x,y))
k,b=Para[0]
print('最小二乘法求解系数:')
print('k=',k,'b=',b)
print('拟合函数为:')
print('y=',b,'+',k,'x')
print('预测第47次训练后,运动员表现:',b+k*47)
print('预测第55次训练后,运动员表现:',b+k*55)
x1 = np.linspace(25, 55, 100)
y1 = k*x1+b
plt.plot(x1, y1,color="black",linewidth=0.5)
plt.rcParams['figure.figsize'] = (8.0, 8.0)
plt.show()
贴图,下面为梯度下降法
最小二乘法
可以看出,二者差别甚微,梯度下降法的拟合思路是正确的。
具体来说,二者的差别如下:
两种模型各有利弊,至于选择哪种模型,需要基于数据量与需求综合考量,二者本质上并无优劣之分。
CSDN首篇,AI本科在读,欢迎大佬来指出错误。