梯度下降(Gradient Descent)
梯度下降是机器学习最基础的一个算法,在我们初次涉及机器学习时,我们学习的第一个基本算法可以肯定的说就是梯度下降,而梯度下降更是机器学习的支柱。接下来我将总结梯度下降的基本原理并给出相应的代码实现。
梯度下降法
梯度下降法又称最快下降法。1847年由数学家柯西提出。函数在某点的梯度▽是一个方向,其方向是增长最快的方向。显然,负梯度方向是J(α)减少最快的方向。在梯度下降法中,求某函数极大值时,沿着梯度方向走,可以最快的到达极大值点,同理沿着负梯度方向走,则可以最快的到达极小值点。
其基本思想如下:
假设我们在一座山的某一位置,我们现在的任务是要以最快的速度下山,但我们又不知道如何下山。这时候我们想到了一种方法,即走一步算一步,寻找每一步是最陡的方向,也就是说我们要求解到当前位置的梯度,沿着梯度的负方向走,在进入下一位置后,重复刚才的步骤。就这样我们一步步走下去,一直走到我们觉得已经到达山脚位置。但注意的是,我们有可能没有到达山脚,而是到达了某一局部的山峰低处(及我们到达的点不是最小值而是一个极小值)。
从上面的解释我们可以看出,梯度下降不一定能找到全局的最优解,有可能是一个局部的最优解。当然,如果损失函数是凸函数,梯度下降法的得到的解就一定是全局最优解。
而函数变化最快的方向便是函数的梯度。
下面我们以线性回归问题进一步讲解梯度下降算法。
解决线性回归问题
假设我们现在有一系列的点,如下图所示
我们现在要通过梯度下降来拟合这条直线!
首先,我们需要定义一个损失函数(损失函数是梯度下降里的要点),在此我们选择均方误差代价函数
再此公式中
- m之数据集中点的个数
- 1/2是为了求导时消除后面括号上的平方,方便后面的计算
- y是数据集中每一个点的真是坐标y坐标的值
- h是我们的预测函数,根据每计算得到的预测得值,即
- 我们可以根据代价函数看到,代价函数中的变量有两个,所以是一个多变量的梯度下降问题,求解出代价函数的梯度,也就是分别对两个变量进行求偏导
基本的python packages
我们要实现梯度下降,下面附上那个一个较简单的代码
#批量梯度下降
#拟合函数:y = theta0 + theta1 * x
#损失函数: j = 1 / 2 * sum (y(x) - y) ^ 2
import matplotlib.pyplot as plt
#造数据
x_train = [150,200,250,300,350,400,600]
y_train = [6450,7450,8450,9450,11450,15450,18450]
#数据初始化
pace = 0.000000001 #步长
theta0 = 0 #01
theta1 = 1 #02
epsilon = 0.00001 #收敛值
#样本的个数
m = len(x_train)
#想要迭代次数
want = 5000
n = 1
def y(x):
return theta0 + theta1 * x
#开始迭代
while 1:
theta0_der = 0
theta1_der = 0
for i in range(m):
theta0_der += y(x_train[i]) - y_train[i]
theta1_der += (y(x_train[i]) - y_train[i]) * x_train[i]
theta0 -= pace * theta0_der
theta1 -= pace * theta1_der
print(theta0,theta1) #打印每一次迭代的值
n += 1;
#判断是否收敛
if (abs(pace * theta0_der) <= epsilon and abs(pace * theta1_der) <= epsilon) or want == n:
break
#数据可视化
plt.plot(x_train,[y(x) for x in x_train]) #训练出的一条直线是拟合的结果
plt.plot(x_train,y_train,'bo')
plt.show()