gpt4 book ai didi

tensorflow - 使用 Keras 构建多变量、多任务 LSTM

转载 作者:行者123 更新时间:2023-11-30 08:21:12 25 4
gpt4 key购买 nike

序言

我目前正在研究机器学习问题,我们的任务是使用过去的产品销售数据来预测 future 的销售量(以便商店可以更好地计划库存)。我们基本上有时间序列数据,其中我们知道每种产品在哪几天售出了多少单位。我们还有诸如天气如何、是否有公共(public)假期、是否有任何产品正在销售等信息。

我们已经能够使用具有密集层的 MLP 成功地对此进行建模,并且仅使用滑动窗口方法来包括周围日子的销售量。但是,我们相信我们将能够通过 LSTM 等时间序列方法获得更好的结果。

数据

我们拥有的数据基本上如下:

enter image description here

( 编辑: 为清楚起见,上图中的“时间”列不正确。我们每天输入一次,而不是每月一次。但其他结构是相同的!)

所以 X 数据的形状是:

(numProducts, numTimesteps, numFeatures) = (50 products, 1096 days, 90 features)

Y 数据的形状为:
(numProducts, numTimesteps, numTargets) =  (50 products, 1096 days, 3 binary targets)

enter image description here

所以我们有三年(2014 年、2015 年、2016 年)的数据,并希望对此进行训练,以便对 2017 年做出预测。(这当然不是 100% 正确,因为我们实际上有截至 2017 年 10 月的数据,但让我们暂时忽略它)

问题

我想在 Keras 中构建一个 LSTM 来进行这些预测。虽然有几个地方我卡住了。所以我有六个具体的问题(我知道一个应该尝试将 Stackoverflow 帖子限制为一个问题,但这些都是相互交织的)。

首先, 我将如何分割批次的数据 ?既然我有整整三年,那么简单地推进三批,每次都是一年的规模是否有意义?或者更小批量(比如 30 天)和使用滑动窗口更有意义吗? IE。而不是 36 个批次,每个批次 30 天,我使用 36 * 6 个批次,每个批次 30 天,每次滑动 5 天?或者这真的不是 LSTM 应该使用的方式吗? (请注意,数据中有相当多的季节性,我也需要捕捉这种长期趋势)。

其次, 使用 有意义吗? return_sequences=True这里?换句话说,我将 Y 数据保持原样 (50, 1096, 3)这样(据我所知)在每个时间步都有一个预测,可以针对目标数据计算损失?或者我会更好地使用 return_sequences=False ,以便仅使用每批的最终值来评估损失(即,如果使用年度批次,则在 2016 年对于产品 1,我们根据 2016 年 12 月的值 (1,1,1) 进行评估)。

