LSTM模型改进实现多步预测未来30天销售额

项目源码获取方式见文章末尾! 600多个深度学习项目资料,快来加入社群一起学习吧。

《------往期经典推荐------》

项目名称
1.【BiLSTM模型实现电力数据预测】
2.【卫星图像道路检测DeepLabV3Plus模型】
3.【GAN模型实现二次元头像生成】
4.【CNN模型实现mnist手写数字识别】
5.【fasterRCNN模型实现飞机类目标检测】
6.【CNN-LSTM住宅用电量预测】
7.【VGG16模型实现新冠肺炎图片多分类】
8.【AlexNet模型实现鸟类识别】
9.【DIN模型实现推荐算法】
10.【FiBiNET模型实现推荐算法】
11.【钢板表面缺陷检测基于HRNET模型】

关于深度实战社区

我们是一个深度学习领域的独立工作室。团队成员有:中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等,曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万+粉丝,拥有2篇国家级人工智能发明专利。

社区特色:深度实战算法创新

获取全部完整项目数据集、代码、视频教程,请进入官网:zzgcz.com。竞赛/论文/毕设项目辅导答疑,v:zzgcz_com


1. 项目简介

本项目旨在利用深度学习中的长短期记忆网络(LSTM)来预测未来30天的销售额。

递归预测(Recursive Forecasting)和多步预测(Direct Multi-Step Forecasting)

方法优点缺点
递归预测简单易实现;资源消耗较低;适应性强误差累积;依赖性高;难以捕捉长期依赖关系
直接多步预测避免误差累积;更好地捕捉多步间依赖关系;灵活性高;提高预测效率模型复杂度增加;训练难度较大;难以扩展到长预测步数;需要更多的标注数据

递归预测是一种逐步预测方法,利用模型对一个时间步的预测结果作为下一个时间步的输入,递归地生成多个未来时间步的预测值。具体步骤如下:

  1. 使用历史数据预测第一个未来时间步。
  2. 将预测的值添加到输入序列中,移除最早的一个时间步。
  3. 使用更新后的输入序列预测下一个时间步。
  4. 重复上述过程,直到预测所需的所有未来时间步。

优点

  1. 简单易实现:

    1. 实现过程直接,不需要对模型结构进行复杂修改。
    2. 适用于大多数现有的单步预测模型,如LSTM、ARIMA等。
  2. 资源消耗较低:

    1. 只需训练一个模型来预测单个时间步,因此训练和存储需求较低。
  3. 适应性强:

    1. 可以应用于不同类型的时间序列数据,无需对数据进行特殊处理。

缺点

  1. 误差累积(Error Accumulation):

    1. 每一步的预测误差都会传递到下一个预测步骤,导致后续预测的误差可能显著增加。
    2. 尤其在长时间步预测时,累积误差可能使预测结果不可靠。
  2. 依赖性高:

    1. 后续预测依赖于之前所有的预测结果,任何一个步骤的错误都会影响整体预测性能。
  3. 难以捕捉长期依赖关系:

    1. 对于需要考虑长时间跨度依赖关系的序列,递归预测可能无法充分利用这些信息。

直接多步预测是一种同时预测多个未来时间步的方法。具体来说,模型直接输出多个未来时间步的预测值,而不是逐步预测。常见的实现方式包括:

  • 独立模型方法(Independent Models): 为每个未来时间步训练一个独立的模型。
  • 联合模型方法(Joint Models): 使用一个模型同时输出多个未来时间步的预测值。

优点

  1. 避免误差累积:

    1. 由于模型直接输出多个时间步的预测值,单步预测的误差不会传递到后续步骤,减少了误差累积的问题。
  2. 更好地捕捉多步间的依赖关系:

    1. 模型可以学习多个未来时间步之间的相互关系,提高预测的整体一致性和准确性。
  3. 灵活性高:

    1. 可以根据需求调整预测的时间步长度,而不受递归预测的限制。
  4. 提高预测效率:

    1. 通过一次性预测多个时间步,可以减少计算资源的消耗,尤其是在需要大规模预测时。

