机器学习的基础算法-梯度下降算法

因为要开始学习机器学习的课程了,现在开始更新一下机器学习的一些内容!!!

在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降和最小二乘法是两个经常常用的方法。

在微分学中,对于多元函数的参数求偏导数,把求得的各个参数的偏导数以向量的形式写出来,这就是梯度。从几何意义上来讲,这就是函数变化增加最快的地方。在这里,有两种的形式即梯度下降和梯度上升,从一定意义上来讲,两者是可以相互转换的。可以用以下的一张图片来反映梯度:

在机器学习算法中,在最小化损失函数时,我们可以通过梯度下降法来一步步迭代求解,从而得到最小化的损失函数,和模型参数值。反过来,如果要求解损失函数的最大值就可以采用梯度上升法。当然,我们在求解的过程中,计算的最小值只能是局部最优解,不一定是全局最优解。

下面来讲解一下梯度下降算法的几个概念:

1、步长(学习率)(learning rate):步长决定了在梯度下降迭代的过程中,每一步沿梯度负方向前进的长度。

2、特征(feature):这个则是指的样本的输入部分。

3、假设函数(hypothesis function):在监督学习中,为了你和输入样本,而是用的假设函数,记作hθ(x)。

4、损失函数(loss function):为了评估模型的好坏,通常用损失函数来度量拟合程度。损失函数极小化,意味着拟合程度最好,对应的模型参数即为最优参数。

梯度下降算法的矩阵形式:(因为在计算机程序中,多数算法的实现都是通过矩阵计算来实现的)

1、先决条件,对于线性回归,假设函数hθ(x1,x2,...xn)=θ0+θ1x1+...+θnxn在矩阵表达式中表示为hθ(x)=Xθ,即hθ(x)为线性的,那么损失函数可以按照最小二乘法的推广形式进行构建J(θ)=(Xθ−Y)T(Xθ−Y)

2、算法参数的初始化:θ可以进行随机初始化,而epsilon作为算法终止的阈值和步长α都需要提前初始化。

3、算法过程:这一步很重要,这是参数更新的重要步骤;

       (1)确定当前位置的损失函数的梯度,对于θ向量,其梯度表达式为:

           

       (2)用步长乘以损失函数,即得到当前位置下降的距离,即     

       (3)确定θ向量里的每个值,梯度下降的距离都要小于epsilon,此时算法终止,而θ向量也停止更新,即为最优参数。否则,进入步骤4。

       (4)更新θ向量,其更新表达式如下,更新完毕后继续转入步骤1。

         

损失函数对于θθ向量的偏导数计算如下:

则步骤4更新表达式应为:

如何选择合适的步长,初始化参数是一个值得思考的问题。步长太大,可能造成迭代在极小值周围震荡,从而不收敛至极小值;步长太小,则迭代过程会过于缓慢,比如在三维曲面中,有一些局部凹陷的区域,当梯度下降到这个位置,会不断的迂回,从而使得整个函数的收敛过于缓慢而增加时间复杂度。

初始值不同,获得的最小值也有可能不同,因此梯度下降求得的只是局部最小值;当然如果损失函数是凸函数则一定是最优解。由于有局部最优解的风险,需要多次用不同初始值运行算法,关键损失函数的最小值,选择损失函数最小化的初值。

另外还有一个因素就是对特征数据进行归一化,对于每个特征x求出期望和标准差,然后转化为(xi−x)/std(x),这样转化后的特征新期望为0,方差为1,可以提高迭代效率。

用Python实现的代码如下:

def gradientdecent():
	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]
	#假设y与x呈现线性关系,即hθ(x)=θX,J(θ)=(Xθ−Y)T(Xθ−Y)
	epsilon=0.00001#初始化算法阈值为0.001
	theta=[0,0,0]#初始化theta为0
	alpha=0.01#初始化步长为0.01
	error0=0#残差基准值初始化为0
	#参数更新迭代过程
	while True:
		for i in range(len(x)):#更新参数theta
			theta[0]-=alpha*x[i][0]*(theta[0]+theta[1]*x[i][1]+theta[2]*x[i][2]-y[i])
			theta[1]-=alpha*x[i][1]*(theta[0]+theta[1]*x[i][1]+theta[2]*x[i][2]-y[i])
			theta[2]-=alpha*x[i][2]*(theta[0]+theta[1]*x[i][1]+theta[2]*x[i][2]-y[i])
		error1=0
		for j in range(len(x)):#带入真实数据,计算残差
			error1+=(y[j]-(theta[0]+theta[1]*x[j][1]+theta[2]*x[j][2]))**2/2
		if abs(error1-error0)<epsilon:#判断残差是否小于阈值
			break#收敛,结束
		else:
			error0=error1#不收敛,还原残差,继续迭代
	print(theta[0],theta[1],theta[2])
gradientdecent()

 

         

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值