第三 我应该如何处理这 50 种不同的产品? 它们不同,但仍然密切相关,我们已经看到其他方法(例如具有简单时间窗口的 MLP)在同一模型中考虑所有产品时结果更好。目前摆在桌面上的一些想法是:
  • 将目标变量更改为不仅仅是 3 个变量,而是 3 * 50 = 150;即对于每个产品有三个目标,所有这些目标都是同时训练的。
  • 将 LSTM 层之后的结果拆分为 50 个密集网络,这些网络将 LSTM 的输出作为输入,加上一些特定于每个产品的特征——即我们得到一个具有 50 个损失函数的多任务网络,然后我们对其进行优化一起。那会不会很疯狂?
  • 将产品视为单个观察,并包含 LSTM 层中已有的产品特定功能。仅使用这一层,然后使用大小为 3 的输出层(用于三个目标)。在单独的批次中推出每个产品。

  • 四、 我如何处理验证数据 ?通常我只会保留一个随机选择的样本进行验证,但在这里我们需要保持时间顺序。所以我想最好的办法是留出几个月?

    第五,这可能是我最不清楚的部分 - 如何使用实际结果进行预测 ?假设我使用了 return_sequences=False我对所有三年进行了三批(每次截至 11 月)的训练,目的是训练模型预测下一个值(2014 年 12 月、2015 年 12 月、2016 年 12 月)。如果我想在 2017 年使用这些结果,这实际上是如何工作的?如果我理解正确,在这种情况下我唯一能做的就是将 2017 年 1 月到 11 月的所有数据点输入模型,它会给我一个 2017 年 12 月的预测。这是正确的吗?但是,如果我使用 return_sequences=True ,然后对截至 2016 年 12 月的所有数据进行训练,那么我是否能够仅通过为模型提供 2017 年 1 月观察到的特征来获得 2017 年 1 月的预测?或者我还需要在 2017 年 1 月之前给它 12 个月吗? 2017 年 2 月怎么样,我还需要给出 2017 年的值(value),再加上之前 11 个月的值(value)吗? (如果听起来我很困惑,那是因为我很困惑!)

    最后,取决于我应该使用什么结构, 我如何在 Keras 中执行此操作 ?我目前想到的是以下几点:(尽管这仅适用于一种产品,因此不能解决所有产品都采用同一型号的问题):

    Keras 代码
    trainX = trainingDataReshaped #Data for Product 1, Jan 2014 to Dec 2016
    trainY = trainingTargetReshaped
    validX = validDataReshaped #Data for Product 1, for ??? Maybe for a few months?
    validY = validTargetReshaped

    numSequences = trainX.shape[0]
    numTimeSteps = trainX.shape[1]
    numFeatures = trainX.shape[2]

    numTargets = trainY.shape[2]

    model = Sequential()
    model.add(LSTM(100, input_shape=(None, numFeatures), return_sequences=True))
    model.add(Dense(numTargets, activation="softmax"))

    model.compile(loss=stackEntry.params["loss"],
    optimizer="adam",
    metrics=['accuracy'])

    history = model.fit(trainX, trainY,
    batch_size=30,
    epochs=20,
    verbose=1,
    validation_data=(validX, validY))

    predictX = predictionDataReshaped #Data for Product 1, Jan 2017 to Dec 2017

    prediction=model.predict(predictX)

    最佳答案

    所以:

    Firstly, how would I slice up my data for the batches? Since I have three full years, does it make sense to simply push through three batches, each time of size one year? Or does it make more sense to make smaller batches (say 30 days) and also to using sliding windows? I.e. instead of 36 batches of 30 days each, I use 36 * 6 batches of 30 days each, each time sliding with 5 days? Or is this not really the way LSTMs should be used? (Note that there is quite a bit of seasonality in the data, to I need to catch that kind of long-term trend as well).



    老实说 - 对此类数据进行建模真的很难。首先 - 我不建议你使用 LSTM s 因为它们旨在捕获一些不同类型的数据(例如 NLP 或语音,其中对长期依赖关系建模非常重要 - 而不是季节性),并且它们需要大量数据才能学习。我宁愿建议您使用 GRU SimpleRNN 这更容易学习,应该更适合你的任务。

    在批处理方面 - 我绝对会建议您使用固定窗口技术,因为它最终会产生比提供整年或整月更多的数据点。尝试将天数设置为元参数,这也将通过在训练中使用不同的值并选择最合适的值进行优化。

    谈到季节性 - 当然,这是一个案例,但是:
  • 您可能收集的数据点和年份太少,无法很好地估计季节趋势,
  • 使用任何类型的循环神经网络来捕捉这种季节性是一个 真的很糟糕主意。

  • 我建议你做的是:
  • 尝试添加季节性特征(例如,月份变量、日期变量,如果当天有某个假期或距离下一个重要假期还有多少天,则该变量将设置为 true - 这是一个您可以真正体验的房间创意)
  • 使用汇总的去年数据作为功能 - 例如,您可以提供去年的结果或它们的汇总,例如去年结果的运行平均值、最大值、最小值等。

  • Secondly, does it make sense to use return_sequences=True here? In other words, I keep my Y data as is (50, 1096, 3) so that (as far as I've understood it) there is a prediction at every time step for which a loss can be calculated against the target data? Or would I be better off with return_sequences=False, so that only the final value of each batch is used to evaluate the loss (i.e. if using yearly batches, then in 2016 for product 1, we evaluate against the Dec 2016 value of (1,1,1)).



    使用 return_sequences=True可能有用,但仅适用于以下情况:
  • 当给定 LSTM (或另一个循环层)之后将是另一个循环层。
  • 在一个场景中 - 当您通过在不同时间窗口中同时学习模型等方式将移位的原始系列作为输出提供时。

  • 第二点中描述的方法可能是一种有趣的方法,但请记住,它可能有点难以实现,因为您需要重写模型以获得生产结果。更困难的是,您需要针对多种类型的时间不稳定性来测试您的模型——而这种方法可能会使这完全不可行。

    Thirdly how should I deal with the 50 different products? They are different, but still strongly correlated and we've seen with other approaches (for example an MLP with simple time-windows) that the results are better when all products are considered in the same model. Some ideas that are currently on the table are:

    • change the target variable to be not just 3 variables, but 3 * 50 = 150; i.e. for each product there are three targets, all of which are trained simultaneously.
    • split up the results after the LSTM layer into 50 dense networks, which take as input the ouputs from the LSTM, plus some features that are specific to each product - i.e. we get a multi-task network with 50 loss functions, which we then optimise together. Would that be crazy?
    • consider a product as a single observation, and include product-specific features already at the LSTM layer. Use just this one layer followed by an ouput layer of size 3 (for the three targets). Push through each product in a separate batch.


    我肯定会选择第一个选择,但在提供详细解释之前,我将讨论第二个和第三个的缺点:
  • 在第二种方法中:它不会生气,但你会失去很多产品目标之间的相关性,
  • 在第三种方法中:您将丢失许多发生在不同时间序列之间的依赖关系中的有趣模式。

  • 在做出我的选择之前——让我们讨论另一个问题——数据集中的冗余。我猜你有3种特征:
  • 产品特定的(假设有“m”个)
  • 一般功能 - 假设有“n”个。

  • 现在你有尺寸表 (timesteps, m * n, products) .我会把它变成形状的 table (timesteps, products * m + n)因为所有产品的一般功能都相同。这将为您节省大量内存,并且还可以提供给循环网络(请记住, keras 中的循环层只有一个特征维度 - 而您有两个 - productfeature)。

    那么为什么我认为第一种方法是最好的呢?因为它利用了许多有趣的数据依赖关系。当然 - 这可能会损害训练过程 - 但有一个简单的技巧可以克服这个问题: 降维 .你可以例如火车 PCA在你的 150 维向量上,并将它的大小减小到一个更小的一个 - 感谢你的依赖项由 PCA 建模并且您的输出具有更可行的尺寸。

    Fourthly, how do I deal with validation data? Normally I would just keep out a randomly selected sample to validate against, but here we need to keep the time ordering in place. So I guess the best is to just keep a few months aside?



    这是一个非常重要的问题。根据我的经验 - 您需要针对多种类型的不稳定性测试您的解决方案,以确保它正常工作。因此,您应该记住一些规则:
  • 应该有无重叠在您的训练序列和测试序列之间。如果有这种情况 - 您将在训练时将测试集中的有效值馈送到模型中,
  • 您需要针对多种时间依赖性测试模型时间稳定性。

  • 最后一点可能有点含糊 - 所以给你提供一些例子:
  • 年稳定性 - 通过使用两年的每种可能组合进行训练来验证您的模型,并在保留时间上对其进行测试(例如 2015、2016 与 2017、2015、2017 与 2016 等)-这将向您展示年份变化如何影响您的模型,
  • future 预测稳定性 - 在周/月/年的子集上训练您的模型,并使用接下来的周/月/年结果对其进行测试(例如,在 2015 年 1 月、2016 年 1 月和 2017 年 1 月进行训练,并使用 2015 年 2 月、2016 年 2 月、2017 年 2 月进行测试)数据等)
  • 月稳定性 - 在测试集中保留某个月份时训练模型。

  • 当然 - 你可以再试一次。

    Fifthly, and this is the part that is probably the most unclear to me - how can I use the actual results to perform predictions? Let's say I used return_sequences=False and I trained on all three years in three batches (each time up to Nov) with the goal of training the model to predict the next value (Dec 2014, Dec 2015, Dec 2016). If I want to use these results in 2017, how does this actually work? If I understood it correctly, the only thing I can do in this instance is to then feed the model all the data points for Jan to Nov 2017 and it will give me back a prediction for Dec 2017. Is that correct? However, if I were to use return_sequences=True, then trained on all data up to Dec 2016, would I then be able to get a prediction for Jan 2017 just by giving the model the features observed at Jan 2017? Or do I need to also give it the 12 months before Jan 2017? What about Feb 2017, do I in addition need to give the value for 2017, plus a further 11 months before that? (If it sounds like I'm confused, it's because I am!)



    这取决于您构建模型的方式:
  • 如果您使用 return_sequences=True你需要重写它才能拥有 return_sequence=False或者只是获取输出并仅考虑结果的最后一步,
  • 如果您使用固定窗口 - 那么您只需要在预测模型之前输入一个窗口,
  • 如果您使用不同的长度 - 您可以在您想要的预测期之前输入任何时间步长(但我建议您至少输入 7 天)。

    最后,根据我应该使用什么结构,我如何在 Keras 中做到这一点?我目前想到的是以下几点:(尽管这仅适用于一种产品,因此不能解决所有产品都采用同一型号的问题)

  • 在这里 - 需要有关您选择的模型类型的更多信息。

    关于tensorflow - 使用 Keras 构建多变量、多任务 LSTM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46947842/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com