缺点

  1. 模型复杂度增加:

    1. 需要设计和训练能够输出多个时间步的复杂模型,可能需要更多的训练数据和计算资源。
  2. 训练难度较大:

    1. 由于需要同时预测多个时间步,模型在训练过程中可能面临更复杂的优化问题,导致训练不稳定或收敛速度较慢。
  3. 难以扩展到非常长的预测步数:

    1. 随着预测步数的增加,模型的输出维度也会增加,可能导致模型性能下降或过拟合。
  4. 需要更多的标注数据:

    1. 直接预测多个时间步需要更多的训练样本,以确保模型能够学习到有效的多步依赖关系。
  5. 选择合适的方法的建议

选择递归预测还是直接多步预测,取决于具体的应用场景和数据特性。以下是一些建议:

  1. 预测步数较短:

    1. 如果只需要预测未来几个时间步,递归预测通常足够且简单。
  2. 预测步数较长:

    1. 对于需要预测较长时间步的情况,直接多步预测可能更合适,能够减少误差累积的问题。
  3. 数据特性:

    1. 如果时间序列具有强烈的多步依赖关系,直接多步预测能够更好地捕捉这些依赖。
    2. 如果数据波动较大,递归预测可能更容易受到误差的影响。
  4. 计算资源:

    1. 递归预测通常计算资源消耗较低,适合资源有限的情况。
    2. 直接多步预测需要更高的计算资源和更多的训练数据,但在资源充足时能够提供更好的预测性能。
  5. 模型复杂度与训练时间:

    1. 如果模型训练时间和复杂度是限制因素,递归预测更具优势。
    2. 如果可以接受更长的训练时间和更高的模型复杂度,直接多步预测可能带来更好的结果。

2.模型核心改进点

  1. 数据预处理中的数据泄漏问题

问题描述

在代码中,使用 MinMaxScaler 对整个数据集(包括训练集和测试集)进行了拟合(fit)和转换(transform):

特征缩放
scaler = MinMaxScaler()
scaled_features = scaler.fit_transform(data)
scaled_data = pd.DataFrame(scaled_features, columns=features + [target])

这种做法会导致数据泄漏(Data Leakage) ,即测试集的信息被泄露到训练集中,从而在模型评估时高估模型的性能。

数据泄漏(Data Leakage)是什么?

数据泄漏是指在模型训练过程中,未经意间将测试集(或未来的信息)引入训练过程,使得模型在评估时表现出不真实的高性能。这种情况会导致模型在实际应用中表现不佳,因为模型在训练时已经“见过”测试集的信息。

为什么会发生数据泄漏?

在时间序列预测中,数据具有时间依赖性,训练集和测试集应保持时间上的先后顺序。通过在整个数据集上进行拟合 MinMaxScaler,您实际上是在训练阶段使用了测试集的信息,具体表现为:

  1. 统计信息共享: MinMaxScaler 在拟合时计算整个数据集的最小值和最大值。这意味着测试集的最小值和最大值也被用于训练集的缩放。
  2. 特征分布影响: 测试集的特征分布信息被传递到了训练集中,使得模型在训练时已经部分“了解”测试集的分布。

数据泄漏带来的影响

  1. 性能高估: 模型在训练时已经获得了测试集的一部分信息,导致在测试集上的表现被高估。
  2. 泛化能力差: 由于模型在训练时依赖于测试集的信息,实际应用中面对新的、未见过的数据时,模型的表现可能远不如预期。
  3. 不可靠的评估指标: 评估指标(如MSE、MAE等)可能反映出不真实的模型性能,误导模型选择和优化过程。

如何避免数据泄漏

要避免数据泄漏,尤其是在数据预处理阶段,关键是在数据划分(训练集和测试集)之后,再进行任何数据转换操作。具体步骤如下:

  1. 数据划分: 首先,将数据集划分为训练集和测试集,确保训练集仅包含用于模型训练的数据,测试集仅用于模型评估。
  2. 拟合Scaler: 仅在训练集上拟合(fit)缩放器。
  3. 转换数据: 使用在训练集上拟合的缩放器,分别转换训练集和测试集。
