在上一篇中,我们简单的说明了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