线性回归中,三种梯度下降MGD、BGD与MBGD对比研究(二)——Python轮子实现

在上一篇中,我们简单的说明了MGD、BGD与MBGD的原理,这一次,我们用numpy实现一下:

先导入需要的库:

import numpy as np
import pandas as pd
import random

此处插入一小段,来说明数据结构:
数据说明
可以简单的说:
X是没有标签的训练数据shape==(m, n)
y是训练数据的标签shape==(m, )
theta是线性回归的参数shape=(n,)


MGD训练线性回归:

def MGD_train(X, y, alpha=0.0001, maxIter=1000, arg_old=None):
    '''
    MGD训练线性回归
    传入:
        X        :  已知数据  
        y        :  标签
        alpha    :  学习率
        maxIter  :  总迭代次数
        arg_old  :  之前的参数,可以断点续训
    返回:
        theta : 权重参数
    '''
    # 初始化权重参数
    theta = np.ones(shape=(X.shape[1],))
    if not theta_old is None:
        # 假装是断点续训练
        theta = theta_old.copy()
    
    for i in range(maxIter):
        # 预测
        y_pred = np.sum(X * theta, axis=1)
        # 全部数据得到的梯度
        gradient = np.average((y - y_pred).reshape(-1, 1) * X, axis=0)
        # 更新学习率
        theta += alpha * gradient
    return theta

代码gradient = np.average((y - y_pred).reshape(-1, 1) * X, axis=0)用到了numpy的广播机制,老铁们好好想想(大佬忽略即可)。


SGD训练线性回归

def SGD_train(X, y, alpha=0.0001, maxIter=1000, theta_old=None):
    '''
    SGD训练线性回归
    传入:
        X       :  已知数据  
        y       :  标签
        alpha   :  学习率
        maxIter :  总迭代次数
        
    返回:
        theta : 权重参数
    '''
    # 初始化权重参数
    theta = np.ones(shape=(X.shape[1],))
    if not theta_old is None:
        # 假装是断点续训练
        theta = theta_old.copy()
    # 数据数量
    data_length = X.shape[0]
    for i in range(maxIter):
        # 随机选择一个数据
        index = np.random.randint(0, data_length)
        # 预测
        y_pred = np.sum(X[index, :] * theta)
        # 一条数据得到的梯度
        gradient = (y[index] - y_pred) * X[index, :]
        # 更新学习率
        theta += alpha * gradient
    return theta

MBGD训练线性回归

def MBGD_train(X, y, alpha=0.0001, maxIter=1000, batch_size=10, arg_old=None):
    '''
    MBGD训练线性回归
    传入:
        X          :  已知数据  
        y          :  标签
        alpha      :  学习率
        maxIter    :  总迭代次数
        batch_size :  没一轮喂入的数据数
        arg_old    :  之前的参数,可以断点续训
    返回:
        theta : 权重参数
    '''
    # 初始化权重参数
    theta = np.ones(shape=(X.shape[1],))
    
    if not theta_old is None:
        # 假装是断点续训练
        theta = theta_old.copy()
    
    # 所有数据的集合
    all_data = np.concatenate([X, y.reshape(-1, 1)], axis=1)
    for i in range(maxIter):
        # 从全部数据里选 batch_size 个 item
        X_batch_size = np.array(random.choices(all_data, k=batch_size))
        
        # 重新给 X, y 赋值
        X_new = X_batch_size[:, :-1]
        y_new = X_batch_size[:, -1]
        
        # 将数据喂入, 更新 theta, 直接调用 MGD_train 即可,你懂得
        theta = MGD_train(X_new, y_new, alpha=0.0001, maxIter=1, theta_old=theta)
    return theta

注:
X_new = X_batch_size[:, :-1]
y_new = X_batch_size[:, -1]
这两行代码,一个返回二维数组,另一个是一维向量


下一次,我们用鸢尾花数据集来尝试一下
https://blog.csdn.net/HaoZiHuang/article/details/104819026

发布了29 篇原创文章 · 获赞 8 · 访问量 2700

猜你喜欢

转载自blog.csdn.net/HaoZiHuang/article/details/104817087
今日推荐