2、处理缺失值的方法可能引入未来信息

在代码中,添加了 last_week_sale 特征后,使用了 后向填充(Backfill) 方法来处理缺失值:

添加上周销售额特征
df['last_week_sale'] = df['sale'].shift(7)处理缺失值
df.fillna(method='bfill', inplace=True)  使用后向填充方法填补缺失值

问题在于,使用后向填充方法可能会导致 数据泄漏(Data Leakage) ,即利用未来的信息来填补过去的缺失值。这会导致模型在训练时“看到了”未来的数据,从而高估模型的性能,并在实际应用中表现不佳。

为什么使用后向填充会引入未来信息?

在时间序列数据中,处理缺失值时,填补缺失值的方法需要谨慎选择,以避免利用未来的信息。具体到您的代码:

last_week_sale 特征的创建:

df['last_week_sale'] = df['sale'].shift(7)

这意味着,每一天的 last_week_sale 是七天前的销售额。周期性模式捕捉: 在许多业务场景中,销售额具有明显的周期性,特别是基于星期的周期。例如,周末的销售额可能高于工作日。通过创建7天的滞后特征,模型可以学习到这种每周的周期性模式。因此,前七天的数据在创建 last_week_sale 时会产生缺失值(因为没有七天前的数据)。

使用后向填充(Backfill):

df.fillna(method='bfill', inplace=True)

后向填充会用后面的非缺失值来填补缺失值。例如,假设第1天到第7天的 last_week_sale 是缺失的,后向填充会用第8天到第14天的 last_week_sale 来填补第1天到第7天的缺失值。

问题在于,填补第1天到第7天的 last_week_sale 使用了第8天到第14天的销售额,这相当于用未来的信息来填补过去的缺失值,导致数据泄漏。

为了避免数据泄漏,尤其是在处理时间序列数据时,需遵循以下原则:

  1. 选择合适的填补缺失值方法: 在时间序列中,通常使用 前向填充(Forward Fill)插值(Interpolation) 来填补缺失值,以避免引入未来信息。
3、LSTM模型输出维度与损失函数的匹配问题

在代码中,LSTM模型的输出维度设置为 FORECAST_STEPS(30),即一次性预测未来30天的销售额。然而,PyTorch中的 nn.MSELoss 默认计算每个元素的均方误差(Mean Squared Error, MSE),这可能未能充分利用时间序列的结构信息,影响模型的预测性能和效果。

定义模型参数
input_size = len(features)
hidden_size = 64
num_layers = 2
output_size = FORECAST_STEPS  输出维度设为30
dropout = 0.2初始化模型
model = LSTMModel(input_size, hidden_size, num_layers, output_size, dropout).to(device)定义损失函数和优化器
criterion = nn.MSELoss()
learning_rate = 0.001
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
  1. LSTM模型的输出维度设置
  • output_size = FORECAST_STEPS (30) :这意味着模型的最终输出层是一个线性层,将LSTM的隐藏状态映射到30个输出值,代表未来30天的销售额预测。

self.fc = nn.Linear(hidden_size, output_size)

  • forward 方法中的输出

    • LSTM层的输出形状为 (batch_size, seq_length, hidden_size)
    • 通过 out[:, -1, :] 取最后一个时间步的隐藏状态,得到形状为 (batch_size, hidden_size)
    • 通过全连接层,输出形状变为 (batch_size, output_size),即 (batch_size, 30)

