假设有一堆按一定规律分布的
样本点,下面我以拟合直线为例,说说这种算法的原理。
其实很简单,先随意画一条直线,然后不断旋转它。每转一下,就分别计算一下每个样本点和直线上对应点的距离(误差),求出所有点的误差之和。这样不断旋转,当误差之和达到最小时,停止旋转。说得再复杂点,在旋转的过程中,还要不断平移这条直线,这样不断调整,直到误差最小时为止。这种方法就是著名的
梯度下降法(Gradient Descent)。为什么是梯度下降呢?在旋转的过程中,当误差越来越小时,旋转或移动的量也跟着逐渐变小,当误差小于某个很小的数,例如0.0001时,我们就可以收工
(收敛, Converge)了。啰嗦一句,如果随便转,转过头了再往回转,那就不是梯度下降法。
我们知道,直线的公式是y=kx+b,k代表斜率,b代表偏移值(y轴上的截距)。也就是说,k可以控制直线的旋转角度,b可以控制直线的移动。强调一下,
梯度下降法的实质是不断的修改k、b这两个参数值,使最终的误差达到最小。
求误差时使用 累加(直线点-样本点)^2,这样比直接求差距 累加(直线点-样本点) 的效果要好。这种利用最小化误差的平方和来解决回归问题的方法叫
最小二乘法(Least Square Method)。
问题到此使似乎就已经解决了,可是我们需要一种适应于各种曲线拟合的方法,所以还需要继续深入研究。
我们根据拟合直线不断旋转的角度(斜率)和拟合的误差画一条函数曲线,如图:
从图中可以看出,误差的函数曲线是个二次曲线,凸函数(下凸, Convex),像个碗的形状,最小值位于碗的最下端。如果在曲线的最底端画一条切线,那么这条切线一定是水平的,在图中可以把横坐标轴看成是这条切线。如果能求出曲线上每个点的切线,就能得到切线位于水平状态时,即
切线斜率等于0时的坐标值,这个坐标值就是我们要求的误差最小值和最终的拟合直线的最终斜率。
这样,梯度下降的问题集中到了切线的旋转上。切线旋转至水平时,切线斜率=0,误差降至最小值。
切线每次旋转的幅度叫做
学习率(Learning Rate),加大学习率会加快拟合速度,但是如果调得太大会导致切线旋转过度而无法收敛。
注意:对于凹凸不平的误差函数曲线,梯度下降时有可能陷入
局部最优解。下图的曲线中有两个坑,切线有可能在第一个坑的最底部趋于水平。
微分就是专门求曲线切线的工具,求出的切线斜率叫做
导数(Derivative),用dy/dx或f'(x)表示。扩展到多变量的应用,如果要同时求多个曲线的切线,那么其中某个切线的斜率就叫
偏导数(Partial Derivative),用∂y/∂x表示,∂读“偏(partial)”。由于实际应用中,我们一般都是对多变量进行处理,我在后面提到的导数也都是指偏导数。