多元线性回归梯度下降法

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
大数据开发治理平台 DataWorks,不限时长
简介: 梯度下降法是一种通用的优化算法,尤其适用于机器学习中找到最优解。与解析解法不同,它不局限于特定情况,能在数据规模较大时依然有效。该方法通过迭代逐步接近最优解,每次迭代利用损失函数的梯度信息调整参数。学习率是控制参数更新幅度的关键因素,太大会导致发散,太小则收敛慢。全量梯度下降每次使用所有样本更新,收敛稳定但速度慢;随机梯度下降每次仅用一个样本,速度快但可能产生较大波动;小批量梯度下降取两者之间,以一定的样本批量进行更新,兼顾速度和稳定性。

梯度下降法(Gradient Descent)是一个算法,但不同于解析解法一般局限,相反,他是一个非常通用的优化算法来帮助一些机器学习求出最优解。

 解析解可以成功的原因是MSE损失函数是凸函数,即Hessian矩阵半正定,但假使损失函数非凸,解析解就比较局限。而且解析解的运算较为复杂,时间复杂度达到 。所以解析解法在涉及数据较大时并不好用。

梯度下降法是一点点逼近最优解的方法

image.gif 编辑

梯度下降公式

这里梯度下降公式仅仅只是一个指导计算机迭代过程中如何去调整θ变化的式子,不需要推导和证明。其中 为学习率(learning rate)。学习率一般为正数。在最优解左侧,梯度小于0,学习率大于0,Wj递增,靠近最优解。同理,在最优解右侧,梯度大于0,学习率大于0,Wj递减,同样会靠近最优解。

学习率设置

image.gif 编辑

如上图所示,小学习率比较稳定,但是迭代次数会比较大,如果遇到鞍面会停留很长时间。

适中的学习率迭代次数更少而且可以跳出局部最优解去寻找更好的解,但是可能会出现达不到最优解的情况。大学习率会发散,损失函数会越来越大。这种是不可取的学习率。最后是最优学习率(一般不考虑),即一步直接到最优解。

image.gif 编辑

我们可以设置学习率随着迭代次数减小,这样既可以跳出局部最优解,同时也保证可以收敛到最优解。这个过程我们称为学习速率调整(又称学习速率调度):一般使用某种事先设定好的策略或者在每次迭代中衰减一个减小的阈值。

梯度下降的流程(附代码)

Step 1. 随机θ参数

我们先创建一组随机的θ参数作为起始点

import numpy as np
theta = np.random.randn(2,1)#创建一组服从正态分布的参数

image.gif

这里,我们创建一个两行一列的参数矩阵。

Step 2. 求解梯度

简而言之,假设X(mxn),W(nx1)某个维度j的梯度gradient(j) = ε(mx1)乘上X的第j列,这显然不符合矩阵相乘,所以真实情况是需要将Xj转置。

import numpy as np
gradients = X_b.T.dot((X_b.dot(theta) - y))

image.gif

Step 3. 调整θ参数

判断收敛时使用g= 0并不合理,因为当损失函数时非凸函数的话,g = 0只是一个驻点,还可能是最大值,这不能说明什么。其实判断loss下降收益更加合理,当收益不再变化就可以认为达到局部最优解。即

theta = theta - learning_rate * gradients

image.gif

梯度下降的分类

区别:三种梯度下降的区别仅在于第二步求解梯度所用到的X数据集的样本数量不同,每次学习(更新模型参数)使用的样本数目,每次使用不同的样本会导致每次学习的准确性和学习时间不同。

全量梯度下降(Batch Gradient Descent)

在全量梯度下降中,对于θ的更新,所有样本都有贡献,也就是参与调整θ。其计算得到的是一个标准梯度。因而理论上来说一次更新的幅度是比较大的。如果样本不多的情况下,这样的收敛速度会更快,优点在于每次更新都会朝着正确的方向进行,最终收敛于极值点,缺点就是时间比较长。

import numpy as np
#全量梯度下降
X = np.random.rand(100,1)
y = 4+3*X + np.random.randn(100,1)
X_b = np.c_[np.ones((100,1)),X]
#创建超参数
n_iterations = 10000
t0,t1 = 5, 500
#定义一个函数来动态调整学习率
def learning_rate_schedule(t):
    return t0/(t+t1)
#初始化theta
theta = np.random.randn(2,1)
truth =np.array([[4],[3]])
#判断是否收敛,一般不设置阈值,而是采用相对大的迭代次数保证收敛
for i in range(n_iterations):
    # 求梯度,计算gradient
    gradients = X_b.T.dot((X_b.dot(theta) - y))  # 一个含有g0和g1的列向量
    # 应用梯度下降法的公式去调整theta值
    learning_rate = learning_rate_schedule(i)
    theta = theta - learning_rate * gradients