2. nn.MSELoss 的工作机制

  • 默认行为nn.MSELoss 计算预测值和目标值之间每个元素的均方误差,并对所有元素取平均。
  • 形状匹配:在您的设置中,预测值和目标值的形状都是 (batch_size, 30),因此 nn.MSELoss 会逐元素计算误差并求平均。
  1. 潜在的问题
  • 未充分利用时间序列结构

    • nn.MSELoss 只是简单地计算每个预测值与实际值的误差,并对所有预测步数进行平均。这种方式忽略了不同时间步之间的依赖关系和序列结构。
    • 时间序列数据具有明显的时序依赖性,未来的销售额往往依赖于过去的销售模式,而不仅仅是单独的预测值。
  • 预测步数之间的相互依赖性未被利用

    • 直接预测30个时间步意味着模型在一次性输出所有预测值,但 nn.MSELoss 无法捕捉这些预测值之间的相互关系。
    • 例如,某一天的销售额可能会影响接下来几天的销售额,这种依赖关系在损失函数中没有得到体现。
  • 权重分配不均

    • 所有预测步数在损失计算中被平等对待,未考虑某些时间步对整体预测的重要性。例如,近期的预测可能比远期的预测更重要,但 nn.MSELoss 无法反映这一点。

为了解决上述问题,可以考虑以下几种方法,以确保损失函数和模型输出更好地匹配时间序列的特性。

使用自定义损失函数

设计一个能够捕捉时间步之间依赖关系的损失函数。例如,可以为不同的预测步数赋予不同的权重,或引入时间步之间的平滑性约束。加权MSELoss

序列到序列(Seq2Seq)模型

使用编码器-解码器结构的模型,可以更好地捕捉序列间的依赖关系。这种结构允许模型在生成每个时间步的预测时,参考整个输入序列的上下文。

在这里插入图片描述

3. 数据集与预处理

本项目所使用的数据集来自某商品的历史销售记录,包含多个特征字段,例如销售日期、销售额、温度等外部因素。数据集中最为核心的目标变量是商品的每日销售额,辅助特征包括温度和日期相关的周数信息。通过这些特征,项目能够分析和捕捉销售额的周期性趋势以及受到外部因素影响的波动性。

  1. 在数据预处理环节,首先对数据集进行了日期格式的标准化,将日期列转换为datetime格式,并按照时间顺序对数据进行了排序,确保后续模型能够捕捉到时间序列的顺序关系。此外,添加了周数作为新的特征,帮助模型捕捉到销售额的季节性和周期性模式。项目还引入了“上一周销售额”这一特征,使得模型在预测时能够参考历史数据,增加了时间序列的上下文信息。
  2. 为了处理缺失值,项目采用了向前填充的方式(bfill),确保特征值的完整性,避免数据不完整导致的模型训练问题。接下来,对选定的特征(如温度、周数、上一周销售额)进行了归一化处理。归一化使用了MinMaxScaler方法,将所有特征值缩放至0到1之间,确保特征的数值范围相近,从而避免某些特征因数值较大而对模型产生过度影响。
  3. 项目还对时间序列数据进行了序列化处理,通过自定义函数将原始数据转换为适合LSTM模型的序列输入形式。每个输入序列包含过去30天的特征值,而对应的目标是预测未来30天的销售额。这种序列化处理不仅保留了原始时间序列的顺序信息,还为模型提供了充足的上下文。

4. 模型架构

本项目采用的是长短期记忆网络(LSTM)来进行未来30天销售额的预测。LSTM是一种能够捕捉时间序列中长期依赖关系的循环神经网络(RNN)变种,能够有效解决序列数据中的梯度消失问题。项目中的LSTM模型由以下几部分组成:

LSTM层

LSTM的核心是其记忆单元和门机制,通过这些机制,它能够决定在每个时间步保留、更新或丢弃哪些信息。

输入门(Input Gate):决定当前时间步的输入对记忆状态的影响。其数学公式为:

i t = σ ( W i ⋅ [ h t − 1 , x t ] + b i ) i_t = \sigma(W_i \cdot [h_{t-1}, x_t] + b_i) it=σ(Wi[ht1,xt]+bi)

其中,it表示输入门的输出,σ是sigmoid激活函数,Wi 和 bi 是输入门的权重和偏置,ht−1 是前一个时间步的隐藏状态,xt 是当前时间步的输入。

遗忘门(Forget Gate):决定从记忆单元中遗忘多少信息,公式为:

f t = σ ( W f ⋅ [ h t − 1 , x t ] + b f ) f_t = \sigma(W_f \cdot [h_{t-1}, x_t] + b_f) ft=σ(Wf[ht1,xt]+bf)

