深度学习入门训练营test2--(Datawhale X 李宏毅苹果书 AI夏令营)

线性模型与时间序列预测:从基础到实践

在机器学习中,线性模型是一种简单且有效的工具,尤其适用于时间序列预测。本文将通过一个实际案例,探讨如何利用线性模型进行时间序列预测,并结合分段线性曲线、批量梯度下降等概念,深入分析模型优化的过程。

1. 线性模型概述

线性模型通过线性组合输入特征来预测输出值。作者通过一个实际案例,展示了如何使用简单的线性模型来预测2021年某段时间内的观看人次。这种模型基于前一天的观看人次来预测下一天的观看人次,其基本形式为:

线性模型简单易懂,但其假设输入特征与输出之间存在线性关系。在实际应用中,这种模型可能需要扩展以处理更复杂的数据模式。

这个简单模型得出的预测结果虽然有一定的准确性,但也存在明显的缺陷,比如在每周周期性波动的情况下,模型无法捕捉这种复杂的模式。图 1.6 中的蓝色线(模型预测值)和红色线(真实观看人次)几乎相差一天,表明模型仅仅是把前一天的数据简单平移,用以预测下一天的观看人次。

2. 分段线性曲线与模型优化

在处理时间序列数据时,简单的线性模型可能无法捕捉数据中的周期性或其他复杂模式。通过扩展模型为分段线性曲线,我们可以更好地捕捉这些特征。作者在观察到数据的周期性后,意识到观看人次每隔7天有一个循环——周五和周六的观看人数特别少,这种周期性对预测非常重要。如果只考虑前一天的数据,显然无法捕捉这种周期性变化。因此,作者提出了一个改进模型的方案,考虑前7天的观看数据,模型变为:

通过考虑更多天的数据,模型能够更好地捕捉到数据的周期性,从而在训练数据上表现出更低的损失。实际上,新的模型在训练数据上的损失减少到了380,而原来只考虑一天的模型损失是480。

以下是一个Python示例代码,展示如何实现这个改进的线性模型:

import numpy as np
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt

# 准备数据
def prepare_data(data, days=7):
    X = []
    y = []
    for i in range(len(data) - days):
        X.append(data[i:i + days])
        y.append(data[i + days])
    return np.array(X), np.array(y)

# 示例数据
data = np.random.randn(100)
X, y = prepare_data(data, days=7)

# 训练模型
model = LinearRegression()
model.fit(X, y)

# 预测
predictions = model.predict(X)

# 打印模型参数
print(f"偏置项 (b): {model.intercept_}")
print(f"权重 (w): {model.coef_}")

# 可视化预测结果
plt.figure(figsize=(12, 6))
plt.plot(range(len(data)), data, label='实际值', color='red')
plt.plot(range(7, len(predictions) + 7), predictions, label='预测值', color='blue')
plt.legend()
plt.xlabel('时间')
plt.ylabel('观看人次')
plt.title('线性模型预测结果')
plt.show()

扩展模型与局限性

随着对数据的深入理解,模型进一步扩展为考虑前28天,甚至56天的数据:

在这种扩展下,训练数据上的损失继续降低。然而,尽管模型在训练数据上的表现不断提升,在未见过的数据(测试集)上的误差没有进一步减少,仍维持在460左右。这表明,简单地增加历史数据的时间跨度未必会显著提升模型的泛化能力。

3. 批量梯度下降与参数更新

在深度学习中,批量梯度下降是优化算法的重要组成部分。它通过将数据集分成多个批量进行迭代更新,来提高训练效率并减少内存消耗。基本步骤包括:

  1. 将数据分成多个批量。
  2. 对每个批量计算损失函数和梯度。
  3. 更新模型参数。

以下是一个示例代码,展示如何实现批量梯度下降:

import numpy as np

def batch_gradient_descent(X, y, batch_size, learning_rate, epochs):
    m, n = X.shape
    weights = np.zeros(n)
    biases = 0
    num_batches = m // batch_size

    for epoch in range(epochs):
        for i in range(num_batches):
            start = i * batch_size
            end = (i + 1) * batch_size
            X_batch = X[start:end]
            y_batch = y[start:end]

            # 计算预测值
            y_pred = np.dot(X_batch, weights) + biases

            # 计算损失
            loss = np.mean((y_pred - y_batch) ** 2)

            # 计算梯度
            gradients = 2 * np.dot(X_batch.T, (y_pred - y_batch)) / batch_size
            bias_gradient = 2 * np.sum(y_pred - y_batch) / batch_size

            # 更新参数
            weights -= learning_rate * gradients
            biases -= learning_rate * bias_gradient

        print(f"Epoch {epoch + 1}/{epochs}, Loss: {loss}")

    return weights, biases

