numpy机器学习 — 实现线性回归

本文介绍如何推导与手写一个线性回归模型,涉及到数学推导没法事无巨细,所以下面只是一个大概的流程记录。

理论简述

假定有一份关于投放”广告费”与获得的”点击量”之间关系的数据:

绘制散点图如下,线性回归模型就是要拟合出一个函数曲线,能够大致穿越这些点,这样预测就比较准确了:

我们尝试用这样的一次函数来拟合,需要调整的就是theta0和theta1参数,最终尽量拟合到这些数据点:

怎么调整这两个系数呢?我们需要定义要优化的目标函数,也就是令“预测值”与“期望值”之间的差尽量小,例如我们可以这样列出一个表格:

因此,我们定义目标函数(未知数是theta,因为只能通过优化theta来让损失E(theta)尽量小)如下:

公式意思就是求每个样本y和预测y之间的差的平方,求和后除2,这就叫”最小二乘法“。

样本x(i)和y(i)是固定的数据,因此只要想办法调整theta,让这个表达式的值尽量小即可。

这个关于theta的目标函数是二次项的形式,其函数曲线如下:

如果当前theta作为横坐标带入目标函数后所处的曲线是向下的,也就是微分(斜率)是负的,那么需要让theta朝更大方向移动,以便让这个目标函数y值向更小的方向移动(损失更小了),这样就是优化theta的方法,也就是梯度下降

所以只要求每个theta系数的偏导数,乘上一个很小的学习率,来调整当前的theta让其朝着损失更小的方向移动即可,这个过程就是模型训练。

求E关于各个theta的微分过程不做展开介绍,需要用到复合函数求导,最后得到如下的theta更新公式:

我们只需要反复带入所有样本x(i),y(i)进行计算,修正theta即可。

代码开发

把训练样本的x和y读取进来,因为x的范围较大可以考虑标准化一下(可选):

标准化不止一种做法,这里就是让x减去均值作为偏离均值的绝对大小,再除以标准差代表偏离的比例。

将训练数据绘制出来:

定义回归函数,这里我用了三次方的项,这样拟合出的函数就可以是弧线了:

初始的theta系数都是随机的,梯度下降这些theta的数学推导没有区别,还是求它们的偏导数,不做展开。

接着准备好训练的控制参数,以及目标函数(误差函数):

目标函数就是样本集中的每个真实y和预测y之间的误差平方和除以2,理论部分讲过。

训练时我采用了随机梯度下降+minibatch的方法,每次从样本中随机抽N个样本来做训练,这是有原因的:

每次使用全量样本进行训练的话,E(theta)的函数中的x(i),y(i)是稳定的,因此E(theta)的函数曲线就是不变的,在梯度下降修正theta沿着x轴移动时会因为局部的波谷而停止下降,导致得到的是局部最小,也就是局部最优解,所以才需要每次让x(i),y(i)变化来产生不同的E(theta)函数曲线。

下面就是局部最优解的情况,使用随机方式就可以避免这个问题:

更新theta_n是基于偏导数的,只要数学推导出来就只剩下代码简单计算一下的问题而已,不需要担心。

最终模型停止训练的条件是连续2轮训练后,模型的目标函数(误差函数)之间的差值很小,这证明目标函数已经到达底部,无法通过调整theta再继续下降到更小值了。

最后回归函数f(x)中的theta系数已经训练好了,我们把一组连续的x带入画出其函数曲线,可见完美的穿越了样本集的点。

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~