其中,ft表示遗忘门的输出,Wf 和 bf 是遗忘门的权重和偏置。

候选记忆单元(Cell Candidate):生成候选记忆状态,用于更新当前的记忆单元,公式为:

C ~ t = tanh ⁡ ( W C ⋅ [ h t − 1 , x t ] + b C ) \tilde{C}_t = \tanh(W_C \cdot [h_{t-1}, x_t] + b_C) C~t=tanh(WC[ht1,xt]+bC)

其中,C~t 是候选的记忆单元状态,tanh 是双曲正切激活函数。

输出门(Output Gate):控制记忆状态如何影响输出,公式为:

o t = σ ( W o ⋅ [ h t − 1 , x t ] + b o ) o_t = \sigma(W_o \cdot [h_{t-1}, x_t] + b_o) ot=σ(Wo[ht1,xt]+bo)

记忆单元更新(Cell State Update):通过遗忘门和输入门来更新记忆单元,公式为:

C t = f t ∗ C t − 1 + i t ∗ C ~ t C_t = f_t * C_{t-1} + i_t * \tilde{C}_t Ct=ftCt1+itC~t

隐藏状态更新(Hidden State Update):通过输出门和当前的记忆单元状态来更新隐藏状态,公式为:

h t = o t ∗ tanh ⁡ ( C t ) h_t = o_t * \tanh(C_t) ht=ottanh(Ct)

LSTM前向传播公式

h t , C t = LSTM ( x t , h t − 1 , C t − 1 ) h_t, C_t = \text{LSTM}(x_t, h_{t-1}, C_{t-1}) ht,Ct=LSTM(xt,ht1,Ct1)

全连接层

LSTM的输出通过全连接层(fully connected layer)进行映射,得到最终的预测值。全连接层的公式为:

y = W f c ⋅ h t + b f c y = W_{fc} \cdot h_t + b_{fc} y=Wfcht+bfc

其中,Wfc 和 bfc 分别是全连接层的权重和偏置,ht 是LSTM输出的隐藏状态。

Dropout层

为了防止过拟合,模型中还使用了Dropout层,在训练过程中随机屏蔽掉部分神经元,Dropout的公式为:

h ′ = Dropout ( h , p ) h' = \text{Dropout}(h, p) h=Dropout(h,p)

其中,p 是保留的神经元概率。

模型的整体训练流程

数据加载与处理:首先将时间序列数据按30天作为一个输入序列,构建训练和测试集。每个输入序列对应未来30天的销售额预测。

模型训练:在训练阶段,模型使用均方误差(MSE)作为损失函数。MSE的公式为:

MSE = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 \text{MSE} = \frac{1}{n} \sum_{i=1}^{n}(y_i - \hat{y}_i)^2 MSE=n1i=1n(yiy^i)2

其中,yi是实际值,y^i是模型预测值,n 是样本数量。优化器选择Adam算法,基于反向传播更新模型参数。

评估指标:在评估阶段,除了MSE外,还使用了平均绝对误差(MAE)作为评估指标。MAE的公式为:

MAE = 1 n ∑ i = 1 n ∣ y i − y ^ i ∣ \text{MAE} = \frac{1}{n} \sum_{i=1}^{n} |y_i - \hat{y}_i| MAE=n1i=1nyiy^i

评估过程中,测试集的预测结果通过这些指标进行比较,最后输出模型的误差情况。

可视化与结果分析:训练完成后,模型的损失曲线和预测结果通过图表进行可视化,便于直观了解模型的收敛情况以及预测性能。

5. 核心代码详细讲解

1. 数据预处理与特征工程
df = pd.read_csv('smoothed_ES_sku023.csv')

解释: 读取销售数据的CSV文件。这里使用的是pandas库的read_csv函数,将原始数据加载为DataFrame格式。

df['date'] = pd.to_datetime(df['date'], format='%Y/%m/%d')

解释: 将date列转换为datetime格式,方便后续的时间序列操作和按日期排序。

df = df.sort_values('date')
df.reset_index(drop=True, inplace=True)