# 示例数据
X = np.random.randn(100, 7)
y = np.random.randn(100)

weights, biases = batch_gradient_descent(X, y, batch_size=10, learning_rate=0.01, epochs=20)

print(f"最终权重: {weights}")
print(f"最终偏置项: {biases}")

二、线性模型基础

1. 线性回归模型:

数学表达式:
线性回归的数学模型通常表示为:

其中,y是目标变量,X1,X2,…,Xn​ 是特征变量,β0,β1,…,βn是回归系数,ϵ 是误差项。 

几何解释:
线性回归可以理解为在高维空间中寻找一条超平面,使得样本点到超平面的距离最小化。

损失函数:
常用的损失函数是均方误差(MSE):

 

其中,yi是真实值,是预测值。 

 优化算法:
线性回归模型通常使用梯度下降法进行优化,以最小化损失函数。

2. 代码示例:
以下代码示例展示了如何使用Python的Scikit-Learn库实现线性回归模型:

from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# 假设数据已经准备完毕,X为特征矩阵,y为目标变量
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建线性回归模型
model = LinearRegression()

# 训练模型
model.fit(X_train, y_train)

# 进行预测
y_pred = model.predict(X_test)

# 计算均方误差
mse = mean_squared_error(y_test, y_pred)
print('Mean Squared Error:', mse)

三、分段线性模型与模型变形

1. 分段线性函数:

  • 引入概念:
    分段线性函数通过将数据集划分为多个区间,并在每个区间内拟合一个线性模型,来捕捉非线性关系。

  • 优势:
    通过多个线性模型的组合,分段线性函数可以有效拟合复杂的非线性数据,且保持模型的可解释性。

2. 模型变形:

  • 多项式回归:
    通过对特征进行多项式变换(如平方、立方),我们可以提高模型的非线性拟合能力。

  • 基函数:
    使用基函数(如径向基函数)可以构造出更复杂的非线性模型,从而捕捉数据中的复杂模式。

3. 代码示例:
以下代码示例展示了如何使用Python的Scikit-Learn库实现多项式回归:

from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline

# 创建多项式特征
poly = PolynomialFeatures(degree=2)
X_poly = poly.fit_transform(X)

# 创建线性回归模型
model = LinearRegression()

# 训练模型
model.fit(X_poly, y)

四、深度学习中的Sigmoid函数与模型优化

在深度学习中,Sigmoid 函数广泛用于构建非线性模型。通过调整 Sigmoid 函数的参数,可以逼近各种分段线性函数。本文将探讨如何通过调整 Sigmoid 函数的参数来优化模型,及如何最小化损失函数。

Sigmoid 函数的调整与应用

1. Sigmoid 函数的基本形式

Sigmoid 函数是一个S形曲线,常用于二分类任务中的激活函数。其标准形式为:


其输出范围在0到1之间,使得它非常适合作为神经网络中的激活函数。

作用:
Sigmoid函数在神经网络中起到激活作用,能够将线性输入转换为非线性输出,从而帮助模型捕捉数据中的复杂关系。

调整参数:

在实际应用中,我们通常使用带有调整参数的 Sigmoid 函数来拟合不同的模型。例如,一个可调的 Sigmoid 函数可以表示为:

通过调整 b、w 和 c,我们可以生成不同形状的 Sigmoid 函数,以适应不同的预测需求。这些 Sigmoid 函数可以组合在一起,逼近各种复杂的分段线性函数。

2. 多Sigmoid函数组合:

为了更准确地捕捉数据中的非线性关系,我们可以将多个 Sigmoid 函数组合在一起。例如,考虑前几天的观看人次数据,可以构造如下模型:

3.向量化表示

为了简化模型的表示,我们可以使用矩阵和向量的方式来表达上述模型。设 r 是每个 Sigmoid 函数的线性组合结果,模型可以写成:

4. 模型优化:

损失函数与优化目标

在实际应用中,我们需要通过优化算法来调整模型参数以最小化损失函数。损失函数度量了预测值与真实值之间的误差。给定一个包含多个参数的模型,损失函数可以表示为:

 其中 θ 是包含所有未知参数的向量。

梯度下降法:

梯度下降是一种优化算法,用于找到最小化损失函数的最佳参数值。基本步骤如下:

  • 随机初始化参数 θo。

  • 计算损失函数 L(θ)的梯度 g。

  • 更新参数

 其中 η是学习率,控制更新的步幅。

优化器:
如Adam优化器是一种广泛使用的优化算法,能够提高训练效率并避免陷入局部最优解。
批量处理与回合

为了提高效率,通常将数据分成若干批量(batch),每次更新参数时只使用一个批量的数据。一个回合(epoch)表示将所有数据分批处理一次。每次更新称为一次更新,因此一个回合内的更新次数取决于批量的大小。

例如:

  • 如果有 10,000 笔数据,每批大小为 10,那么一个回合内会进行 1,000 次更新。
  • 如果批量大小为 100,那么一个回合内会进行 100 次更新。
5. 代码示例:
以下代码示例展示了如何使用PyTorch实现一个简单的全连接神经网络:
import torch
import torch.nn as nn
import torch.optim as optim

# 定义神经网络模型
class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()
        self.fc1 = nn.Linear(10, 50)
        self.sigmoid = nn.Sigmoid()
        self.fc2 = nn.Linear(50, 1)
    
    def forward(self, x):
        x = self.sigmoid(self.fc1(x))
        x = self.fc2(x)
        return x

# 初始化模型、损失函数和优化器
model = SimpleNN()
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 假设数据已准备完毕
inputs = torch.randn(100, 10)
targets = torch.randn(100, 1)

# 训练模型
for epoch in range(1000):
    optimizer.zero_grad()
    outputs = model(inputs)
    loss = criterion(outputs, targets)
    loss.backward()
    optimizer.step()

五、机器学习框架 

在机器学习的过程中,模型的训练和测试是至关重要的步骤。以下是对这三个步骤的详细说明,并补充一些代码示例,以帮助理解和实践。

1. 模型函数的定义

在模型训练的第一步,我们需要定义一个函数 fθ​(x),其中θ代表模型中的所有未知参数。这个函数的目的是通过输入特征 x 来预测输出值 y。对于线性回归模型来说,函数通常表现为:fθ​(x)=θ0​+θ1​X1​+θ2​X2​+⋯+θn​Xn 这里 ​θ0是偏置项,θ1​,θ2​,…,θn 是模型的权重。

2. 定义损失函数

为了评估模型的预测效果,我们需要定义一个损失函数L(θ),它用来衡量模型预测结果与实际值之间的差距。常见的损失函数是均方误差(MSE),其公式为:L(θ)=​ 这里,N 是训练样本的数量, yi是实际值,fθ​(xi​)是预测值。

3. 优化问题的求解

接下来,我们需要解决一个优化问题,即找到使损失函数最小化的参数θ*:θ*=arg⁡ min⁡θL(θ) 通常,优化算法如梯度下降法用于迭代地调整 θ,以逐步减小损失值。

4. 模型的应用与测试

一旦找到最优参数θ*,我们就可以将其应用于测试数据集上。测试集的特征 xN+1​,xN+2​,…,xN+M​没有对应的目标值 y,模型会使用这些输入特征进行预测,并输出预测结果。

以下是一个简单的代码示例,使用Scikit-Learn库进行线性回归模型的训练和测试:

from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# 假设已经有数据集 X(特征)和 y(目标变量)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# 定义线性回归模型
model = LinearRegression()

# 训练模型
model.fit(X_train, y_train)

# 在测试集上进行预测
y_pred = model.predict(X_test)

# 计算并输出损失值(均方误差)
mse = mean_squared_error(y_test, y_pred)
print('Mean Squared Error:', mse)

在这个代码示例中,我们首先将数据集分为训练集和测试集,然后使用线性回归模型进行训练。训练完成后,我们在测试集上进行预测,并计算均方误差来评估模型的表现。

5. 结果应用与提交

一旦得到了预测结果,可以将这些结果保存并上传到像Kaggle这样的平台上进行评估。

通过上述步骤,我们可以完整地体验从模型定义、训练、优化到测试的过程。这种流程在实际机器学习项目中非常常见,也是理解模型训练和应用的重要基础。

总结

线性模型在时间序列预测中展示了其基础而重要的作用,但面对更复杂的特征时,可能需要通过模型变形和更复杂的优化技术来提升预测性能。利用批量梯度下降等优化方法,可以提高训练效率和模型性能。借助现代机器学习框架,我们可以更加高效地实现和优化模型,从而在实际应用中取得更好的效果。

  • 14
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值