1 概述

梯度下降(Gradient Descent)在机器学习中是很常用的算法,它不仅被用在了线性回归上,还被广泛应用于机器学习的众多领域,它的主要目的是通过迭代找到目标函数的最小值,或者收敛到最小值。

本文将从一个下山的场景开始,先提出梯度下降算法的基本思想,进而从数学上解释梯度下降算法的原理,解释为什么要用梯度,最后将此算法应用于具体的拟合直线的线性回归中。

2  梯度下降算法

2.1  场景假设

想象一下你正站立在一座红色山上,站立在山的一点上,在梯度下降算法中,我们要做的就是旋转360度,看看我们的周围,并问自己要在某个方向上,用小碎步尽快下山。这些小碎步需要朝什么方向?如果我们站在山坡上的这一点,你看一下周围,你会发现最佳的下山方向,你再看看周围,然后再一次想想,我应该从什么方向迈着小碎步下山,然后你按照自己的判断又迈出一步,重复上面的步骤,从一个新的点,你环顾四周,并决定从什么方向将会最快下山,然后又迈进了一小步,并依此类推,直到你接近局部最低点的位置。如图1所示,具体可描述为:首先以当前所处的位置为基准,寻找这个位置最陡峭的地方,然后朝着下降方向走一步,然后又继续以当前位置为基准,再找最陡峭的地方,再走直到最后到达最低处。

梯度下降算法原理及代码实现_java

图1 

2.2 梯度下降

梯度下降的基本过程就和下山的场景很类似。首先,我们有一个可微分的函数,这个函数就代表着一座山。我们的目标就是找到这个函数的最小值,也就是山底。根据之前的场景假设,最快的下山的方式就是找到当前位置最陡峭的方向,然后沿着此方向向下走,对应到函数中,就是找到给定点的梯度,然后朝着梯度相反的方向,就能让函数值下降的最快。因为梯度的方向就是函数变化最快的方向。所以,我们重复利用这个方法,反复求取梯度,最后就能到达局部的最小值,这就类似于我们下山的过程。而求取梯度就确定了最陡峭的方向,也就是场景中测量方向的手段。

梯度下降算法原理及代码实现_java_02

图2

2.3  数学解释

梯度下降算法原理及代码实现_java_03

梯度下降算法的直观理解

    接下来深入研究一下,更直观地感受一下这个算法是做什么的,以及梯度下降算法的更新过程有什么意义。梯度下降算法的更新规则如下:

梯度下降算法原理及代码实现_java_04

图3 

梯度下降算法原理及代码实现_java_05

3.1 导数项的意义

梯度下降算法原理及代码实现_java_06

图4 

梯度下降算法原理及代码实现_java_07

3.2 α的作用

梯度下降算法原理及代码实现_java_08

图5 

梯度下降算法原理及代码实现_java_09

    实际上,在梯度下降法中,当我们接近局部最低点时,梯度下降法会自动采取更小的幅度,这是因为当我们接近局部最低点时,很显然在局部最低时导数等于零,导数值会自动变得越来越小,所以梯度下降将自动采取较小的幅度。

梯度下降算法原理及代码实现_java_10

图6

4  线性回归梯度下降代码实现

    梯度下降算法和线性回归算法比较如下图:

梯度下降算法原理及代码实现_java_11

首先,我们需要定义一个代价函数,在此我们选用均方误差代价函数(也称平方误差代价函数)

梯度下降算法原理及代码实现_java_12

梯度下降算法原理及代码实现_java_13

梯度下降算法原理及代码实现_java_14

以上算法,有时也称为批量梯度下降。指的是在梯度下降的每一步中,我们都用到了所有的训练样本,在梯度下降中,在计算微分求导项时,我们需要进行求和运算,所以,在每一个单独的梯度下降中,我们最终都要计算这样一个东西,这个项需要对所有m个训练样本求和。

    下面给出具体实例,首先给出数据集:

梯度下降算法原理及代码实现_java_15

图7

利用MATLAB进行梯度下降线性回归拟合,得到拟合结果,如图8,同时给出代价函数的三维图及轮廓图,如图9,轮廓图中的红点即为取得的最优值:

梯度下降算法原理及代码实现_java_16

图8 

梯度下降算法原理及代码实现_java_17

图9 

部分MATLAB代码给出如下:

梯度下降算法原理及代码实现_java_18

梯度下降算法原理及代码实现_java_19