print(theta)
print("Error(%):")
print("W0=",((abs(theta-truth)[0,:]/abs(truth)[0,:])*100)[0],"%")
print("W1=",((abs(theta-truth)[1,:]/abs(truth)[1,:])*100)[0],"%")

image.gif

image.gif

随机梯度下降(Stochastic Gradient Descent)

梯度下降算法每次从训练集中随机选择一个样本来进行学习

优点:学习非常迅速,可能会选择更好的局部最优解。

缺点:每次更新可能并不会按照正确方向进行,因此带来优化波动,迭代次数增加。

import numpy as np
X = np.random.rand(100,1)
y = 4 + 3*X + np.random.randn(100,1)
X_b = np.c_[np.ones((100,1)),X]
n_epochs = 10000
m = 100
truth =np.array([[4],[3]])
t0,t1 = 5, 500
def learning_rate_schedule(t):
    return t0/(t+t1)
theta = np.random.randn(2,1)
for epoch in range(n_epochs):
    #每个轮次开始前打乱顺序
    arr = np.arange(len(X_b))
    np.random.shuffle(arr)
    X_b = X_b[arr]
    y = y[arr]
    for i in range(m):
        xi = X_b[i:i+1]#左闭右开
        yi = y[i:i+1]
        gradients = xi.T.dot((xi.dot(theta) - yi))
        learning_rate = learning_rate_schedule(epoch*m + i)
        theta = theta - learning_rate*gradients
print(theta)
print("Error(%):")
print("W0=",((abs(theta-truth)[0,:]/abs(truth)[0,:])*100)[0],"%")
print("W1=",((abs(theta-truth)[1,:]/abs(truth)[1,:])*100)[0],"%")

image.gif

image.gif 编辑

小批量梯度下降(Mini-Batch Gradient Descent)

Mini-Batch梯度下降综合了batch梯度下降与stochastic梯度下降,在每次更新速度与更新次数中间取得一个平衡,其每次更新从训练集中随机选择batch-size个样本进行学习,使得学习更加稳定。

import numpy as np
X = 2*np.random.rand(100,1)
y = 4+3*X + np.random.randn(100,1)
X_b = np.c_[np.ones((100,1)),X]
learning_rate = 0.0001
n_epochs = 10000
m = 100
batch_size = 10
num_batches = int(m/batch_size)
theta = np.random.randn(2,1)
truth =np.array([[4],[3]])
for epoch in range(n_epochs):
    arr = np.arange(len(X_b))
    np.random.shuffle(arr)
    X_b = X_b[arr]
    y = y[arr]
    for i in range(num_batches):
        selected_index = np.random.randint(m)
        x_batch = X_b[i:i+batch_size]
        y_batch = y[i:i+batch_size]
        gradients = x_batch.T.dot((x_batch.dot(theta) - y_batch))
        theta = theta - learning_rate * gradients
print(theta)
print("Error(%):")
print("W0=",((abs(theta-truth)[0,:]/abs(truth)[0,:])*100)[0],"%")
print("W1=",((abs(theta-truth)[1,:]/abs(truth)[1,:])*100)[0],"%")

image.gif

image.gif 编辑

目录
相关文章
|
7月前
MATALB运用——最小二乘法拟合
MATALB运用——最小二乘法拟合
104 0
|
机器学习/深度学习 数据可视化 Python
逻辑回归那些事—使用牛顿法解决实际问题
逻辑回归是机器学习中的重要章节,本文将带你从公式推导到算法实现详细讲述这部分内容,想学习这个高大上的技能么,快来看吧!!!
5439 0
|
1月前
R语言多项式线性模型:最大似然估计二次曲线
R语言多项式线性模型:最大似然估计二次曲线
|
1月前
|
算法 Python
梯度下降法
梯度下降法
32 0
曲线拟合-最小二乘法
线性最小二乘法及matlab例程
|
机器学习/深度学习 Web App开发 算法
四、多元线性回归
四、多元线性回归
四、多元线性回归
R 多元线性回归
R 多元线性回归
148 0
R 多元线性回归
|
人工智能 BI
最小二乘法-公式推导
基本思想 求出这样一些未知参数使得样本点和拟合线的总误差(距离)最小 最直观的感受如下图(图引用自知乎某作者) 而这个误差(距离)可以直接相减,但是直接相减会有正有负,相互抵消了,所以就用差的平方 推导过程 1 写出拟合方程y=a+bxy=a+bx 2 现有样本(x1,y1),(x2,y2).
3954 1