机器学习:一元线性回归(梯度下降法)

目录

一、理论知识

1、一元线性回归模型(映射函数)

2、损失函数(代价函数)

3、梯度计算

4、梯度下降

二、代码实现

1、导入Python包

2、利用sklearn构造线性回归数据集

3、定义并初始化权重参数 W 和 b

4、前向传播函数:计算映射函数

5、损失计算函数

6、反向传播函数:梯度下降

7、数据预处理:特征归一化 + 调整维度

8、划分训练集和测试集

9、模型训练

10、模型测试


一、理论知识

1、一元线性回归模型(映射函数)

\hat{Y} = XW+b

其中,X \in \mathbb{R}^{N \times 1}表示输入,\hat{Y} \in \mathbb{R}^{N \times 1}表示输出,W \in \mathbb{R}^{1 \times 1}b \in \mathbb{R}^{1 \times 1}表示可学习的权重参数。

2、损失函数(代价函数)

L = \frac{1}{2N}(\hat{Y} - Y)^2 = \frac{1}{2N}[(XW+b) - Y]^2

其中,Y是标签,\hat{Y}是预测值。

3、梯度计算

\frac{\partial L}{\partial W} = \frac{1}{N} \cdot X^T(\hat{Y}-Y)

\frac{\partial L}{\partial b} = \frac{1}{N} \cdot (\hat{Y}-Y)

注:梯度计算遵循的是矩阵求导法则和链式求导法则。

4、梯度下降

W_{new} = W_{old} - \alpha \cdot \frac{\partial L}{\partial W}

b_{new} = b_{old} - \alpha \cdot \frac{\partial L}{\partial b}

其中,A是梯度下降步长,又称学习率。多次迭代执行前向传播(计算映射函数)和反向传播(梯度计算+梯度下降),损失函数最终收敛至局部最优解。

二、代码实现

1、导入Python包

import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.datasets import make_regression

plt.rcParams['font.sans-serif'] = ['Times New Roman']

2、利用sklearn构造线性回归数据集

X, Y = make_regression(n_samples=100, n_features=1, noise=50, random_state=2024)

plt.figure(dpi=100)
plt.scatter(X, Y)

3、定义并初始化权重参数 W 和 b

weights = np.zeros((1, 1))
bias = 0

4、前向传播函数:计算映射函数

def forward(X, weights, bias):
    Y_hat = np.dot(X, weights) + bias
    return Y_hat

5、损失计算函数

def Loss_fuction(Y, Y_hat):
    N = Y.shape[0]
    cost = 1 / (2 * N) * np.sum((Y_hat - Y) ** 2)
    return cost

6、反向传播函数:梯度下降

def backward(X, Y, Y_hat, weights, bias, lr):
    # 梯度计算
    N = Y.shape[0]
    dw = 1 / N * np.dot(X.T, (Y_hat - Y))
    db = 1 / N * np.sum(Y_hat - Y)

    # 权重更新
    weights -= lr * dw
    bias -= lr * db
    return weights, bias

7、数据预处理:特征归一化 + 调整维度

X = (X - np.mean(X, axis=0, keepdims=True)) / (np.std(X, axis=0, keepdims=True) + 1e-8)
Y = Y[:, None]

8、划分训练集和测试集

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=2024)
print(X_train.shape, X_test.shape, Y_train.shape, Y_test.shape)

(80, 1) (20, 1) (80, 1) (20, 1)

9、模型训练

lr = 0.01 # 学习率
epochs = 1000  # 迭代次数
train_loss = []
for _ in range(epochs):
    # 前向传播
    Y_hat = forward(X_train, weights, bias)

    # 损失计算
    loss = Loss_fuction(Y_train, Y_hat)
    train_loss.append(loss)

    # 反向传播
    weights, bias = backward(X_train, Y_train, Y_hat, weights, bias, lr)

plt.figure(dpi=100)
plt.plot(train_loss)
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.title("Training Loss")
plt.show()

10、模型测试

plt.figure(dpi=100)
plt.scatter(X_test[:,0], Y_test[:,0], label='test data')
lin_x = np.linspace(np.min(X_test[:,0]), np.max(X_test[:,0]), 100)
lin_y = forward(lin_x[:,None], weights, bias)[:,0]
plt.plot(lin_x, lin_y, 'r', label='predict')
plt.legend()
plt.xlabel('X_test')
plt.ylabel('Y_test')
plt.show()

y_predict = forward(X_test, weights, bias)
print(f"Test MSE: {mean_squared_error(y_predict, Y_test)}")

Test MSE: 3130.9712952593727 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值