本文介绍如何推导与手写一个线性回归模型,涉及到数学推导没法事无巨细,所以下面只是一个大概的流程记录。
理论简述
假定有一份关于投放”广告费”与获得的”点击量”之间关系的数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
x,y 235,591 216,539 148,413 35,310 85,308 204,519 49,325 25,332 173,498 191,498 134,392 99,334 117,385 112,387 162,425 272,659 159,400 159,427 59,319 198,522 |
绘制散点图如下,线性回归模型就是要拟合出一个函数曲线,能够大致穿越这些点,这样预测就比较准确了:
我们尝试用这样的一次函数来拟合,需要调整的就是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带入画出其函数曲线,可见完美的穿越了样本集的点。
如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~

1