解释: 对数据集按日期升序排序,确保时间序列的顺序一致。同时重置索引,删除旧索引并更新为新顺序。

df['week_number'] = df['date'].dt.isocalendar().week

解释: 提取每条数据所属的周数,并将其作为新的特征添加到数据集中,捕捉销售额的周期性特征。

df['last_week_sale'] = df['sale'].shift(7)

解释: 创建“上一周销售额”这一特征,用于捕捉前一周销售额对当前销售额的影响。shift(7)表示将销售额向前平移7天。

df.fillna(method='bfill', inplace=True)

解释: 处理缺失值。这里使用向后填充的方法(backward fill),用之后的有效值填补缺失数据,确保数据的完整性。

features = ['temperature', 'week_number', 'last_week_sale']
target = 'sale'

解释: 定义模型的特征列和目标变量。其中,特征列包含温度、周数和上一周的销售额,目标变量为每日的销售额。

scaler = MinMaxScaler()
scaled_features = scaler.fit_transform(data)

解释: 使用MinMaxScaler将特征和目标变量缩放到0到1之间的范围。这样做可以避免不同特征数值范围差异太大,防止某些特征对模型的影响过大。

2. 创建多步序列数据
def create_sequences(data, seq_length, forecast_steps, feature_cols, target_col):xs = []ys = []for i in range(len(data) - seq_length - forecast_steps + 1):x = data.iloc[i:i + seq_length][feature_cols].valuesy = data.iloc[i + seq_length:i + seq_length + forecast_steps][target_col].valuesxs.append(x)ys.append(y)return np.array(xs), np.array(ys)
  • 解释: 这是创建多步序列数据的核心函数。它通过滑动窗口的方式将输入数据分割成固定长度的序列,用于训练LSTM模型。

    • data: 输入的已预处理数据。
    • seq_length: 输入序列的长度,这里为过去30天。
    • forecast_steps: 预测步长,这里为未来30天。
    • feature_cols: 使用的特征列。
    • target_col: 目标列。
    • 函数返回两个数组:xs为输入特征序列,ys为对应的目标序列。
X, y = create_sequences(scaled_data, SEQ_LENGTH, FORECAST_STEPS, features, target)
  • 解释: 使用上面的create_sequences函数生成训练和测试数据,X是特征序列,y是目标值序列。
3. 模型架构构建
class LSTMModel(nn.Module):def init(self, input_size, hidden_size, num_layers, output_size, dropout=0.2):super(LSTMModel, self).
__init__
()self.hidden_size = hidden_sizeself.num_layers = num_layersself.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True, dropout=dropout)self.fc = nn.Linear(hidden_size, output_size)
  • 解释: 这是模型的构建部分,定义了LSTM模型的结构。

    • input_size: 输入特征的数量。
    • hidden_size: LSTM层的隐藏单元数量,决定了每层输出的维度。
    • num_layers: LSTM层的数量,这里使用了2层。
    • dropout: Dropout的比例,用于防止过拟合。
    • lstm: 定义了一个LSTM层,带有batch_first=True,即输入的batch维度为第一维。
    • fc: 全连接层,将LSTM的输出映射到最终的预测值(未来30天的销售额)。
def forward(self, x):h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)out, _ = self.lstm(x, (h0, c0))out = out[:, -1, :]out = self.fc(out)return out
  • 解释: 前向传播函数。初始化LSTM的隐藏状态和细胞状态为全零向量,然后通过LSTM层获取输出,并仅保留最后一个时间步的输出。最终通过全连接层生成预测结果。
4. 模型训练与评估
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
  • 解释: 定义损失函数和优化器。损失函数为均方误差(MSE),优化器为Adam算法,它通过梯度下降优化模型的参数。
for epoch in range(EPOCHS):model.train()epoch_train_loss = 0for X_batch, y_batch in train_loader:X_batch = X_batch.to(device)y_batch = y_batch.to(device)outputs = model(X_batch)loss = criterion(outputs, y_batch)optimizer.zero_grad()loss.backward()optimizer.step()epoch_train_loss += loss.item() * X_batch.size(0)
  • 解释: 训练循环。每个epoch中,模型首先进入训练模式,并循环遍历训练数据进行前向传播、计算损失、反向传播和优化更新权重。每个batch训练完成后,累积损失用于后续的模型评估。
