机器学习-梯度降低参数调优小结

在机器学习领域,经过对特征的参数调优可让模型的预测值更接近真实值的常见的两种方法包括最小二乘法和梯度降低方法。目前梯度降低更成为了一种解决问题的方法和思路,在集成学习和深度学习领域都有较多的应用。html

定义

直观理解“梯度降低”:咱们在山上想要下山的时候,不知道方向,手头上只有一个仪器能够提醒当前的海拔,这时候随意的走一步能够知道海拔变大仍是变小,往海拔变小的方向一步一步走,经过顺着梯度降低的方向一步步缩小海拔,直到海拔也基本没有变化为止,这样咱们就从山顶走道山下。这就是梯度降低的一个运算思惟。在实际的机器学习中,山顶的海拔高度表明了模型的预测值和真实值之间的差距,而梯度降低的方法是经过不断迭代的方式来缩小这个差距,直到该差距收敛到极小值,从而肯定参数。
以电子商务推荐算法为例,从建模的角度描述如何经过梯度降低来作参数调优:
用户对于商品的兴趣能够经过简单的线性回归建模,并设计函数h(x)来表明模型预测用户对于某个商品的购买兴趣,若是购买兴趣高,则能够做为商品推荐。模型的公式以下:
image
其中X(x1,x2…)是购买行为的特征,例如用户的年龄和喜爱,商品类别和价格,参数组θ(θ0,θ1…)表示特征对于预测值的影响大小。
机器学习中除了包括数据分析、特征选择、模型选择以外,还有一个步骤是参数调优。假设 模型的X已经肯定,目前须要肯定参数组θ,来评估对于特定用户对于特定商品的购买兴趣而言,到底是商品的价格重要仍是用户的爱好影响更重要。
咱们须要构建一个损失函数去评估所选择参数的优劣,简单的认为在当前参数组θ,直接比较预测值和真实值差距便可,公式表达为:
image
梯度学习方法就是经过调整参数组θ从而让J(θ)取得最小值,调整的方法与从山上顺着梯度朝下同样:python

  1. 首先对θ初始赋值,这个值能够是随机的,也可让θ是一个全零的向量。
  2. 改变θ的值,使得J(θ)按梯度降低的方向进行减小,直到损失函数差减少收敛到极小值或者0为止。

第二个步骤是关键步骤,就是如何让θi会向着梯度降低的方向进行减小,对于(θ)求偏导J,咱们能够进一步获得θ的变化函数:
image
其中α表示步长,h(x)-y表示上次偏差,经过上次偏差、步长和变量来反馈更新θi。更新的图示以下,其中的两个黑线都是
Boosting
当参数组θ的每个参数都按照这样的计算公式进行变化更新的时候,模型的预测值将会以梯度的方向接近真实值,最终获得一个最优值,这个最优值多是局部最优也多是全局最优,咱们将在后面的章节讨论这个问题。算法

关联概念

在上一章节,咱们举的建模样例中提到了一些概念,系统介绍一下:数组

  • 特征x:建模的输入变量,例如商品推荐中商品的价格、类别等参数。
  • 预测值:建模h(x)的输出指标,例如商品推荐中预测用户对于某商品的兴趣程度。
  • 损失函数 J(θ):为了评估模型拟合的好坏,一般用损失函数来度量拟合的程度。损失函数极小化,意味着拟合程度最好,对应的模型参数即为最优参数。在线性回归中,损失函数一般为样本输出和假设函数的差取平方。
  • 步长:梯度降低过程当中,每一步参数变化的长度大小。步长的设置应该仔细斟酌,若是过小,获得最优参数组合的速度很慢(须要迭代的轮数次数会不少),若是太大,收敛过早获得的并不是是最优参数,模型的可靠性不高。
  • 初始赋值:初始值不一样,得到的最小值也有可能不一样,所以梯度降低求得的只是局部最小值;固然若是损失函数是凸函数则必定是最优解。因为有局部最优解的风险,须要屡次用不一样初始值运行算法,关键损失函数的最小值,选择损失函数最小化的初值。
  • 退出阈值:当梯度降低的降低幅度达到该阈值时,退出梯度降低。该退出阈值应该尽可能接近0(若是有充足的资源进行迭代训练的话),我我的认为最低不大于步长的百分之一,即在最大百分之一步长内的变化即认为收敛到没法变化了。

对于步长和退出阈值应该基于训练数据屡次遍历后判断得出机器学习

在训练的时候一个技巧:对特征值x进行归一化处理提升迭代的速度。能够参考博文 的方法。函数

算法版本

批量梯度降低

批量梯度降低法的作法是,当前一步的梯度降低迭代遍历中参数空间θ的保持不变,当前步结束后,使用更新后的参数θ得到步长大小,而后进行下一步的梯度降低,这就是批量的梯度降低思路。
批量梯度降低的方法须要计算整个数据集才会更新一次参数θ,对于数据集较大的状况下,会很是耗时,另外也不适用于在线更新模型的应用状况,所以应用不太普遍。
代码示例以下:学习

x = [(1,0.,3) , (1,1.,3) ,(1,2.,3), (1,3.,2) , (1,4.,4)]
y = [95.364,97.217205,75.195834,60.105519,49.342380]
my_break=0.00001
alpha=0.01
diff=0
error1,error0=0,0
theta0,theta1,theta2=0,0,0
sum0,sum1,sum2=0,0,0
while True:
    for i in range(len(x)):
        #批量更新参数
        diff=y[i]-(theta0*x[i][0]+theta1*x[i][1]+theta2*x[i][2])
        sum0=sum0+alpha*diff*x[i][0]
        sum1=sum1+alpha*diff*x[i][1]
        sum2=sum2+alpha*diff*x[i][2]
        count+=1
    theta0,theta1,theta2=sum0,sum1,sum2
    error1=0
    for i in range(len(x)):
        error1+=(y[i]-(theta0*x[i][0]+theta1*x[i][1]+theta2*x[i][2]))**2/2
        count+=1
    if abs(error1-error0)<my_break:
        break
    else:
        error0=error1
