【发布时间】:2018-04-07 10:53:22
【问题描述】:
序言
我目前正在研究一个机器学习问题,我们的任务是使用过去的产品销售数据来预测未来的销售量(以便商店可以更好地计划他们的库存)。我们基本上有时间序列数据,我们知道每种产品在哪几天售出了多少件。我们还提供诸如天气情况、是否有公共假期、是否有任何产品在销售等信息。
我们已经能够使用具有密集层的 MLP 成功地对此进行建模,并且仅使用滑动窗口方法来包含周围几天的销售量。但是,我们相信使用 LSTM 等时间序列方法可以获得更好的结果。
数据
我们掌握的数据基本如下:
(编辑:为清楚起见,上图中的“时间”列不正确。我们每天输入一次,而不是每月一次。但其他结构是相同的!)
所以X数据是有形状的:
(numProducts, numTimesteps, numFeatures) = (50 products, 1096 days, 90 features)
Y 数据的形状:
(numProducts, numTimesteps, numTargets) = (50 products, 1096 days, 3 binary targets)
所以我们有三年(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 月的值 @987654333 进行评估@)。
第三,我应该如何处理这 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 年的价值,以及在那之前的 11 个月? (如果听起来我很困惑,那是因为我很困惑!)
最后,根据我应该使用的结构,我如何在 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)
【问题讨论】:
-
这个问题可能会帮助您入门:stackoverflow.com/questions/46482139/…
-
一些不构成完整答案但可能有用的随机想法:#1 请参阅github.com/fchollet/keras/issues/8055 re timedistributed issues; #2 我发现拆分序列以尝试捕获整体数据的多个具有代表性的“特征”似乎最适合设置序列长度; #3 参数模型似乎比分类模型更难在 LSTM 上获得好的结果——我在这里尝试了一段时间:babble-rnn.consected.com; #4 在训练期间,我在查看结果时得到了最好的结果,而不仅仅是计算出的损失,这主要是建模噪声!
标签: tensorflow machine-learning neural-network keras lstm