model.eval()
epoch_test_loss = 0with torch.no_grad():for X_batch, y_batch in test_loader:X_batch = X_batch.to(device)y_batch = y_batch.to(device)outputs = model(X_batch)loss = criterion(outputs, y_batch)epoch_test_loss += loss.item() * X_batch.size(0)
  • 解释: 测试循环。在评估阶段,模型切换为评估模式,不进行梯度更新。通过前向传播计算测试集的损失,以评估模型的泛化能力。
mse = mean_squared_error(y_test_unscaled, y_pred_unscaled)
mae = mean_absolute_error(y_test_unscaled, y_pred_unscaled)
  • 解释: 计算均方误差(MSE)和平均绝对误差(MAE),作为模型的评估指标,评估预测值与真实值之间的偏差。

↓↓↓更多热门推荐:
CNN模型实现CIFAR-10彩色图片识别

全部项目数据集、代码、教程点击下方名片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/462793.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三周精通FastAPI:27 使用使用SQLModel操作SQL (关系型) 数据库

官网文档:https://fastapi.tiangolo.com/zh/tutorial/sql-databases/ SQL (关系型) 数据库 FastAPI不需要你使用SQL(关系型)数据库。 但是您可以使用任何您想要的关系型数据库。 这里我们将看到一个使用SQLModel的示例。 SQLModel是在SQLAlchemy和Pydantic的基础…

C语言 ——— 学习和使用 strstr 函数,并模拟实现

目录 strstr 函数的作用 学习 strstr 函数​编辑 使用 strstr 函数 模拟实现 strstr 函数 strstr 函数的作用 查找子字符串 返回指向 str1 中第一次出现的 str2 的指针,如果 str2 不是 str1 的一部分,则返回 null 指针 学习 strstr 函数 函数的参数…

将 IBM WatsonX 数据与 Milvus 结合使用,构建用于知识检索的智能 Slack 机器人

在当今快节奏的工作环境中,快速轻松地访问信息对于保持生产力和效率至关重要。无论是在 Runbook 中查找特定说明,还是访问关键知识转移 (KT) 文档,快速检索相关信息的能力都可以产生重大影响。 本教程将指导您构建一个…

《高频电子线路》—— 振荡器稳定性问题

文章内容来源于【中国大学MOOC 华中科技大学通信(高频)电子线路精品公开课】,此篇文章仅作为笔记分享。 振荡器稳定性问题 频率准确度 & 频率稳定度 希望频率稳定度越小越好。 频率稳定度分类 影响振荡频率稳定度的参数 振荡频率是和电…

基本查询【MySQL】