print("Done: theta0:{0}, theta1:{1}, theta2:{2}.".format(theta0,theta1,theta2))

随机梯度降低

随机梯度降低与批量梯度降低相似,惟一的区别在于在每一步梯度降低的迭代遍历中,参数空间θ都在变化。也便是说批量梯度降低用全部数据来作梯度降低,随机梯度降低用的是单条数据来作梯度降低。
随机梯度降低的优势是训练速度快,随之而来的是所获得的解并非最优解,准确度没有批量梯度降低好,尤为是当训练数据噪音比较大的状况。
代码演示以下:测试

x = [(1,0.,3) , (1,1.,3) ,(1,2.,3), (1,3.,2) , (1,4.,4)]
y = [95.364,97.217205,75.195834,60.105519,49.342380]
my_break=0.00001
alpha=0.01
diff=0
error1,error0=0,0
theta0,theta1,theta2=0,0,0
sum0,sum1,sum2=0,0,0
min_x=2
while True:
    for i in range(len(x)):
        #迭代内参数被单次样本迭代进行更新
        diff=y[i]-(theta0*x[i][0]+theta1*x[i][1]+theta2*x[i][2])
        theta0=theta0+alpha*diff*x[i][0]
        theta1=theta1+alpha*diff*x[i][1]
        theta2=theta2+alpha*diff*x[i][2]
        count+=1
    error1=0
    for i in range(len(x)):
        error1+=(y[i]-(theta0*x[i][0]+theta1*x[i][1]+theta2*x[i][2]))**2/2
        count+=1
    if abs(error1-error0)<my_break:
        break
    else:
        error0=error1
print("Done: theta0:{0}, theta1:{1}, theta2:{2}.".format(theta0,theta1,theta2))

小批量梯度降低

小批量梯度降低结合了批量梯度降低准确度高和随机梯度降低训练速度快的特色,对于训练集m的迭代中,选择x(1<x<m)次迭代后,参数空间θ进行更新。优化

x = [(1,0.,3) , (1,1.,3) ,(1,2.,3), (1,3.,2) , (1,4.,4)]
y = [95.364,97.217205,75.195834,60.105519,49.342380]
my_break=0.00001
alpha=0.01
diff=0
error1,error0=0,0
theta0,theta1,theta2=0,0,0
sum0,sum1,sum2=0,0,0
count=0
min_x=2
while True:
    count_x=0
    for i in range(len(x)):
        diff=y[i]-(theta0*x[i][0]+theta1*x[i][1]+theta2*x[i][2])
        sum0=sum0+alpha*diff*x[i][0]
        sum1=sum1+alpha*diff*x[i][1]
        sum2=sum2+alpha*diff*x[i][2]
        count_x+=1
        #在迭代内部小批量迭代更新参数
        if count_x%min_x==0:
            theta0,theta1,theta2=sum0,sum1,sum2
        count+=1

    error1=0
    for i in range(len(x)):
        error1+=(y[i]-(theta0*x[i][0]+theta1*x[i][1]+theta2*x[i][2]))**2/2
        count+=1
    if abs(error1-error0)<my_break:
        break
    else:
        error0=error1
print("Done: theta0:{0}, theta1:{1}, theta2:{2}.".format(theta0,theta1,theta2))

过分拟合

梯度降低的目标是在下降预测值和真实值之间的差距从而得到最优的参数空间,基于已有的数据进行迭代训练,须要特别注意”过分拟合“的现象。
防止过分拟合的方法能够参考这篇博文机器学习:防止过拟合的方法
这里参考wiki使用Early Stopping的方法来作防止过拟合:.net

  1. 将训练数据分隔成训练集和测试集,80%:20%或者2:1的比例都行;
  2. 只基于训练集进行训练,每轮训练集迭代后记录并记为一次EPOCH,每隔N(N=5,8…)个epoch在测试集上运行validation metric进行计算获得validation accuracy并,validation metric能够是模型表现的评估函数;
  3. 当连续M(M=10)次EPOCH没有达到最佳的validation accuracy,中止在训练集上的迭代;
  4. 记录最佳validation accuracy所对应的参数。

上述的方法是与梯度降低结合使用的,也能够认为在梯度降低的退出条件中增长了一个过渡拟合。除此以外,还能够选择交叉验证、拓展数据集数据等方法来进行过拟合。

局部最优VS全局最优

在不考虑模型过拟合的状况下,梯度降低获得的最优解不必定是全局最优解,也有多是局部最优解,注意本文第三章节的代码示例中,梯度降低的退出条件:

if abs(error1-error0)<my_break:
    break

在降低过程当中,咱们找到了一个数据无变化的点(不动点),这个不动点可能有三个含义:极大值、极小值和鞍点。在梯度降低中,极大值基本上可能性没有,只有多是极小值和鞍点。当前仅当梯度降低是凸函数时,梯度降低会收敛到最小值。
也就是在使用梯度降低中,咱们最大可能获得是局部最优解。
为了确保不动点是局部最优解,能够设置更小的退出阈值,进行屡次比较看看参数是否变化,若是变化了,说明能够再次调试。
总的来讲,梯度降低时一种得到最优解的参数组合的思路,实际应用过程当中会结合多种优化方法一块儿使用。

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

相关文章
相关标签/搜索