当前位置: 首页 > 后端技术 > Python

机器学习笔记(八)——随机梯度上升(下降)算法调优

时间:2023-03-25 22:42:44 Python

前言概述上一篇文章简单介绍了逻辑回归的原理和基本思想,并通过引入Sigmoid函数和梯度公式成功推导了梯度上升和梯度下降的公式都出来了。以上分类实例都是基于full-batchascent方法,本文将介绍一种full-batch梯度上升的优化算法——随机梯度上升。不懂逻辑回归原理和推理公式的,还请看上一篇:机器学习笔记(七)——逻辑回归入门,以及梯度公式推导的两种方法。stochasticgradientascent的比较在解释full-batchgradientascent和stochasticgradientascent的区别之前,我们先来看一下两者的公式比较,有助于后面的理解。Full-batch梯度上升法:Stochasticgradientascentmethod:我们已经很熟悉full-batch梯度上升的公式,在上一篇文章中介绍过;其实stochasticgradientascent和full-batch公式很相似,原理也大致相同,区别体现在哪里呢?fullbatch每次更新回归系数都需要遍历整个数据集。这种方法在处理小数据集的时候还好,但是如果有几十亿的样本和几千个特征,这种方法的计算量就太大了。高的。随机梯度上升一次只使用一个样本点来更新回归系数,大大降低了计算复杂度,提高了函数的收敛速度。改变算法StochasticGradientAscentAlgorithm伪代码如下所有回归系数初始化为1计算数据集中每个样本的梯度使用alpha*gradient更新回归系数值返回回归系数值因为两个公式大致是相同,所以stochasticgradientascent方法的代码只会略有不同。defstocGradAscent1(dataMatrix,classLabels):#将列表转换为数组格式dataMatrix=np.array(dataMatrix)#获取dataMatrix的行数和列数m,n=np.shape(dataMatrix)#初始化回归系数和步长sizeweights=np.ones(n)alpha=0.01foriinrange(m):#遍历样本,一次选一个,计算hh=sigmoid(sum(dataMatrix[i]*weights))#计算误差error=classLabels[i]-h#更新回归系数weights=weights+alpha*error*dataMatrix[i]returnweights可以看到两种算法有一些区别:一是随机梯度上升的变量h和errorerror都是数值,而在全批中都是矢量格式;其次,随机梯度没有矩阵运算,所有变量的数据类型都是Numpy数组。执行以上代码,得到一条新的最佳拟合直线图,如下:可以看出,这条新的最佳拟合直线只对一半的样本正确。明明是优化算法,可是准确率怎么会越来越低呢?原因是full-batch梯度上升法是对整个数据集迭代500次得到的,迭代次数远大于随机梯度法。判断一个算法好坏的可靠方法是看它是否收敛,即参数是否达到稳定值后是否会继续变化?下图展示了两种方法的迭代次数与回归系数的关系:可以看出,fullbatchgradient的三张回归图相较于randomgradient有比较大的波动幅度,最明显的是fullbatchgradient回归系数X2用于比较。前者在下标值为300时收敛完成,后者的曲线在下标为14000时基本稳定;但是这里需要注意的是,fullbatchgradient的每次迭代都使用了整个数据集,所以该方法收敛时的准确迭代次数应该是30000次,远大于stochasticgradient的迭代次数。在随机梯度法中,大的波动之后会有很多小的周期性波动。出现这种现象的原因是有些样本点无法正确分类,会导致每次迭代时系数发生剧烈变化。我们希望算法能够避免波动问题,从而收敛到某个值,加快收敛速度??。算法调优所以对随机梯度上升算法做如下改进:defstocGradAscent2(dataMatrix,classLabels,numIter=150):#将列表转换为数组格式dataMatrix=np.array(dataMatrix)#获取行数和列数ofdataMatrixm,n=np.shape(dataMatrix)#初始化回归系数和步长weights=np.ones(n)forjinrange(numIter):dataIndex=list(range(m))foriinrange(m):#逐渐降低alpha,每次降低1.0/(j+i)1,alpha=4/(1.0+j+i)+0.01#随机选择样本2,randIndex=int(random.uniform(0,len(dataIndex)))#随机选择一个样本,计算hh=sigmoid(sum(dataMatrix[randIndex]*weights))#计算误差error=classLabels[randIndex]-h#更新回归系数weights=weights+alpha*error*dataMatrix[randIndex]#删除已经使用过的样本del(dataIndex[randIndex])returnweights第一个改进是调整e中步长alpha的值ach迭代,alpha会在每次迭代中减少1/(j+i),其中j为迭代次数,i为样本点的下标。虽然alpha会随着迭代次数的增加而不断减小,但它永远不会减小到0,并且有一个常数项。这是因为经过多次迭代后alpha的值接近于0,使得新的数据对回归系数的更新几乎没有影响。这里我再用图来说明为什么alpha要这样优化。上图是二次函数的图像。一开始梯度很大,步长alpha可以比较大,但是梯度在逐渐减小。此时离最优值越来越近,步长alpha也相应减小。如果下降幅度很大,当梯度接近最优点时,梯度乘以一个比较大的alpha,就会出现下图所示的情况。比如直接从1点跳到2点,开始震荡。上面迭代次数和回归系数的关系出现大振荡的原因,上面对步长alpha的优化可以避免这种情况,虽然用的例子是Gradientdescent,但是梯度上升的原理和梯度下降是一样的。第二次改进的目的是减少随机梯度关系图中的周期性波动。这里通过随机选择样本来更新回归系数,每次从列表中随机选择一个值,然后从列表中删除该值,然后进行下一步。一次迭代,类似于决策树如何选择信息增益。下图展示了改进后的随机梯度上升法迭代次数与回归系数的关系。可以看出,该方法的三个回归系数图像比固定步长alpha的方法收敛得更快,并且没有周期性的波动。为了更直观的看到改进后算法的效果,下图展示了改进后算法通过以下算法绘制的最佳拟合直线图。最终随机梯度的分类效果和fullbatchgradient几乎一样,只是迭代次数少很多,所以前者大大降低了算法的计算复杂度,减少了程序占用的内存。总结在文章的最后,我会总结一下full-batch梯度下降法、随机梯度下降法、small-batch梯度下降法的优缺点,即因应场合。FullBatchGradientDescent(BGD):所有样本都参与回归系数的每次更新。优点:分类准确,获得全局最优解缺点:样本多时,训练速度极慢适用场合:样本少的数据集随机梯度下降法(SGD):回归的每次更新只有一个样本参与系数。优点:训练速度快缺点:准确率会下降,不朝整体最优方向,容易求出局部最优解适用场合:样本量多的数据集Mini-batch梯度下降法(MBGD)):每次都有部分样本参与更新回归系数。该方法兼顾了上述两种方法的优点,同时削弱了两者的缺点,可以看作是前两种算法的平衡。如果数据集的样本量不是很极端,最好使用mini-batch梯度下降。关注公众号【奶糖猫】后台回复“随机梯度”获取源码参考,感谢阅读。