文章目录 基本查询插入时是否更新替换查询指定列查询查询字段为表达式为查询结果指定别名结果去重where条件NULL 的查询 结果排序筛选分页结果UpdateDelete截断表聚合函数分组(group by)having && where 基本查询 建表 mysql> create table Student (-> id int…

Android15音频进阶之Cuttlefish搭建音频开发环境(九十二)

简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【原创干货持续更新中……】🚀 优质视频课程:AAOS车载系统+…

Qt QCheckBox、QPushButton和QRadioButton详解

QCheckBox(复选框) 功能:QCheckBox用于创建一个复选框控件,允许用户从多个选项中选择多个。 属性: checkable:决定复选框是否可以被选中或取消选中。checked:表示复选框当前的选中状态&#…

【SpringMVC】传递json,获取url参数,上传文件

【传递json数据】 【json概念】 一种轻量级数据交互格式,有自己的格式和语法,使用文本表示一个对象或数组的信息,其本质上是字符串,负责在不同的语言中数据传递与交换 json数据以字符串的形式体现 【json字符串与Java对象互转…

2024/11/1 操作系统pv大题总结

2014: 2022: 2020: 2019: 2011: 读者写者问题:

00-开发环境 MPLAB IDE 配置

MPLAB IDE V8.83 File 菜单简介 New (CtrlN): 创建一个新文件,用于编写新的代码。 Add New File to Project...: 将新文件添加到当前项目中。 Open... (CtrlO): 打开现有文件。 Close (CtrlE): 关闭当前打开的文件。 …

如何在Apple Vision Pro上打造成功的沉浸式叙述应用

随着科技的进步,沉浸式叙述应用正在成为一种全新的娱乐方式。Apple Vision Pro的发布,标志着空间计算技术迈上了新的台阶。本文将探讨如何在Vision Pro上构建一款类似Encounter Dinosaur的沉浸式叙述应用,具体通过分析《Out There》这款作品,总结出一系列关键点,帮助创作者…

Linux练习作业

1.搭建dns服务器能够对自定义的正向或者反向域完成数据解析查询。 2.配置从DNS服务器,对主dns服务器进行数据备份 环境准备 主从服务器都需要进行的操作#关闭防火墙、SELinnux systemctl stop firewalld setenforce 0#软件安装 yum install bind -y实验一&#…

计算机网络:网络层 —— IP 多播技术

文章目录 基本概念IP多播地址和多播组 IP多播的类型硬件多播将IPv4多播地址映射为多播MAC地址 基本概念 多播(Multicast,也称为组播)是一种实现“一对多”通信的技术,允许一台或多台主机(多播源)发送单一数…

掌握AI Prompt的艺术:如何有效引导智能助手

开头叙述: 在人工智能的世界里,Prompt(提示)是沟通人类意图与机器理解之间的桥梁。它不仅是一串简单的文字,而是一把钥匙,能够解锁AI模型的潜力,引导它们执行复杂的任务。本文将探讨Prompt的重…

[SAP ABAP] SMW0上传模板

通常来说,一个批量导入的程序必须使用指定的模板,我们需要将模板保存到SAP系统中,以便用户下载并更改。这里我们可以使用事务码SMW0解决上述的问题 1.选择二进制类型 2.输入存放的包 3.创建对象 选择需要进行上传的本地模板文件到SAP系统中 …

第二十六章 Vue之在当前组件范围内获取dom元素和组件实例

目录 一、概述 二、获取dom 2.1. 具体步骤 2.2. 完整代码 2.2.1. main.js 2.2.2. App.vue 2.3. BaseChart.vue 三、获取组件实例 3.1. 具体步骤 3.2. 完整代码 3.2.1. main.js 3.2.2. App.vue 3.2.3. BaseForm.vue 3.3. 运行效果 一、概述 我们过去在想要获取一…

基于树莓派的安保巡逻机器人--(一、快速人脸录入与精准人脸识别)

目录 零、前言 一、人脸检测 二、人脸识别 1、采集人脸 2、训练人脸识别模型 3、人脸识别应用 零、前言 随着智能安防需求的增长,基于人工智能和物联网的安保系统逐渐成为趋势。树莓派因其低成本、高扩展性等特点,成为很多AI项目的理想平台。本文将为大…

软件测试学习笔记丨Flask操作数据库-对象与数据模型

本文转自测试人社区,原文链接:https://ceshiren.com/t/topic/23440 对象与数据模型 数据模型:是数据特征的抽象,抽象层次上描述了系统的静态特征、动态行为和约束条件,为数据库系统的信息表示与操作提供一个抽象的框架…

信号量本质 信号量实验(控制车辆运行,优先级反转)互斥量

信号量本质 前面介绍的队列(queue)可以用于传输数据:在任务之间、任务和中断之间。 消息队列用于传输多个数据,但是有时候我们只需要传递状态,这个状态值需要用一个 数值表示,比如: ⚫ 卖家:做好了 1 …

【STL_list 模拟】——打造属于自己的高效链表容器

一、list节点 ​ list是一个双向循环带头的链表&#xff0c;所以链表节点结构如下&#xff1a; template<class T>struct ListNode{T val;ListNode* next;ListNode* prve;ListNode(int x){val x;next prve this;}};二、list迭代器 2.1、list迭代器与vector迭代器区别…