ML笔记(三)线性回归梯度下降法

本文深入探讨了梯度下降法的原理,详细解释了如何通过调整模型参数来最小化损失函数,特别是在线性回归场景中的应用。文章还提供了梯度下降法的Python代码实现,帮助读者理解其工作流程。

1 梯度下降法

1.1原理

J(θ)J(\theta)J(θ)是模型的损失函数,我们设定初始参数θ\thetaθ,不断迭代,使得J(θ)J(\theta)J(θ)最小化:
θj:=θj−α∂J(θ)∂θ\theta_j:=\theta_j-\alpha\frac{\partial{J(\theta)}}{\partial\theta}θj:=θjαθJ(θ)

这里∂J(θ)∂θ\frac{\partial{J(\theta)}}{\partial\theta}θJ(θ)体现的是损失函数减少方向,θj\theta_jθj表示模型的参数,α\alphaα表示学习率,是我们梯度的步长参数。在线性回归中,这个θj\theta_jθj向量表示了自变量的系数和常数项。

  • 迭代终点:当损失函数的导数为0时停止迭代,认为当前点是模型参数的最优点。
  • 迭代缺点:在曲折的损失函数中,导数等于0可能表示局部最优解,并不是全局最优解。在实际运行中,尽可能的多次选择初始值并迭代。
  • 迭代现象:导数越接近于0的时候,∂J(θ)∂θ\frac{\partial{J(\theta)}}{\partial\theta}θJ(θ)的值会越小,意味着参数的值变化的频率会更快,所以在一个迭代进行中时我们并不需要调整α\alphaα的值
  • α\alphaα值的选择应谨慎,α\alphaα太大会导致结果不收敛,太小会增大计算量。

1.2 线性回归的梯度下降

线性回归函数:f(x)=θ0+θ1x1+θ2x2f(x)=\theta_0+\theta_1x_1+\theta_2x_2f(x)=θ0+θ1x1+θ2x2
线性回归的损失函数:
J(θ)=12∑j=1n(hθ(x(i))−y(i))2J(\theta)=\frac{1}{2}\sum_{j=1}^{n}(h_{\theta}(x^{(i)})-y^{(i)})^2J(θ)=21j=1n(hθ(x(i))y(i))2

对损失函数求导:
∂J(θ)∂θ=∂∂θj12∑i=1n(fθ(x)(i)−y(i))2=2∗12∑i=1n(fθ(x)(i)−y(i))∗∂∂θj(fθ(x)(i)−y(i))=∑i=1n(fθ(x)(i)−y(i))∗∂∂θj(∑j=0dθjxj(i)−y(i)))=∑i=1n(fθ(x)(i)−y(i))xj(i)\begin{aligned} \frac{\partial J(\theta)}{\partial \theta} &=\frac{\partial}{\partial \theta_{j}} \frac{1}{2} \sum_{i=1}^{n}\left(f_{\theta}(x)^{(i)}-y^{(i)}\right)^{2} \\ &=2 * \frac{1}{2} \sum_{i=1}^{n}\left(f_{\theta}(x)^{(i)}-y^{(i)}\right) * \frac{\partial}{\partial \theta_{j}}\left(f_{\theta}(x)^{(i)}-y^{(i)}\right) \\ &\left.=\sum_{i=1}^{n}\left(f_{\theta}(x)^{(i)}-y^{(i)}\right) * \frac{\partial}{\partial \theta_{j}}\left(\sum_{j=0}^{d} \theta_{j} x_{j}^{(i)}-y^{(i)}\right)\right) \\ &=\sum_{i=1}^{n}\left(f_{\theta}(x)^{(i)}-y^{(i)}\right) x_{j}^{(i)} \end{aligned}θJ(θ)=θj21i=1n(fθ(x)(i)y(i))2=221i=1n(fθ(x)(i)y(i))θj(fθ(x)(i)y(i))=i=1n(fθ(x)(i)y(i))θj(j=0dθjxj(i)y(i)))=i=1n(fθ(x)(i)y(i))xj(i)

梯度方程为:θj=θj+α∑i=1n(y(i)−fθ(x)(i))xj(i) \theta_j = \theta_j + \alpha\sum_{i=1}^{n}(y^{(i)}-f_\theta(x)^{(i)})x_j^{(i)} θj=θj+αi=1n(y(i)fθ(x)(i))xj(i)

2 代码实现

def dJ(theta, X_b, y):
    #损失函数倒数
    res = np.empty(len(theta))
    res[0] = np.sum(X_b.dot(theta) - y)
    for i in range(1, len(theta)):
        res[i] = (X_b.dot(theta) - y).dot(X_b[:,i])
    return res * 2 / len(X_b)
   
def gradient_descent(X_b, y, initial_theta, eta, n_iters = 1e4, epsilon=1e-8):
    #梯度下降法实现
    theta = initial_theta
    cur_iter = 0

    while cur_iter < n_iters:
        gradient = dJ(theta, X_b, y)
        last_theta = theta
        theta = theta - eta * gradient
        if(abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon):
            break
            
        cur_iter += 1

    return theta

测试结果:
在这里插入图片描述这个梯度下降还没封装到类里,就是只实现了个函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值