算命学之线性回归(二)

 

梯度下降法-线性回归...



算命学之线性回归(二)

上一篇的线性回归(一)里给大家介绍了用最小二乘法求线性方程参数,这次让我们换一种方法,用计算机+微积分的方式来求解。

用最小二乘法求解线性方程的方法,公式简便,用起来非常的爽快,但是缺点也很明显。矩阵乘法与求逆运算对于计算机来说是个挺费脑子的事,所以如果数据集非常大,电脑的运算就会变的很慢,百位的矩阵运算对现在的计算机来说,并不是什么困难事,但是一旦超过了万位,比如20000 x 20000的矩阵进行乘法或者求逆运算,普通PC可能就有些吃不消了。

所以,在数据集非常大的时候,我们可以用另一种“万能方法”来解,这个方法叫做“梯度下降法”,主要是用到大学本科里学到的微积分的内容,在机器学习的很多算法中都会应用梯度下降法来求解,下面我来介绍下算法的思想。





梯度下降法是用来求解方程最小值,也就是上一篇中直线方程的参数theta,确定了最小的theta,就找出了上图这个蓝色的最优直线,那么线性方程也就确定了,可以用来进行预测了。

重要的事情说三遍!

我们要求最小的theta值!

我们要求最小的theta值!

我们要求最小的theta值!

最小值怎么求呢?如果你还记得高中时候学过的求导,也许还有印象,导数就是函数上某一点处的切线,也是某一点处的斜率。导数等于0的时候会有最小值。



先看一个最简单的情况,对这条抛物线求导,平方拿下来,得到Y=2X,令2X=0可以得到最小值,X=0的时候函数会有最小值,也就是红色切线的部分。

还没想起来?不要紧,我们直接看下面的例子吧。



周末我去爬山,爬累了想下山回家,如何下山速度最快呢?肯定是沿着往最陡的方向走啦!我站在山顶上,每一步都沿着最陡峭的方向,也就是沿着图上的蓝色箭头方向,可以很快的下山。很显然,如果我沿着红色箭头的方向,下山会慢很多,影响我回家吃晚饭了,肯定不能走这条路。

这个蓝色的方向,就叫做“梯度”,是最陡峭的,也是导数的方向。我每走一步,都沿着最陡的方向,数学上来说就是“一步一求导”,很快就能下到山底,找到函数最小值。

有人可能会问,为什么最陡的方向就是导数的方向呢?如果我沿着红色线走是什么样的呢?如果我们走红色箭头的路线,会出现一个夹角COS(theta),导致我们这一步无法得到最小值。



如果X的次方数很高的话,函数图像会像上图一样,会有几个局部最小值。我们初始位置由于是随机选择的,有可能无法收敛到全局最小。所以最好在做之前,先判断一下这个函数是不是凸函数,也就是求函数的二阶导,如果二阶导大于0,说明函数是凸的,只有全局最小值。

下图就是一个凸函数,只有唯一的最小值。在3维里是一个这样的网兜状,在2维里就是上面的抛物线了。



现在来动手吧,上一篇我们做的是单变量线性回归,这次我们看看多变量的如何做。



让我随便构建一个数据源,从X1到X5共有5个变量,由于X0是常数,我就让它先等于1了。

我们这个数据源的直线方程是



现在是要根据这个数据源,求出一条直线,让这条直线和这些数据点的距离最短,即找到最小的距离平方和。



很多人看到这个公式又一次憋不住尿了,J是损失函数,意思是求能使函数达到最小值的参数theta0到thetaN,我们这个例子最多只有6个theta

等式右边的h(x)是我们的预测值,y是实际值,预测值减实际值,是每一点到直线的误差,然后求平方和,让所有点到这条直线的误差最小,就是我们的目标

正式开始,我站在山顶上,一开始我们先随便给所有的theta一个初值,假设都为1。然后我们要下山,迈出第一步,往哪个方向迈?也就是要求最陡方向也就是梯度,我们对损失函数求偏导数,即最陡的方向。



这个反向的6样子的符号是求偏导数的意思,偏导数就是有多个未知数,对多个未知数求导,比如有xyz三个变量,我们对x求偏导数,就令y和z都为常数,这样求导的时候,y和z就都会变成0了)

Alpha是我们下山的步子迈的多大,是人为设置的,随便设置多少都可以。当然步子迈的大了,很容易直接跨过最小值,导致无法收敛。设置小了,收敛缓慢,计算量大。

对以上的式子求偏导数之后,我们得到:



这个就是梯度下降算法的核心公式了。

下山每走一步,我们就更新一次theta,越接近山底,坡度越平缓,偏导数会更小,也就是说每步走的就会小一些,收敛也会越来越慢,直至收敛接近最小值。



至此方程里的6个theta值就都求解出来了。

唠唠叨叨说了一大堆,不知道大家有木有看懂,直接看代码可能会更清晰些。

输入数据源x和y,然后设置步长与迭代次数,给theta随意设定一个初值(这里是1),然后就开始下山循环了。如果发现迭代之后,theta数字非常大,说明步长设定过大,无法收敛,直接发散了。梯度下降不如最小二乘法的地方,就在于要设定步长与迭代次数,相对比较麻烦,如果数据维度不大的情况,还是更推荐用最小二乘法,简单粗暴!

还有很重要的一点,在写代码的时候,向量化虽然可以简化代码量,但是一定要注意矩阵相乘的维度,矩阵特性是mxn 点乘 nxm会得到mxm矩阵。我经常会遇到报错无法相乘的情况,通过对矩阵进行转置,保证相乘的维度正确即可。

如果您有任何疑问,欢迎直接留言狂喷,随时沟通交流。

下一篇预告:用梯度下降法实现Logistic回归


    关注 数据马里奥


微信扫一扫关注公众号

0 个评论

要回复文章请先登录注册