时间序列预测深度学习速成班。
在7天内将深度学习方法应用到您的时间序列项目中。
时间序列预测具有挑战性,尤其是在处理长序列、嘈杂数据、多步预测以及多个输入和输出变量时。
深度学习方法为时间序列预测提供了诸多前景,例如自动学习时间依赖性和自动处理趋势和季节性等时间结构。
在这个速成课程中,您将发现如何在7天内使用Python入门并自信地为时间序列预测问题开发深度学习模型。
这是一篇内容丰富且重要的文章。您可能想把它加入书签。
开始您的项目,阅读我的新书《时间序列预测深度学习》,其中包含分步教程和所有示例的Python源代码文件。
让我们开始吧。

如何开始使用深度学习进行时间序列预测(7 天迷你课程)
照片由 Brian Richardson 拍摄,保留部分权利。
本速成课程适合谁?
在开始之前,让我们确保您来对了地方。
以下列表提供了一些关于本课程设计对象的一般性指导。
您需要了解
- 您需要了解时间序列预测的基础知识。
- 您需要熟悉基础的Python、NumPy和用于深度学习的Keras。
您不需要知道:
- 您不需要是数学天才!
- 您无需成为深度学习专家!
- 您不需要成为时间序列专家!
这个速成课程将带您从一位了解少量机器学习的开发者,成长为能够将深度学习方法应用到您自己的时间序列预测项目中的开发者。
注意:本速成课程假定您拥有可用的Python 2或3 SciPy环境,并且至少安装了NumPy和Keras 2。如果您在环境设置方面需要帮助,可以遵循此处的[分步教程](https://machinelearning.org.cn/setup-manage-python-deep-learning-step-step-tutorial/)。
速成课程概览
本速成课程分为7节课。
您可以每天完成一节课(推荐),或者在一天内完成所有课程(硬核)。这真的取决于您的可用时间和热情程度。
以下是7个课程,将帮助您开始并熟练掌握Python中的时间序列预测深度学习。
- 第一课:深度学习的承诺
- 第二课:如何转换时间序列数据
- 第三课:用于时间序列预测的MLP
- 第四课:用于时间序列预测的CNN
- 第五课:用于时间序列预测的LSTM
- 第六课:用于时间序列预测的CNN-LSTM
- 第七课:用于多步时间序列预测的Encoder-Decoder LSTM
每节课可能需要60秒到30分钟不等。请慢慢来,按照自己的节奏完成课程。在下面的评论中提问,甚至发布结果。
这些课程要求您自己去了解如何完成任务。我将提供提示,但每节课的部分目的是迫使您学习在哪里可以找到有关深度学习、时间序列预测以及Python中最佳工具的帮助(提示,我所有的答案都在这个博客上,请使用搜索框)。
我确实以相关文章链接的形式提供了更多帮助,因为我希望您建立一些信心和动力。
在评论中发布您的结果,我会为您加油!
坚持住,不要放弃。
注意:这只是一个速成课程。有关更多详细信息和25个完整的教程,请参阅我关于该主题的书《时间序列预测深度学习》。
时间序列深度学习需要帮助吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
第一课:深度学习的承诺
在本课中,您将发现深度学习方法在时间序列预测中的潜力。
通常,多层感知机 (MLP) 等神经网络提供了一些算法所不具备的功能,例如:
- 对噪声具有鲁棒性。神经网络对输入数据和映射函数中的噪声具有鲁棒性,甚至可以支持在缺失值存在的情况下进行学习和预测。
- 非线性。神经网络不对映射函数做出强假设,并且很容易学习线性和非线性关系。
- 多变量输入。可以指定任意数量的输入特征,为多变量预测提供直接支持。
- 多步预测。可以指定任意数量的输出值,从而提供
对多步甚至多变量预测的直接支持。
仅凭这些功能,前馈神经网络可能对时间序列预测很有用。
您的任务
对于本课,您必须从卷积神经网络和循环神经网络中各提出一种可能有利于时间序列预测问题建模的能力。
请在下面的评论中发布您的答案。我很想看看您会发现什么。
更多信息
在下一课中,您将学习如何转换时间序列数据以用于时间序列预测。
第二课:如何转换时间序列数据
在本课中,您将学习如何将时间序列数据转换为监督学习格式。
大多数实际的机器学习都使用监督学习。
监督学习是指您拥有输入变量(X)和输出变量(y),并使用算法学习从输入到输出的映射函数。目标是近似真实的底层映射,以便当您拥有新的输入数据时,可以预测该数据对应的输出变量。
时间序列数据可以被表述为监督学习。
给定一个时间序列数据集的数字序列,我们可以重新构造数据,使其看起来像一个监督学习问题。我们可以通过使用先前的时间步作为输入变量,并将下一个时间步作为输出变量来实现这一点。
例如,序列
1 |
1, 2, 3, 4, 5, ... |
可以转换为具有输入和输出组件的样本,用作训练集的一部分,以训练深度学习神经网络之类的监督学习模型。
1 2 3 4 |
X, y [1, 2, 3] 4 [2, 3, 4] 5 ... |
这被称为滑动窗口转换,因为它就像将一个窗口滑过先前用作模型输入的观测值,以预测序列中的下一个值。在这种情况下,窗口宽度为3个时间步。
您的任务
对于本课,您必须开发Python代码,将每日女性出生数据集转换为监督学习格式,其中包含一定数量的输入和一个输出。
您可以从这里下载数据集:daily-total-female-births.csv
请在下面的评论中发布您的答案。我很想看看您会发现什么。
更多信息
在下一课中,您将学习如何开发多层感知器深度学习模型来预测单变量时间序列。
第三课:用于时间序列预测的MLP
在本课中,您将学习如何开发多层感知器模型(MLP)来进行单变量时间序列预测。
我们可以将一个简单的单变量问题定义为整数序列,用该序列拟合模型,并让模型预测序列中的下一个值。我们将问题框定为有3个输入和1个输出,例如:[10, 20, 30]作为输入,[40]作为输出。
首先,我们可以定义模型。我们将通过第一个隐藏层上的input_dim参数将输入时间步的数量定义为3。在这种情况下,我们将使用高效的Adam版本随机梯度下降,并优化均方误差(‘mse‘)损失函数。
模型定义后,就可以在训练数据上进行拟合,然后使用拟合的模型进行预测。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# 单变量 MLP 示例 from numpy import array from keras.models import Sequential from keras.layers import Dense # 定义数据集 X = array([[10, 20, 30], [20, 30, 40], [30, 40, 50], [40, 50, 60]]) y = array([40, 50, 60, 70]) # 定义模型 model = Sequential() model.add(Dense(100, activation='relu', input_dim=3)) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=2000, verbose=0) # 演示预测 x_input = array([50, 60, 70]) x_input = x_input.reshape((1, 3)) yhat = model.predict(x_input, verbose=0) print(yhat) |
运行示例将用数据拟合模型,然后预测下一个样本外的值。
给定输入[50, 60, 70],模型正确预测序列中的下一个值为80。
您的任务
对于本课,您必须下载每日女性出生数据集,将其分为训练集和测试集,并开发一个能够对测试集进行合理准确预测的模型。
您可以从这里下载数据集:daily-total-female-births.csv
请在下面的评论中发布您的答案。我很想看看您会发现什么。
更多信息
在下一课中,您将学习如何开发卷积神经网络模型来预测单变量时间序列。
第四课:用于时间序列预测的CNN
在本课中,您将学习如何开发卷积神经网络模型(CNN)来进行单变量时间序列预测。
我们可以将一个简单的单变量问题定义为整数序列,用该序列拟合模型,并让模型预测序列中的下一个值。我们将问题框定为有3个输入和1个输出,例如:[10, 20, 30]作为输入,[40]作为输出。
与MLP模型的一个重要区别是,CNN模型期望三维输入,形状为[样本数, 时间步数, 特征数]。我们将数据定义为[样本数, 时间步数]的形式,并相应地进行重塑。
我们将通过第一个隐藏层上的input_shape参数将输入时间步的数量定义为3,特征数定义为1。
我们将使用一个卷积隐藏层,后跟一个最大池化层。然后将filter maps展平,再由Dense层解释并输出预测。该模型使用高效的Adam版本随机梯度下降,并优化均方误差(‘mse‘)损失函数。
模型定义后,就可以在训练数据上进行拟合,然后使用拟合的模型进行预测。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# 单变量CNN示例 from numpy import array from keras.models import Sequential from keras.layers import Dense from keras.layers import Flatten from keras.layers.convolutional import Conv1D from keras.layers.convolutional import MaxPooling1D # 定义数据集 X = array([[10, 20, 30], [20, 30, 40], [30, 40, 50], [40, 50, 60]]) y = array([40, 50, 60, 70]) # 从 [样本数, 时间步数] 重塑为 [样本数, 时间步数, 特征数] X = X.reshape((X.shape[0], X.shape[1], 1)) # 定义模型 model = Sequential() model.add(Conv1D(filters=64, kernel_size=2, activation='relu', input_shape=(3, 1))) model.add(MaxPooling1D(pool_size=2)) model.add(Flatten()) model.add(Dense(50, activation='relu')) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=1000, verbose=0) # 演示预测 x_input = array([50, 60, 70]) x_input = x_input.reshape((1, 3, 1)) yhat = model.predict(x_input, verbose=0) print(yhat) |
运行示例将用数据拟合模型,然后预测下一个样本外的值。
给定输入[50, 60, 70],模型正确预测序列中的下一个值为80。
您的任务
对于本课,您必须下载每日女性出生数据集,将其分为训练集和测试集,并开发一个能够对测试集进行合理准确预测的模型。
您可以从这里下载数据集:daily-total-female-births.csv
请在下面的评论中发布您的答案。我很想看看您会发现什么。
更多信息
在下一课中,您将学习如何开发长短期记忆(LSTM)网络模型来预测单变量时间序列。
第五课:用于时间序列预测的LSTM
在本课中,您将学习如何开发长短期记忆神经网络模型(LSTM)来进行单变量时间序列预测。
我们可以将一个简单的单变量问题定义为整数序列,用该序列拟合模型,并让模型预测序列中的下一个值。我们将问题框定为有3个输入和1个输出,例如:[10, 20, 30]作为输入,[40]作为输出。
与MLP模型的一个重要区别是,并且像CNN模型一样,LSTM模型期望三维输入,形状为[样本数, 时间步数, 特征数]。我们将数据定义为[样本数, 时间步数]的形式,并相应地进行重塑。
我们将通过第一个隐藏层上的input_shape参数将输入时间步的数量定义为3,特征数定义为1。
我们将使用一个LSTM层来处理每个输入子序列(3个时间步),然后使用一个Dense层来解释序列的摘要。该模型使用高效的Adam版本随机梯度下降,并优化均方误差(‘mse‘)损失函数。
模型定义后,就可以在训练数据上进行拟合,然后使用拟合的模型进行预测。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# 单变量LSTM示例 from numpy import array from keras.models import Sequential 从 keras.layers 导入 LSTM from keras.layers import Dense # 定义数据集 X = array([[10, 20, 30], [20, 30, 40], [30, 40, 50], [40, 50, 60]]) y = array([40, 50, 60, 70]) # 从 [样本数, 时间步数] 重塑为 [样本数, 时间步数, 特征数] X = X.reshape((X.shape[0], X.shape[1], 1)) # 定义模型 model = Sequential() model.add(LSTM(50, activation='relu', input_shape=(3, 1))) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=1000, verbose=0) # 演示预测 x_input = array([50, 60, 70]) x_input = x_input.reshape((1, 3, 1)) yhat = model.predict(x_input, verbose=0) print(yhat) |
运行示例将用数据拟合模型,然后预测下一个样本外的值。
给定输入[50, 60, 70],模型正确预测序列中的下一个值为80。
您的任务
对于本课,您必须下载每日女性出生数据集,将其分为训练集和测试集,并开发一个能够对测试集进行合理准确预测的模型。
您可以从这里下载数据集:daily-total-female-births.csv
请在下面的评论中发布您的答案。我很想看看您会发现什么。
更多信息
在下一课中,您将学习如何开发混合CNN-LSTM模型来解决单变量时间序列预测问题。
第六课:用于时间序列预测的CNN-LSTM
在本课中,您将学习如何开发混合CNN-LSTM模型来进行单变量时间序列预测。
该模型的优势在于,它可以支持非常长的输入序列,这些序列可以被CNN模型块或子序列读取,然后由LSTM模型组合起来。
我们可以将一个简单的单变量问题定义为整数序列,用该序列拟合模型,并让模型预测序列中的下一个值。我们将问题框定为有4个输入和1个输出,例如:[10, 20, 30, 40]作为输入,[50]作为输出。
在使用混合CNN-LSTM模型时,我们将进一步将每个样本划分为更多的子序列。CNN模型将解释每个子序列,LSTM将组合来自子序列的解释。因此,我们将每个样本划分为2个子序列,每个子序列有2个时间步。
CNN将被定义为期望每个子序列有2个时间步和一个特征。然后,整个CNN模型将被封装在TimeDistributed包装器层中,以便它可以应用于样本中的每个子序列。之后,结果将被LSTM层解释,然后模型输出预测。
该模型使用高效的Adam版本随机梯度下降,并优化均方误差(‘mse’)损失函数。
模型定义后,就可以在训练数据上进行拟合,然后使用拟合的模型进行预测。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# 单变量CNN-LSTM示例 from numpy import array from keras.models import Sequential 从 keras.layers 导入 LSTM from keras.layers import Dense from keras.layers import Flatten from keras.layers import TimeDistributed from keras.layers.convolutional import Conv1D from keras.layers.convolutional import MaxPooling1D # 定义数据集 X = array([[10, 20, 30, 40], [20, 30, 40, 50], [30, 40, 50, 60], [40, 50, 60, 70]]) y = array([50, 60, 70, 80]) # 从[样本数, 时间步数]重塑为[样本数, 子序列数, 时间步数, 特征数] X = X.reshape((X.shape[0], 2, 2, 1)) # 定义模型 model = Sequential() model.add(TimeDistributed(Conv1D(filters=64, kernel_size=1, activation='relu'), input_shape=(None, 2, 1))) model.add(TimeDistributed(MaxPooling1D(pool_size=2))) model.add(TimeDistributed(Flatten())) model.add(LSTM(50, activation='relu')) model.add(Dense(1)) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=500, verbose=0) # 演示预测 x_input = array([50, 60, 70, 80]) x_input = x_input.reshape((1, 2, 2, 1)) yhat = model.predict(x_input, verbose=0) print(yhat) |
运行示例将用数据拟合模型,然后预测下一个样本外的值。
给定输入[50, 60, 70, 80],模型正确预测序列中的下一个值为90。
您的任务
对于本课,您必须下载每日女性出生数据集,将其分为训练集和测试集,并开发一个能够对测试集进行合理准确预测的模型。
您可以从这里下载数据集:daily-total-female-births.csv
请在下面的评论中发布您的答案。我很想看看您会发现什么。
更多信息
在下一课中,您将学习如何开发Encoder-Decoder LSTM网络模型来进行多步时间序列预测。
第七课:用于多步时间序列预测的Encoder-Decoder LSTM
在本课中,您将学习如何开发Encoder-Decoder LSTM网络模型来进行多步时间序列预测。
我们可以将一个简单的单变量问题定义为整数序列,用该序列拟合模型,并让模型预测序列中的下两个值。我们将问题框定为有3个输入和2个输出,例如:[10, 20, 30]作为输入,[40, 50]作为输出。
LSTM模型期望三维输入,形状为[样本数, 时间步数, 特征数]。我们将数据定义为[样本数, 时间步数]的形式,并相应地进行重塑。在使用Encoder-Decoder模型时,输出也必须这样形状。
我们将通过第一个隐藏层上的input_shape参数将输入时间步的数量定义为3,特征数定义为1。
我们将定义一个LSTM编码器来读取和编码3个时间步的输入序列。编码后的序列将由模型重复2次,以满足模型所需的两个输出时间步,使用RepeatVector层。这些将被馈送到解码器LSTM层,然后使用一个TimeDistributed层包装的Dense输出层,该层为输出序列中的每个时间步产生一个输出。
该模型使用高效的Adam版本随机梯度下降,并优化均方误差(‘mse‘)损失函数。
模型定义后,就可以在训练数据上进行拟合,然后使用拟合的模型进行预测。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# 多步Encoder-Decoder LSTM示例 from numpy import array from keras.models import Sequential 从 keras.layers 导入 LSTM from keras.layers import Dense from keras.layers import RepeatVector from keras.layers import TimeDistributed # 定义数据集 X = array([[10, 20, 30], [20, 30, 40], [30, 40, 50], [40, 50, 60]]) y = array([[40,50],[50,60],[60,70],[70,80]]) # 从 [样本数, 时间步数] 重塑为 [样本数, 时间步数, 特征数] X = X.reshape((X.shape[0], X.shape[1], 1)) y = y.reshape((y.shape[0], y.shape[1], 1)) # 定义模型 model = Sequential() model.add(LSTM(100, activation='relu', input_shape=(3, 1))) model.add(RepeatVector(2)) model.add(LSTM(100, activation='relu', return_sequences=True)) model.add(TimeDistributed(Dense(1))) model.compile(optimizer='adam', loss='mse') # 拟合模型 model.fit(X, y, epochs=100, verbose=0) # 演示预测 x_input = array([50, 60, 70]) x_input = x_input.reshape((1, 3, 1)) yhat = model.predict(x_input, verbose=0) print(yhat) |
运行示例将用数据拟合模型,然后预测未来两个样本外的值。
给定输入[50, 60, 70],模型正确预测序列中的下两个值为[80, 90]。
您的任务
对于本课,您必须下载每日女性出生数据集,将其分为训练集和测试集,并开发一个能够对测试集进行合理准确预测的模型。
您可以从这里下载数据集:daily-total-female-births.csv
请在下面的评论中发布您的答案。我很想看看您会发现什么。
更多信息
结束!
(看看您取得了多大的进步)
您做到了。干得好!
花点时间回顾一下您已经走了多远。
您发现了:
- 深度学习神经网络在时间序列预测问题中的应用前景。
- 如何将时间序列数据集转换为监督学习问题。
- 如何为单变量时间序列预测问题开发多层感知器模型。
- 如何为单变量时间序列预测问题开发卷积神经网络模型。
- 如何为单变量时间序列预测问题开发长短期记忆网络模型。
- 如何为单变量时间序列预测问题开发混合CNN-LSTM模型。
- 如何为多步时间序列预测问题开发Encoder-Decoder LSTM模型。
这仅仅是您在时间序列预测深度学习之旅的开始。请继续练习并提升您的技能。
迈出下一步,查看我的时间序列深度学习书籍。
总结
您对这个迷你课程感觉如何?
您喜欢这个速成课程吗?
您有任何问题吗?有没有遇到什么难点?
告诉我。在下面留言。
嗨,Jason,
喜欢这些教程,我开始觉得我能理解如何创建自己的模型了。
我目前正在尝试开发一个 LSTM,用于分析具有强烈季节性模式(尽管季节间隔相当不规则)的能源消耗时间序列数据集。它包含大约 8 个季节性周期,数据点约 45000 个。我希望能够基于此数据集训练一个模型,该模型能够模拟出与我已有数据形状相同的模拟数据;无需进行前向验证(即,我希望能够使用数据集的最后一个值作为输入来预测下一个值,然后将预测值用作下一次预测的输入)。
这种方法看起来合理吗?我也研究过 SARIMA 模型,但未能生成接近的模式。我对数据科学和机器学习相当陌生,到目前为止,你们的教程对我来说非常有价值。
谢谢!
我推荐这个过程
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
尝试多种方法和多种数据预处理方法,找出最有效的方法。不要从算法开始,算法可能错了。
嗨 Jason
可以请您解释一下这个函数吗?
x_input.reshape((1, 3))?
为什么需要这样?
谢谢
Denis
您好 Denus… 在深度学习时间序列预测的上下文中,将输入数据重塑为特定格式至关重要,因为深度学习模型期望以特定的形状接收输入。
函数
x_input.reshape((1, 3))
可能是为神经网络模型准备输入数据,该模型期望一个具有一列和三行的二维数组。以下是每个组成部分的含义:- **
1
**: 第一维表示样本或序列的数量。在这种情况下,1
表示一次只向模型输入一个序列或时间步。- **
3
**: 第二维表示此序列中的时间步长或特征数量。在这里,3
表示此序列中有三个值(特征)。### 为什么需要这种重塑?
对于许多神经网络,特别是处理时间序列数据(如 LSTM)的神经网络,输入格式通常期望为 **三维数组**:
(样本数, 时间步数, 特征数)
。通过重塑为(1, 3)
,我们创建了一个二维输入,可以根据需要进一步重塑以用于 LSTM 或其他模型。这种重塑与模型的期望一致,确保每个训练步骤都能以一致且可预测的格式接收数据。因此,
x_input.reshape((1, 3))
确保输入数据与模型的结构兼容。如果您处理多个序列或时间步,您可以相应地调整这些维度。import os
import cv2
import pandas as pd
from sklearn.model_selection import train_test_split
DATADIR = “C://Test/daily-total-female-births.csv”
data = pd.read_csv(DATADIR)
print(data.head())
y = data.Births
X = data.drop(‘Births’, axis=1)
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size=0.2)
print(“\nX_train:\n”)
print(X_train.head())
打印(X_train.shape)
print(“\nX_test:\n”)
print(X_test.head())
print(X_test.shape)
model = Sequential()
model.add(Dense(100, activation=’relu’, input_dim=3))
model.add(Dense(1))
model.compile(optimizer=’adam’, loss=’mse’,metrics=[‘accuracy’])
model.fit(X_train, y, epochs=20000, verbose=0)
错误
—————————————————————————
ValueError 回溯 (最近一次调用)
in
—-> 1 model.fit(X_train, y, epochs=20000)
c:\python\python37\lib\site-packages\keras\engine\training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)
950 sample_weight=sample_weight,
951 class_weight=class_weight,
–> 952 batch_size=batch_size)
953 # Prepare validation data.
954 do_validation = False
c:\python\python37\lib\site-packages\keras\engine\training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
749 feed_input_shapes,
750 check_batch_axis=False, # Don’t enforce the batch size.
–> 751 exception_prefix=’input’)
752
753 if y is not None
c:\python\python37\lib\site-packages\keras\engine\training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
136 ‘: expected ‘ + names[i] + ‘ to have shape ‘ +
137 str(shape) + ‘ but got array with shape ‘ +
–> 138 str(data_shape))
139 return data
140
ValueError: Error when checking input: expected dense_35_input to have shape (3,) but got array with shape (1,)
请帮帮我!!!!!!
也许可以确认一下您是否正确加载了数据集?
第一课:我对 CNN 的理解水平在维度问题上卡住了。但是,我能够使用 ANN 执行数字分类。准确率大约为 92%,正如许多地方报告的那样。
期待 CNN 等。
谢谢。
嗨,Jason,
我发现您的帖子非常有趣,因为我使用其他算法在各种场景中预测季节性数据。在这些场景中,我使用自动 ARIMA 和 R 平台,虽然一些结果令人满意,但开发平台和 ARIMA 调优过程的可行性不高。因此,如果我能找到一个更可行的算法和平台,那将是极好的。
我测试了您教程中的例子 3 到 5,使用了一些季节性场景(简单的 sin(x) 和具有季节性特征的线性函数),但发现预测结果非常差:我尝试更改多个参数(输入为 3、4 和 5 个值;归一化输入和输出值;选择 relu/adam 选项之外的其他激活/优化器/损失参数),但预测输出始终是一个线性函数,并且与预期输出相差甚远。对于相同的场景,自动 ARIMA 提供了更好的预测结果。
我将测试剩余的算法(06 和 07)以获得更好的结果;但是,如果您有任何关于如何改进它们的建议,请告知。
也许可以尝试调整模型以适应您的问题?
也许可以先尝试对数据进行季节性差分?
也许可以尝试混合模型?
喜欢这个博客。这个博客给了我很有用的信息。我喜欢这篇帖子,感谢提供……!!!!!
谢谢,很高兴它有帮助。
Jason,您提到(提示,我博客上有所有答案,请使用搜索框)。
我该如何通过搜索栏访问答案?我是不是错过了什么?
输入您需要帮助的内容,例如“LSTM 时间序列”,查看结果,阅读一些帖子。
这有帮助吗?
#Lesson 02: 如何转换时间序列数据
干得好!
嗨 David,
我可能是错的,但 Y=list(data[“Births”])[i+3] 应该对吗?当然,需要添加一些限制,以避免出现 IndexError。
正确。FYI,如果您想直接将数据下载到 python 中,可以使用这个
import pandas as pd
df_url = ‘https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-total-female-births.csv?__s=t6njmj1ql2orsiddx0lo’
df = pd.read_csv(df_url)
好建议!
一如既往地精彩,Jason!
我有一个关于您最后的编码器-解码器 LSTM 多步预测的例子的问题:是否有可能将其转化为分类预测解决方案?
我的意思是,假设我们有一个图像或声音作为输入,我们想要输出编码为整数的字符或单词。例如
输入是 x=[0.9,0.8,0.3…]
输出是 y=[0,1…]
这怎么可能?到目前为止,我尝试过将损失从 'mse' 改为 'sparse_categorical_crossentropy',并将最后一个 Dense 层的输出数量从 1 改为 3(假设我想输出两个介于 0 到 2 之间的整数)。但是,损失从未低于 1.0986,模型当然也没有学习任何东西。我也尝试过将输入数字归一化到 0 到 1 的范围,但仍然无效。有什么想法吗?谢谢!
是的,我在这里解释了如何做
https://machinelearning.org.cn/faq/single-faq/how-can-i-change-a-neural-network-from-regression-to-classification
我的博客上也有很多关于序列分类的例子,用于文本(情感分析)和活动识别,这可能会有帮助。
谢谢回复!
我看了您提供的链接,并稍微修改了我的代码。它比以前工作得更好,这次损失确实开始下降了。
在我实验一个我构建的玩具数据集时,我还有两个问题:
1) 时间分布式层(time distributed layer)能否用作某种注意力机制?据我所知,Keras 尚未正式实现注意力机制,但我认为 timedistributed 可以做到。但同样,我也可能错了。
2) 对于多类分类问题,使用独热编码(one-hot encoding)与使用整数有什么实质性区别吗?我自己在实现独热编码时遇到了困难,所以我选择了使用简单的整数来表示类别。我是否应该强制使用独热编码?
再次感谢您的宝贵时间和帮助,并继续保持良好的工作!
干得好!
不,时间分布式允许您在更广泛的模型中使用子模型(自动)。
是的,还没有官方的注意力机制,我认为这简直是疯狂的。如果他们不尽快行动起来,PyTorch 项目将会超越(并杀死)它们。
是的,我记得关于这个主题的经典论文曾谈到独热编码/softmax 会给模型带来更大的灵活性——因此,当类别数量大于 2 时,这是一种最佳实践。也许可以为您的项目同时尝试这两种方法,然后选择效果更好的。
谢谢 Jason 的教程:我认为这是您慷慨的表现!
我第一次开始接触时间序列,并得到了两个主要想法(时间序列方法的不同风格),我想与您核对一下,与“经典”回归/分类相比,经典回归/分类不关心数据的时间顺序。
1) 在单变量(或 1 个特征)的时间序列中,序列的含义(即输入的数量),在一组样本中,与经典回归/分类方法中的特征有直接对应关系,如下所示:
回归/分类中的特征数量 == 时间序列中选择的输入数量。
因此,时间序列中的“特征”一词(在此教程的第一个单变量方法中只有一个)与等效回归/分类方法中的“特征”一词(在此为 3,因为序列有 3 个输入数据)具有不同的值(或含义)。
2) 如果我改变输出序列中的输出数量(我认为您称之为“多步”),这完全等同于多类别分类(例如,使用输出层中相同数量的输出神经元(每个类别 1 个)的方法)。
您是否同意这种第一个“手动”的时间序列与回归/分类方法的等价性?
我不确定我是否理解。
一般来说,如果大多数模型是序列无关的,就像 MLP。在这种情况下,滞后观测值是特征。
有些模型是序列感知的,如 RNN 和 CNN。在这种情况下,滞后观测值被直接处理,并行时间序列是特征。
多步与多类分类不同。但思想是相同的,将输出层更改为具有 n 个节点,每个节点对应一个类别,但使用 softmax 激活。
这有帮助吗?
谢谢您的建议!
我正在总结(就输入输出张量而言)我之前关于 MLP、CNN 模型以及现在 LSTM(RNN 模型)在 TS(时间序列)应用方面的知识,以处理不同的问题。
也就是说,我们使用 MLP/CNN 进行分类问题,例如图像处理(例如 CIFAR-10 多类分类)或多类分类(例如 3 种鸢尾花),或二元分类(例如,皮马糖尿病 y/n),或线性回归(例如,连续波士顿房价)。
我的意思是,我想将输入/输出 ML/DL 模型过程表示为几何“张量”(或最佳 3D 矩阵),以获得模型处理的整体思路。
也就是说,在 CIFAR-10 中,我有一个图像输入(用于训练/验证/测试),其格式为三维矩阵 [样本 -行-, 特征 -列- X, 通道]……因此,特征的含义很清楚(多变量 X 自变量或图像像素),输出矩阵对于 CIFAR-10 也很清楚 [对于每一行中的图像样本,Y 类变量位于列中]。
简而言之,在“皮马”案例中,输入张量是 [768 行的患者样本,8 个特征或 X 自变量],输出张量是 [对于每一行中的样本或患者,糖尿病是/否类别]。
对于鸢尾花 [行中的样本花,4 个花特征或列中的 X],输出是 [行中的样本花,以及列中的 3 种鸢尾花 Y]。在波士顿房价案例中,输入“张量”是 [506 行的房屋样本,13 个特征或列中的 X],输出“张量”是 [对于每一行中的样本或房屋,房屋的连续值或 Y]。
所以,当您谈论 TS(时间序列,不知道是否有人称之为“TS”)时,例如在“每日出生”案例中,在 MLP 模型下的输入张量(例如,在我这里是 7 天的星期几)作为输入时间步,以及 1 个要预测的输出日期标签,我可以在几何上将其视为“TS”的输入张量为 [行中的样本,列中的时间步(例如 7 天)- 在这种情况下,它就像 X -特征-,但它们实际上不是!],输出张量为 [对于每一行中的样本,预测的 Y 日期]。
但是,如果我改用 CNN 模型进行“TS”应用,输入“张量”必须是三维的,即 [行中的样本 -例如我的情况是 52 周-, 列中的时间步 -例如 7 天-, 和 1 个特征],输出张量为 [对于每一行中的样本,列中的预测 Y 或日期]。很容易推断,当我们有多个输出步骤时,在这个“视野”下,列中会有相应的数量的时间步。
为什么我说这么多?答案在这里。因为我们初学者在模型处理过程中很容易在矩阵的维度和形状上迷失,因此我们会犯错误,因为在模型处理过程中矩阵的形状不匹配。更糟糕的是,因为我们迷失了模型处理的整体思路,因为我们无法“几何地”看到输入“张量”和输出“张量”的案例或问题,所以我们很容易迷失,然后我们就无法跟上教师在帖子或教程中介绍的后续思想。
总而言之,我的建议是,在教授这些案例和机器学习模型概念时,尝试从一开始就“可视化”问题,尤其是在问题介绍中,以“输入张量”和“输出张量”的形状和含义来表示……这样,教师在帖子或教程中介绍的后续思想和细微之处就会更容易理解……至少这是我的个人经验。
始终将这些进出 ML/深度学习黑盒的张量可视化……:-))
此致,
JG
感谢分享。
嗨,Jason,
感谢您的这个教程,它看起来非常有帮助!!🙂
对于第二课,这是我写的函数:
(受到 https://machinelearning.org.cn/time-series-prediction-lstm-recurrent-neural-networks-python-keras/ 的严重启发)
祝好,
Steph
干得好!
(我的回答) 第 1 课
我目前正在重读《简单复杂性》(Neil Johnsson),其中一个复杂系统的必要标准是存在某种反馈,某种记忆。
股票市场是一个复杂的系统,不同的参与者进行交互,股票价格是其反映。
因此,就 RNN 而言,时间能力利用先前的作为反馈的数据来创建某种记忆,我认为这是有益的。
就 CNN 而言,我认为“滤波器”是有益的。例如,在技术分析中,有许多模式(=滤波器)用于确定阻力位等。也许也可以使用不同的“良好”模式来检测数据中的异常。在实时应用中(我已经在交易台工作了多年),这对于避免错误可能至关重要。
有趣,谢谢分享。
非常感谢这个精彩的教程。我只是想知道为什么在运行第 5、6 和 7 课时会收到以下错误。您能告诉我如何修复它吗?
使用 TensorFlow 后端。
回溯(最近一次调用)
File “time_series.py”, line 16,
model.add(LSTM(100, activation=’relu’, input_shape=(3, 1)))
File “C:\Users\Volka\Miniconda2\envs\Tensorflow\lib\site-packages\keras\engine\sequential.py”, line 165, in add
layer(x)
File “C:\Users\Volka\Miniconda2\envs\Tensorflow\lib\site-packages\keras\layers\recurrent.py”, line 532, in __call__
return super(RNN, self).__call__(inputs, **kwargs)
File “C:\Users\Volka\Miniconda2\envs\Tensorflow\lib\site-packages\keras\engine\base_layer.py”, line 457, in __call__
output = self.call(inputs, **kwargs)
File “C:\Users\Volka\Miniconda2\envs\Tensorflow\lib\site-packages\keras\layers\recurrent.py”, line 2194, in call
initial_state=initial_state)
File “C:\Users\Volka\Miniconda2\envs\Tensorflow\lib\site-packages\keras\layers\recurrent.py”, line 649, in call
input_length=timesteps)
File “C:\Users\Volka\Miniconda2\envs\Tensorflow\lib\site-packages\keras\backend\tensorflow_backend.py”, line 3011, in rnn
maximum_iterations=input_length)
TypeError: while_loop() 收到意外的关键字参数 ‘maximum_iterations’
您能否确认您的 TensorFlow 和 Keras 版本是最新的?
非常感谢。我更新了 TensorFlow,它奏效了:)
干得好!
更新到多少?
您好!
非常棒的初学者指南,非常有用……
关于 LSTM 方法的快速澄清
为什么我得到的预测值与预期值(例如 80)相比非常低,而任何人都可以轻松预测它……
我是否遗漏了什么!
# 拟合模型
model.fit(X, y, epochs=100, verbose=0)
# 演示预测
x_input = array([50, 60, 70])
x_input = x_input.reshape((1, 3, 1))
print(yhat) — 87.488
当增加 epoch 时,可以看到预测结果比之前有所改善。
epochs=1000 — 82.359
epochs=8000 — 81.217
epochs=10000 — 80.747
epochs=15000 — 82.087
但仍然可以看到 epoch=10000 的预测结果不像预期的那么接近。
请指导。
谢谢。
Guna
通常,LSTM 在时间序列预测方面不是很好,并且需要大量的调优。
也许可以尝试调整您的模型?我在这里有一些想法
https://machinelearning.org.cn/improve-deep-learning-performance/
使用CNN-LSTM模型,您能否解释一下所需的输入形状是从哪里来的?我不明白您为什么会这样做
X = X.reshape((X.shape[0], 2, 2, 1))
您怎么知道的?
好问题,LSTM和CNN的输入形状是3D的,我在下面有更详细的解释
https://machinelearning.org.cn/faq/single-faq/how-do-i-prepare-my-data-for-an-lstm
感谢您的回复。您说LSTM和CNN的输入形状是3D的。但看看这一行
X = X.reshape((X.shape[0], 2, 2, 1))
在我看来是4,我很困惑……
那是因为CNN-LSTM模型,而不是CNN模型。
CNN-LSTM确实有4D输入,因为它在每个样本中读取一系列子序列。更多信息请看这里
https://machinelearning.org.cn/cnn-long-short-term-memory-networks/
感谢Jason提供的精彩教程!
它让我对如何使用深度学习进行时间序列预测有了基本了解。
关于使用CNN/RNN预测时间序列的好处,这是我的一点想法
当卷积运算应用于一维数据(如时间序列)时,
其行为与计算(加权)移动平均相同,
因此CNN可以捕捉系列趋势并获得更平滑的特征,就像MA方法一样(没有线性约束)。
RNN自然是顺序数据模型,可以基于当前输入和先前输入来预测当前输出。
LSTM可以保留很久以前生成的有意义的特征,并继续使用此内存来预测时间序列的当前输出。
LSTM可以保留很久以前生成的有意义的特征,并继续使用此内存来预测时间序列的当前输出。
LSTM可以保留很久以前生成的有意义的特征,并继续使用此内存来预测时间序列的当前输出。
但我认为对于时间序列数据,最近的点对未来点的影��通常比很久以前的点大得多。
因此,LSTM的能力可能不像它适用于其他序列数据(例如NLP)那样适合该领域。
我猜想仅使用LSTM预测时间序列可能会更容易受到数据中随机噪声的影响,因为它可能无法通过平滑来捕捉潜在趋势。
我猜想仅使用LSTM预测时间序列可能会更容易受到数据中随机噪声的影响,因为它可能无法通过平滑来捕捉潜在趋势。
归根结底,我建议测试一套方法并使用效果最好的方法。
嗨
感谢这个迷你课程。
我肯定漏掉了一些要点,但这个迷你课程为什么没有提到RNN(特别是LSTM和GRU),它们显然在序列数据建模和预测中被使用。
我指的是这个课程:https://machinelearning.org.cn/time-series-forecasting-python-mini-course/
这是一个入门课程(例如,线性方法),而不是时间序列深度学习课程。
此外,LSTM在单变量数据上的表现非常差。
是的,有三天专注于LSTM(第5、6和7天)。
也许您应该重新阅读一下帖子?
很好的文章,Jason,
我真的很喜欢关于时间序列数据的文章,我参加了这门课程,并将其应用到一个稍微复杂的问题上,一个Kaggle比赛的商店/商品销售数据集,我对代码做了一些修改,并写了一个内核,如果有人想看看并留下反馈,请查看https://www.kaggle.com/dimitreoliveira/deep-learning-for-time-series-forecasting
干得好!
干得不错。
干得好。
感谢Jason的教程。
我正在使用Matlab处理MLP时间序列数据集。
您能帮我指导一下吗?
抱歉,我没有关于Matlab的教程。
信息丰富的文章,感谢分享。
谢谢,很高兴对您有帮助。
很高兴看到这篇文章,因为我一直在寻找关于时间序列神经网络的资料,并且不确定我构建的模型,因为我不太了解基础知识,所以很高兴能有循序渐进的指导。另外,很高兴能建议在评论中分享答案,因为这很有帮助。在学习这个主题的过程中,我还阅读了您的一些其他帖子,非常感谢您的贡献。
谢谢Drew,希望它有帮助,祝您玩得开心!
Jason,您自己尝试过这些出生数据练习吗?
它们似乎不是一个很好的例子。数据中几乎所有的方差都是随机的。最好的R平方值将是0.10左右,无论您使用什么模型。
是的,我在博客上有一些使用这些数据的教程。
你好,感谢这个迷你课程。
我有一个问题。能否使用CNN-LSTM进行时间序列多步预测?如果答案是肯定的,您的书中是否对此进行了说明?
是的,我在书中提供了一些示例,本教程中也有一个示例。
https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/
感谢您的课程,非常生动!
这是我对第三课的回答
import pandas as pd
import numpy as np
data = pd.read_csv("https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-total-female-births.csv")
columns = 30
rows = data.shape[0] - columns
y = np.zeros((rows,1))
x = np.zeros((rows, columns))
for i in range(rows)
x[i,:] = data['Births'].iloc[i:i+columns]
y[i] = data['Births'].iloc[i+columns]
干得好!
嗨,Jason
感谢您对TSF方法的简化版本,它非常有帮助。您能否为我正在进行的场景提供建议?我有一个TSF问题,我需要预测未来3/4个月的每小时值。我有过去6个月的每小时数据。按照上面的例子,Y(输出)向量的大小将非常大。这该如何简化?
我推荐遵循此框架
https://machinelearning.org.cn/how-to-develop-a-skilful-time-series-forecasting-model/
嗨,Jason,
谢谢你的工作!
我计算了测试数据的mse和方差,并且lstm和cnn-lstm的方差较低,那么用测试集y的均值描述数据的一个恒定的线性函数是否比我们的nn更好?
您有同样的经验吗?
抱歉,我不明白。您具体得到了什么结果?
Jason您好!!
感谢您的课程,非常易于理解和有帮助。我的模型试图通过查看前几天的值来预测特定天的出生人数。为了衡量预测精度,我使用了RMSE,但所有模型的误差都差不多(大约6)。我尝试修改超参数,但没有任何改进。这是因为数据库的随机性吗?
如果在使用一系列模型时,您无法获得比持续性更好的结果,那么可能没有可学习的模式?
也许可以探索其他模型?
也许可以探索其他数据转换?
也许可以探索问题的其他构建方式?
Jason Brownlee您好,感谢您的信息性文章。
我有一个问题。您是否写过关于CNN-LSTM分类器用于时间序列单变量预测的文章?如果有,请分享链接。
是的,我有很多。
或许可以从这里开始的一些简单示例
https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/
您好Jason,感谢您的所有努力和信息丰富的教程。
我想知道您是否有关于多元时间序列分类(非回归)的完整教程。如果有,请分享链接好吗?
我对时间序列预测是新手,我有一个数据集,测量了3个月内大约50个变量。输出是二进制的,要么是1,要么是0(故障或无故障)。
我想预测未来7天是否会发生故障。
我在数据预处理和滑动窗口方面遇到了困难。您能帮帮我吗?
非常感谢,
是的,请看这里的活动识别教程。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
您好Jason,感谢您的回复。
所以我看了教程,但我的担忧是,教程中的数据已经预处理过了。
所以,在我的案例中,我想预测一台机器在未来7天的故障。我每天都有数据记录,用于数千台不同的机器。我有一个单独的文件记录每一天。每个文件包含数千个不同唯一机器的观测值。所以在单个文件中,您找不到同一台机器的多个观测值。然后我有一个标签,说明机器在这天是否发生故障。
所以我的问题是,我是否应该将所有文件连接或绑定在一起,以便例如拥有一个月测量值的数据框?然后对其进行转换?
我的窗口大小是多少?是我需要形状化它的东西吗?还是仅仅是我传递给模型的参数(如n_timesteps和n_features)?
我对窗口大小的概念以及如何确定合适的窗口大小感到非常困惑。您能给我一些建议吗?
非常感谢,
您的问题听起来像是一个时间序列分类任务。
是的,数据必须为您的首选框架做好准备。您可以选择如何准备数据,并编写自定义代码来加载它——例如,数据生成器。
我建议测试不同大小的窗口,尝试按机器学习或跨机器学习等。尝试问题的多种不同构建方式,以发现最适合您特定数据集的方法。
抱歉,我不确定您说的“数据生成器”是什么意思。您能解释一下吗?
非常感谢
当然,这里有更多关于生成器的一般信息
https://wiki.python.org/moin/Generators
我在博客上有一些例子,也许可以看看这里“渐进式加载”下的例子。
https://machinelearning.org.cn/develop-a-deep-learning-caption-generation-model-in-python/
在时间序列工作中,CNN与RNN相比,RNN似乎占有优势。RNN接收数据然后确定一个结果,并继续这样做。然后,它可以改进LSTM,使其能够记住过去发生的事情,并找到跨越时间的模式,从而使其下一次猜测更好。
有效/最好的模型因问题而异。
1. 我认为CNN使用不同滤波器来学习不同因子的方式可以用于时间序列预测,以学习时间序列的各个方面,如季节性、不同时间阶段的模式。
2. 我认为RNN似乎是时间序列的最佳模型,因为它将前一个状态作为输入,这意味着时间序列的当前状态取决于可能为真的先前状态,并且它在每个状态下都接收输入,这表示影响时间序列的各种因素,但我知道它存在梯度爆炸等问题。
干得不错。
Lección 02: 如何转换时间序列数据
import numpy
import pandas
def create_dataset(dataset, ventana)
dataX, dataY = [], []
for i in range(len(dataset)-ventana-1)
a = dataset[i:(i+ventana), 0]
dataX.append(a)
dataY.append(dataset[i + ventana, 0])
return numpy.array(dataX), numpy.array(dataY)
# 加载数据集
dataframe = pandas.read_csv(‘https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-total-female-births.csv’, usecols=[1], engine=’python’)
dataset = dataframe.values
dataset = dataset.astype(‘float32’)
c_dataset = create_dataset (dataset, 5)
print (c_dataset)
干得好!
关于第一课的评论:卷积神经网络可以自动从输入中提取特征,如果我们把多变量输入和二维或三维图像进行类比,它们有能力处理多维输入。对于RNN,它们能够处理噪声和缺失值,学习非线性依赖关系,并且还可以处理多变量输入。
干得好!
第二课的输入准备函数
def prepare_ts_input(ts_data, window)
ts_df = pd.DataFrame(columns = [‘x’, ‘y’])
for i in range(0, ts_data.shape[0]-window, window)
row = [ts_data[i:i+window].values, ts_data[i+window]]
ts_df.loc[len(ts_df)] = row
return ts_df
干得好!
第二课 – 准备输入数据集
def prepare_ts_input(ts_data, window)
ts_df = pd.DataFrame(columns = [‘x’, ‘y’])
for i in range(0, ts_data.shape[0]-window)
row = [ts_data[i:i+window].to_list(), ts_data[i+window]]
ts_df.loc[len(ts_df)] = row
return ts_df
干得漂亮!
我使用了滑动窗口大小=5。我的第二课答案是:42.53852
干得好!
import os
import csv
import pandas as pd
df = pd.read_csv(“https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-total-female-births.csv”)
date=df[“Date”]
births=df[“Births”]
x= births[0:200]
y= births[200]
干得好!
嗨,Jason,
第2课
我比较懒,更喜欢numpy。
我使用了您的超级例程
def series_to_supervised(data, n_in=1, n_out=1, dropnan=True)
# from https://machinelearning.org.cn/convert-time-series-supervised-learning-problem-python/
然后使用.tolist()我的代码
from numpy import genfromtxt
my_data = genfromtxt(‘femtotal.csv’, delimiter=’,’,skip_header=1)
# drop datum
my_data = my_data[:,1]
print(my_data)
print(my_data.shape)
erg = series_to_supervised(my_data.tolist())
print(erg.head())
干得好!
嗨,Jason,
第3课
daily-total-female-birth.csv
Input/Lay1/Lay2/Lay3 epoch 训练 测试 MSE_train MSE_test
3/3/12/1 400 2/3 1/3 50,70 49,98
3/3/8/1 400 2/3 1/3 55,70 49,53
3/12/12/1 400 2/3 1/3 50,29 46,68
3/12/8/1 300 2/3 1/3 55,51 51,72
3/12/8/1 400 2/3 1/3 50,53 50,64
3/12/8/1 500 2/3 1/3 53,04 51,32
我有一个关于MSE重现性的根本性问题。
Keras中是否有一个随机数(没有种子)?
谢谢
Béla
这是可以预期的,请看这个。
https://machinelearning.org.cn/faq/single-faq/why-do-i-get-different-results-each-time-i-run-the-code
第一课
RNN和CNN都可以学习长期模式,因为它们能够使用“内存”状态(RNN)并能通过滤波器(CNN)从短期到长期序列中看到模式。
干得不错。
你好,
你能写下你的电子邮件吗?
我有一些关于LSTM的重要问题。
谢谢你
您随时可以在这里联系我。
https://machinelearning.org.cn/contact/
嗨,Jason,
非常感谢这个很棒的教程。
您是否有关于使用Transformer和注意力机制进行时间序列预测的文章?
谢谢
目前还没有。
第一课评论
RNN或CNN在时间序列中的一个特性是它们对i.i.d假设持中立态度。
显然,它们可以处理相关或独立的观测值,而不会影响模型的性能。
(有趣的是,打破iid违规的ML应用示例……仍然很常见)
干得好。
这是第一课的答案
(1) 循环神经网络(RNN)对于时间序列预测问题很有益,因为它们即使在数据是序列的情况下也能对时间序列数据进行可靠的预测。RNN的行为类似于人脑的运作方式。它们对噪声具有鲁棒性。
(2) CNN——CNN从原始输入数据中学习和自动提取特征的能力可以应用于时间序列预测问题。
干得好!
这是第二课的答案
如何将数据转换为时间序列?您有正确的代码吗?我可以看看吗?
# 加载并汇总数据集
from pandas import read_csv
from sklearn.model_selection import train_test_split
# 加载数据集
url = ‘https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-total-female-births.csv’
df = read_csv(url, header=None)
# 检索数组
data = df.values
# 分割输入和输出元素
X, y = data[:, :1], data[:, 1]
# 总结数据集的形状
print(X)
print(y)
print(X.shape, y.shape)
干得好。
这是第三课的答案
# 单变量 MLP 示例
from numpy import array
from pandas import read_csv
from sklearn.model_selection import train_test_split
来自 keras.models import Sequential
from keras.layers import Dense
# 定义数据集
url = ‘https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-total-female-births.csv’
df = read_csv(url, header=None)
# 检索数组
data = df.values
# 分割输入和输出元素
X, y = data[:, :1], data[:, 1]
# 总结数据集的形状
print(X)
print(y)
print(X.shape, y.shape)
# 拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)
# 总结训练集和测试集的形状
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
X = array([[10, 20, 30], [20, 30, 40], [30, 40, 50], [40, 50, 60]])
y = array([40, 50, 60, 70])
# 定义模型
model = Sequential()
model.add(Dense(100, activation=’relu’, input_dim=3))
model.add(Dense(1))
model.compile(optimizer=’adam’, loss=’mse’)
# 拟合模型
model.fit(X, y, epochs=2000, verbose=0)
# 演示预测
x_input = array([50, 60, 70])
x_input = x_input.reshape((1, 3))
yhat = model.predict(x_input, verbose=0)
print(yhat)
干得好!
第四课
我遇到了以下属性错误:在使用 predict ‘yhat’ 时,“list”对象没有属性“reshape”。我不想包含程序,因为它没有成功运行。正在尝试修复错误。
听到这个消息很遗憾,也许这些提示会有帮助
https://machinelearning.org.cn/faq/single-faq/why-does-the-code-in-the-tutorial-not-work-for-me
我成功修复了错误。这是第四课
# 单变量CNN示例
from numpy import array
from pandas import read_csv
来自 keras.models import Sequential
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers.convolutional import Conv1D
from keras.layers.convolutional import MaxPooling1D
from pandas import read_csv
from sklearn.model_selection import train_test_split
# 加载数据集
url = ‘https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-total-female-births.csv’
df = read_csv(url, header=None)
# 检索数组
data = df.values
# 分割输入和输出元素
X, y = data[:, :1], data[:, 1]
# 总结数据集的形状
print(X.shape, y.shape)
# 拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)
# 总结训练集和测试集的形状
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
# 定义数据集
X = array([[35,32,30], [32,30,31], [30,31,44], [31,44,29]])
y = array([[31,44,29,45]])
# 将单变量序列分成样本
def split_sequence(sequence, n_steps)
X, y = list(), list()
for i in range(len(sequence))
# 找到此模式的末尾
end_ix = i + n_steps
# 检查是否超出了序列
if end_ix > len(sequence)-1
break
# 收集模式的输入和输出部分
seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)
# 定义输入序列
raw_seq = [35, 32, 30, 31, 44, 29, 45, 43, 38]
# 选择时间步数
n_steps = 3
# 分割成样本
X, y = split_sequence(raw_seq, n_steps)
#print(X)
#print(y)
# 从 [样本数, 时间步数] 重塑为 [样本数, 时间步数, 特征数]
X = X.reshape((X.shape[0], X.shape[1], 1))
# 定义模型
model = Sequential()
model.add(Conv1D(filters=64, kernel_size=2, activation=’relu’, input_shape=(3, 1)))
model.add(MaxPooling1D(pool_size=2))
model.add(Flatten())
model.add(Dense(50, activation=’relu’))
model.add(Dense(1))
model.compile(optimizer=’adam’, loss=’mse’)
# 拟合模型
model.fit(X, y, epochs=1000, verbose=0)
# 演示预测
x_input = array([44, 29, 45])
#print(x_input)
x_input = x_input.reshape((1, 3, 1))
yhat = model.predict(x_input, verbose=0)
print(yhat)
这是第五课
# 单变量LSTM示例
from numpy import array
来自 keras.models import Sequential
from pandas import read_csv
from keras.layers import LSTM
from keras.layers import Dense
# 加载数据集
url = ‘https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-total-female-births.csv’
df = read_csv(url, header=None)
# 检索数组
data = df.values
# 分割输入和输出元素
X, y = data[:, :1], data[:, 1]
# 总结数据集的形状
print(X.shape, y.shape)
# 拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)
# 总结训练集和测试集的形状
#print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
# 定义数据集
X = array([X_train])
y = array([y_train])
#X = array([[35,32,30], [32,30,31], [30,31,44], [31,44,29]])
#y = array([[31,44,29,45]])
# 将单变量序列分成样本
def split_sequence(sequence, n_steps)
X, y = list(), list()
for i in range(len(sequence))
# 找到此模式的末尾
end_ix = i + n_steps
# 检查是否超出了序列
if end_ix > len(sequence)-1
break
# 收集模式的输入和输出部分
seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)
# 定义输入序列
raw_seq = [35, 32, 30, 31, 44, 29, 45, 43, 38]
# 选择时间步数
n_steps = 3
# 分割成样本
X, y = split_sequence(raw_seq, n_steps)
#print(X)
#print(y)
# 从 [样本数, 时间步数] 重塑为 [样本数, 时间步数, 特征数]
X = X.reshape((X.shape[0], X.shape[1], 1))
print(X)
# 定义模型
model = Sequential()
model.add(LSTM(50, activation=’relu’, input_shape=(3, 1)))
model.add(Dense(1))
model.compile(optimizer=’adam’, loss=’mse’)
# 拟合模型
model.fit(X, y, epochs=1000, verbose=0)
# 演示预测
x_input = array([44, 29, 45])
#x_input = array([50, 60, 70])
x_input = x_input.reshape((1, 3, 1))
yhat = model.predict(x_input, verbose=0)
print(yhat)
亲爱的 Jason,
我买了您很多书,并且很满意。
目前,我正在研究深度学习,并且正在寻找一本关于如何实现 WEKA 的深度学习的书。
您有什么资料吗?
祝好
Souza
谢谢!
抱歉,我没有关于 Weka 中 DL 的资料。
对于第一课:CNN和RNN都能学习输入到输出的映射函数,这可能对时间序列预测有益。
干得不错。
from pandas import read_csv
第二课,分割数据为X和y的最简单方法。
df = read_csv(‘daily-total-female-births-CA.csv’, header=None)
data = df.values
# 输入输出数据
X, y = data[:, :1], data[:, 1]
X.shape
干得不错。
我正在尝试回答第一课的作业。我找到了这篇论文,其中对时间序列有一个有趣的观点。我指出我认为这就是答案。
学习多个判别性特征
“将卷积应用于输入时间序列的多个滤波器背后的直觉是,学习多个对分类任务有用的判别性特征”
Ismail Fawaz, H., Forestier, G., Weber, J. et al. Deep learning for time series classification: a review. Data Min Knowl Disc 33, 917–963 (2019). https://doi.org/10.1007/s10618-019-00619-1
请原谅我的英语
干得好!
import pandas as pd
import numpy as np
#读取文件
df = pd.read_csv(“daily-total-female-births.csv”)
#获取序列
serie = df[“Births”].values
#滞后是变量“step”
def create_seq(serielista,step)
lista = []
for i in range(0,len(serielista)-step)
lista.append(serielista[i:i+step])
return lista
#创建序列
create_seq(serie,4)
干得好。
第三课:使用 80% 的训练数据和 20% 的测试数据,我得到了 39.07 的误差
来自 keras.models import Sequential
from keras.layers import Dense
# 定义数据集
X = df.loc[:289,0:2]
y = df.loc[:289,3]
X_test = df.loc[289:,0:2]
y_test = df.loc[289:,3]
# 定义模型
model = Sequential()
model.add(Dense(100, activation=’relu’, input_dim=3))
model.add(Dense(1))
model.compile(optimizer=’adam’, loss=’mse’)
# 拟合模型
model.fit(X, y, epochs=2000, verbose=0)
# 演示预测
yhat = model.predict(X_test, verbose=0)
print(yhat)
干得不错。
你好 Jason,我不确定这里是否是提问的合适论坛,但我想就一些问题征求您的建议。我正在处理一个旅游和生活方式呼叫中心的时间序列数据,因为 covid 对这个行业造成了非常严重的影响,现在它又恢复了正常,但 2020 年有些是异常值。我该如何处理这些数据才能使模型的准确性保持良好?
这可能会给你一些想法
https://machinelearning.org.cn/faq/single-faq/how-do-i-model-anomaly-detection
亲爱的Jason
我受到了您的材料和 Kaggle 的启发。对初学者来说是非常好的课程。
第二课,我们首先需要从 URL 下载文件
import requests
path = ‘daily-total-female-births.csv’
link = ‘https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-total-female-births.csv?__s=ot1xapc4zxmlwkxq2v86&utm_source=drip&utm_medium=email&utm_campaign=DLFTSF+Mini-Course&utm_content=Day+2%3A+How+to+Transform+Data+for+Time+Series’
尝试
data = requests.get(link).text
with open(path, ‘w’) as output
output.write(data)
print(‘File downloaded :)’)
except ValueError
print(‘Could not download file !!’)
现在我们可以继续第二课的任务了
import pandas
from numpy import array
path = ‘daily-total-female-births.csv’
#仅加载 daily-total-female-births.csv 文件中索引为 1 的列
dataframe = pandas.read_csv(path, usecols=[‘Births’], engine=’python’)
print(dataframe.head())
dataset = dataframe.values
#将序列分割成样本
def window_creator_1(dataset, shift)
X,y = list(), list()
for i in range(len(dataset))
if (i + shift) < (len(dataset) – 1)
end_ix = i + shift
# 收集模式的输入和输出部分
seq_x, seq_y = dataset[i:end_ix, 0], dataset[end_ix, 0]
X.append(seq_x)
y.append(seq_y)
return array(X), array(y)
print(window_creator_1(dataset, 4))
干得好!
第三课
我受到了您的文章的启发🙂
import pandas
import numpy
import keras
import matplotlib.pyplot as plt
来自 keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from sklearn.preprocessing import MinMaxScaler
print(keras.__version__)
path = ‘daily-total-female-births.csv’
#仅加载 daily-total-female-births.csv 文件中索引为 1 的列
dataframe = pandas.read_csv(path, usecols=[‘Births’], engine=’python’)
print(dataframe.head())
#获取数据集中的值并返回 numpy 数组
dataset = dataframe.values
dataset = dataset.astype(‘float32’)
# 规范化数据集
scaler = MinMaxScaler(feature_range=(0, 1))
数据集 = scaler.fit_transform(数据集)
# 拆分为训练集和测试集
train_size = int(len(dataset) * 0.8)
test_size = len(dataset) – train_size
train, test = dataset[0:train_size], dataset[train_size:len(dataset)]
#将序列分割成样本
def window_creator(dataset, shift)
X, y = list(), list()
for i in range(len(dataset))
if (i + shift) < (len(dataset) – 1)
end_ix = i + shift
seq_x, seq_y = dataset[i:end_ix, 0], dataset[end_ix, 0]
X.append(seq_x)
y.append(seq_y)
return numpy.array(X), numpy.array(y)
# 重塑为 X=t 和 Y=t+1
shift = 8
trainX, trainY = window_creator(train, shift)
testX, testY = window_creator(test, shift)
print('trainX.shape ',trainX.shape)
print('trainY.shape ',trainY.shape)
print('testX.shape ',testX.shape)
print('testY.shape ',testY.shape)
# 定义模型
model = Sequential()
model.add(Dense(64,activation = 'relu', input_shape=(trainX.shape[1],)))
model.add(Dropout(0.2))
model.add(Dense(64,activation = 'relu'))
model.add(Dropout(0.2))
model.add(Dense(64,activation = 'relu'))
model.add(Dropout(0.2))
model.add(Dense(64,activation = 'relu'))
model.add(Dropout(0.2))
model.add(Dense(1))
model.compile(optimizer='rmsprop', loss='mse', metrics=['mae'])
model.summary()
model.fit(trainX, trainY, epochs=300, batch_size=16, verbose=0)
test_loss, test_acc = model.evaluate(testX, testY)
print("Test loss: %.2f%%" % (test_loss*100))
print("Test accuracy: %.2f%%" % (test_acc*100))
# 进行预测
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)
# 反转预测
trainPredict = scaler.inverse_transform(trainPredict)
trainY = scaler.inverse_transform([trainY])
testPredict = scaler.inverse_transform(testPredict)
testY = scaler.inverse_transform([testY])
# 移动测试预测以进行绘图
testPredictPlot = numpy.empty_like(dataset)
testPredictPlot[:, :] = numpy.nan
testPredictPlot[len(trainPredict)+(shift*2)+1:len(dataset)-1, :] = testPredict
# 绘制基线和预测
plt.plot(scaler.inverse_transform(dataset))
plt.plot(testPredictPlot)
plt.show()
# 比较预测值与实际值
import colored
import math
j = 0
test = scaler.inverse_transform(dataset)
test = test.astype(int)
print('=' * 85)
for i in range(len(testPredictPlot))
predict = testPredictPlot[i,0]
x = float(str(predict))
is_nan = math.isnan(x)
if is_nan is False
if test[i, 0] != predict.astype(int)
print(colored.fg("black") + str(i+1) + '|',test[i, 0],'|', predict.astype(int),'|')
print('-' * 85)
else
print(colored.fg("red") + str(i+1) + '|',test[i, 0], '|', predict.astype(int),'|')
print(colored.fg("black") + '-' * 85)
j+=1
print(colored.fg("green") + '100% accurate predictions: ',j)
干得好!
第四课
import pandas
import numpy
import keras
import matplotlib.pyplot as plt
来自 keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Conv1D
from keras.layers.convolutional import MaxPooling1D
from sklearn.preprocessing import MinMaxScaler
print(keras.__version__)
path = ‘daily-total-female-births.csv’
#仅加载 daily-total-female-births.csv 文件中索引为 1 的列
dataframe = pandas.read_csv(path, usecols=[‘Births’], engine=’python’)
print(dataframe.head())
#获取数据集中的值并返回 numpy 数组
dataset = dataframe.values
dataset = dataset.astype(‘float32’)
# 规范化数据集
scaler = MinMaxScaler(feature_range=(0, 1))
数据集 = scaler.fit_transform(数据集)
# 拆分为训练集和测试集
train_size = int(len(dataset) * 0.8)
test_size = len(dataset) – train_size
train, test = dataset[0:train_size], dataset[train_size:len(dataset)]
#将序列分割成样本
def window_creator(dataset, shift)
X, y = list(), list()
for i in range(len(dataset))
if (i + shift) < (len(dataset) – 1)
end_ix = i + shift
seq_x, seq_y = dataset[i:end_ix, 0], dataset[end_ix, 0]
X.append(seq_x)
y.append(seq_y)
return numpy.array(X), numpy.array(y)
# 重塑为 X=t 和 Y=t+1
shift = 8
trainX, trainY = window_creator(train, shift)
testX, testY = window_creator(test, shift)
print('trainX.shape ',trainX.shape)
print('trainY.shape ',trainY.shape)
print('testX.shape ',testX.shape)
print('testY.shape ',testY.shape)
# 从 [样本数, 时间步数] 重塑为 [样本数, 时间步数, 特征数]
trainX = trainX.reshape(trainX.shape[0], trainX.shape[1], 1)
testX = testX.reshape(testX.shape[0], testX.shape[1], 1)
print('trainX.shape ',trainX.shape)
print('testX.shape ',testX.shape)
# 定义模型
model = Sequential()
model.add(Conv1D(filters=64, kernel_size=7, activation='relu', padding = 'same', input_shape=(trainX.shape[1], trainX.shape[2])))
model.add(Conv1D(filters=64, kernel_size=3, padding = 'same', activation='relu'))
model.add(Conv1D(filters=64, kernel_size=2, activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(Flatten())
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse', metrics=['mae'])
model.summary()
history = model.fit(trainX, trainY, epochs=300, batch_size=4, verbose=1)
test_loss, test_mae = model.evaluate(testX, testY)
print("Test loss: %.2f%%" % (test_loss*100))
print("Test mae: %.2f%%" % (test_mae*100))
# 进行预测
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)
# 反转预测
trainPredict = scaler.inverse_transform(trainPredict)
trainY = scaler.inverse_transform([trainY])
testPredict = scaler.inverse_transform(testPredict)
testY = scaler.inverse_transform([testY])
# 移动测试预测以进行绘图
testPredictPlot = numpy.empty_like(dataset)
testPredictPlot[:, :] = numpy.nan
testPredictPlot[len(trainPredict)+(shift*2)+1:len(dataset)-1, :] = testPredict
# 绘制基线和预测
plt.plot(scaler.inverse_transform(dataset))
plt.plot(testPredictPlot)
plt.show()
# 比较预测值与实际值
import colored
import math
j = 0
test = scaler.inverse_transform(dataset)
test = test.astype(int)
print('=' * 85)
for i in range(len(testPredictPlot))
predict = testPredictPlot[i,0]
x = float(str(predict))
is_nan = math.isnan(x)
if is_nan is False
if test[i, 0] != predict.astype(int)
print(colored.fg("black") + str(i+1) + '|',test[i, 0],'|', predict.astype(int),'|')
print('-' * 85)
else
print(colored.fg("red") + str(i+1) + '|',test[i, 0], '|', predict.astype(int),'|')
print(colored.fg("black") + '-' * 85)
j+=1
print(colored.fg("green") + '100% accurate predictions: ',j)
干得好!
你好,
感谢这个迷你课程。我认为 CNN 和 RNN 在时间序列预测中的能力是“自动检测特征”。
是的
第五课
这次我使用了 keras 包中的 TimeseriesGenerator🙂
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import keras
from keras.preprocessing.sequence import TimeseriesGenerator
来自 keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from sklearn.preprocessing import MinMaxScaler
print(keras.__version__)
path = ‘daily-total-female-births.csv’
#仅加载 daily-total-female-births.csv 文件中索引为 1 的列
dataframe = pd.read_csv(path, usecols=[‘Births’], engine=’python’)
print(dataframe.head())
#获取数据集中的值并返回 numpy 数组
dataset = dataframe.values
dataset = dataset.astype(‘float32’)
# 规范化数据集
scaler = MinMaxScaler(feature_range=(0, 1))
数据集 = scaler.fit_transform(数据集)
# 拆分为训练集和测试集
train_size = int(len(dataset) * 0.8)
test_size = len(dataset) – train_size
train, test = dataset[0:train_size], dataset[train_size:len(dataset)]
shift = 12
n_features = 1
train_generator = TimeseriesGenerator(train, train, length=shift, batch_size=1)
# 样本数
print(‘Samples train: %d’ % len(train_generator))
test_generator = TimeseriesGenerator(test, test, length=shift, batch_size=1)
# 样本数
print(‘Samples test: %d’ % len(test_generator))
model=Sequential()
model.add(LSTM(128,activation=’relu’,input_shape=(shift,n_features),return_sequences=True))
model.add(LSTM(64,activation=’relu’,return_sequences=True))
model.add(LSTM(64,activation=’relu’,return_sequences=True))
model.add(LSTM(16,activation=’relu’))
model.add(Dense(1))
model.compile(optimizer=’adam’, loss=’mse’, metrics=[‘mae’])
model.summary()
history = model.fit(train_generator, epochs = 200, batch_size=4, verbose=1)
test_loss, test_mae = model.evaluate(test_generator)
print(“Test loss: %.2f%%” % (test_loss*100))
print(“Test mae: %.2f%%” % (test_mae*100))
# 进行预测
trainPredict = model.predict(train_generator)
print(trainPredict.shape)
testPredict = model.predict(test_generator)
print(testPredict.shape)
# 反转预测。
trainPredict = scaler.inverse_transform(trainPredict)
testPredict = scaler.inverse_transform(testPredict)
# 移动测试预测以进行绘图
testPredictPlot = np.empty_like(dataset)
testPredictPlot[:, :] = np.nan
testPredictPlot[len(trainPredict)+(shift*2):len(dataset), :] = testPredict
# 绘制基线和预测
plt.plot(scaler.inverse_transform(dataset))
plt.plot(testPredictPlot)
plt.show()
# 比较预测值与实际值
import colored
import math
j = 0
test = scaler.inverse_transform(dataset)
test = test.astype(int)
print(‘=’ * 85)
for i in range(len(testPredictPlot))
predict = testPredictPlot[i,0]
x = float(str(predict))
is_nan = math.isnan(x)
if is_nan is False
if test[i, 0] != predict.astype(int)
print(colored.fg(“black”) + str(i+1) + ‘|’,test[i, 0],’|’, predict.astype(int),’|’)
print(‘-‘ * 85)
else
print(colored.fg(“red”) + str(i+1) + ‘|’,test[i, 0], ‘|’, predict.astype(int),’|’)
print(colored.fg(“black”) + ‘-‘ * 85)
j+=1
print(colored.fg(“green”) + ‘100% accurate predictions: ‘,j)
干得好!
第六课
import pandas
import numpy
import keras
import matplotlib.pyplot as plt
来自 keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers import TimeDistributed
from keras.layers.convolutional import Conv1D
from keras.layers.convolutional import MaxPooling1D
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
print(keras.__version__)
path = ‘daily-total-female-births.csv’
#仅加载 daily-total-female-births.csv 文件中索引为 1 的列
dataframe = pandas.read_csv(path, engine=’python’)
print(dataframe.head())
# 绘制数据框
ax = plt.gca()
dataframe.plot(kind=’line’,x=’Date’,y=’Births’,ax=ax)
# plt.xticks(rotation=’vertical’)
plt.setp(ax.get_xticklabels(), rotation=45)
plt.grid()
plt.show()
#获取数据集中的值并返回 numpy 数组
dataset = dataframe[‘Births’].values
dataset = dataset.reshape(-1,1)
dataset = dataset.astype(‘float32’)
print(dataset.shape)
# 规范化数据集
scaler = MinMaxScaler(feature_range=(0, 1))
数据集 = scaler.fit_transform(数据集)
# 拆分为训练集和测试集
train_size = int(len(dataset) * 0.8)
test_size = len(dataset) – train_size
train, test = dataset[0:train_size], dataset[train_size:len(dataset)]
#将序列分割成样本
def window_creator(dataset, shift)
X, y = list(), list()
for i in range(len(dataset))
if (i + shift) < (len(dataset) – 1)
end_ix = i + shift
seq_x, seq_y = dataset[i:end_ix, 0], dataset[end_ix, 0]
X.append(seq_x)
y.append(seq_y)
return numpy.array(X), numpy.array(y)
# 重塑为 X=t 和 Y=t+1
shift = 4
trainX, trainY = window_creator(train, shift)
testX, testY = window_creator(test, shift)
print('trainX.shape ',trainX.shape)
print('trainY.shape ',trainY.shape)
print('testX.shape ',testX.shape)
print('testY.shape ',testY.shape)
# 从[样本数, 时间步数]重塑为[样本数, 子序列数, 时间步数, 特征数]
sub_seq = shift//2
time_steps = shift//2
trainX = trainX.reshape(trainX.shape[0], sub_seq, time_steps, 1)
testX = testX.reshape(testX.shape[0], sub_seq, time_steps, 1)
print('trainX.shape ',trainX.shape)
print('testX.shape ',testX.shape)
# 定义模型
model = Sequential()
model.add(TimeDistributed(Conv1D(filters=64, kernel_size=1, activation='relu'), input_shape=(None, trainX.shape[2], trainX.shape[3])))
model.add(TimeDistributed(Conv1D(filters=64, kernel_size=1, activation='relu')))
model.add(TimeDistributed(MaxPooling1D(pool_size=2)))
model.add(TimeDistributed(Flatten()))
model.add(LSTM(64, activation='relu', return_sequences=True))
model.add(LSTM(64, activation='relu'))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse', metrics=['mae'])
model.summary()
# 拟合模型
model.fit(trainX, trainY, epochs=1000, batch_size=16, verbose=0)
test_loss, test_mae = model.evaluate(testX, testY)
print("Test loss: %.2f%%" % (test_loss*100))
print("Test mae: %.2f%%" % (test_mae*100))
# 进行预测
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)
# 反转预测
trainPredict = scaler.inverse_transform(trainPredict)
# print(trainPredict)
trainY = scaler.inverse_transform([trainY])
testPredict = scaler.inverse_transform(testPredict)
testY = scaler.inverse_transform([testY])
# 移动训练预测以进行绘图
trainPredictPlot = numpy.empty_like(dataset)
trainPredictPlot[:, :] = numpy.nan
trainPredictPlot[shift:len(trainPredict)+shift, :] = trainPredict
# 移动测试预测以进行绘图
testPredictPlot = numpy.empty_like(dataset)
testPredictPlot[:, :] = numpy.nan
testPredictPlot[len(trainPredict)+(shift*2)+1:len(dataset)-1, :] = testPredict
# 绘制基线和预测
plt.figure(figsize=(15, 6))
plt.plot(scaler.inverse_transform(dataset),alpha = 0.5, color = 'green', label = 'Dataset')
plt.plot(trainPredictPlot, label = 'Train predictions', color = 'k', linestyle = '–')
plt.plot(testPredictPlot, label = 'Test predictions', color = 'r', linestyle = '–')
plt.legend()
plt.grid()
plt.show()
import math
# 计算均方根误差
trainScore = math.sqrt(mean_squared_error(trainY[0], trainPredict[:,0]))
print('Train Score: %.2f RMSE' % (trainScore))
testScore = math.sqrt(mean_squared_error(testY[0], testPredict[:,0]))
print('Test Score: %.2f RMSE' % (testScore))
# 比较预测值与实际值
import colored
j = 0
test = scaler.inverse_transform(dataset)
test = test.astype(int)
print('=' * 85)
for i in range(len(testPredictPlot))
predict = testPredictPlot[i,0]
x = float(str(predict))
is_nan = math.isnan(x)
if is_nan is False
if test[i, 0] != predict.astype(int)
print(colored.fg("black") + str(i+1) + '|',test[i, 0],'|', predict.astype(int),'|')
print('-' * 85)
else
print(colored.fg("red") + str(i+1) + '|',test[i, 0], '|', predict.astype(int),'|')
print(colored.fg("black") + '-' * 85)
j+=1
print(colored.fg("green") + '100% accurate predictions: ',j)
干得好!
嗨,Jason,
非常感谢您对复杂算法(MLP、CNN、LSTM 等)进行清晰、精确且易于理解的解释。我想了解“Adam 版本的随机梯度下降”。如果可以解释一下,我将非常感激。
看这里
https://machinelearning.org.cn/adam-optimization-algorithm-for-deep-learning/
还有这个。
https://machinelearning.org.cn/adam-optimization-from-scratch/
嗨 Jason
第二课
导入库并读取数据
import pandas as pd
import numpy as np
import datetime as dt
import plotly.express as px
csv_to_read = ‘./Data/daily-total-female-births.csv’
df = pd.read_csv(csv_to_read, engine=’python’)
df.set_index(‘Date’, inplace=True)
探索数据
df.head(5)
df.describe()
px.line(df, title=’Number of daily births’)
#每日出生人数变动很大(平均每天+/-16%),所以线性方法很难提供良好的准确性……
### 月度趋势
df[‘month’] = df.Date.astype(np.datetime64).dt.month
month_gr = df.groupby([‘month’]).Births.sum()
px.line(month_gr)
#有一个月度趋势,在9月达到高峰,所以我们应该将月份纳入模型以考虑长期变化
### 周内变化
df[‘dayofweek’] = df.Date.astype(np.datetime64).dt.dayofweek
week_gr = df.groupby([‘dayofweek’]).Births.sum()
px.line(week_gr)
#我们可以看到,周末的出生人数比工作日少 10-15%。
#这可能是由于周末某些产科医生的可用性有限
#所以我们应该将工作日纳入模型以考虑每周的微小变化
输入组件
# 时间滞后
# 使用滞后和移动平均
# 我希望使输入更加灵活,以便将来进行特征数量、时间窗口等实验。
def shift(series, i)
return series.shift(i)
def rolling(series, i)
return series.rolling(i).mean().shift(1)
def add_lags(df, cols, n_lags, func, ranged=True)
#df – 包含时间序列的数据框
#cols – 要创建滞后的一个或多个列
#n_lags – 滞后的天数
#func – 滞后函数(shift 或某种平均)
#ranged – 如果为 True,则添加从 t-1 到 t-n_lags 的多个滞后。如果为 False,则只添加一个 t-n_lags
if type(cols) == str
cols = [cols]
elif type(cols) != list
cols = [str(cols)]
for col in cols
col_prefix = col+’_’+ func.__name__ + ‘_’
if ranged
for i in range(1, n_lags+1)
col_name = col_prefix + str(i)
df[col_name] = func(df[col], i)
else
col_name = col_prefix + str(n_lags)
df[col_name] = func(df[col], n_lags)
return df
df = add_lags(df, ‘Births’, 4, shift, ranged=True)
df = add_lags(df, ‘Births’, 4, rolling, ranged=False)
df.dropna(inplace=True)
#所有转换后 df 的外观如下:
df.head(4)
Date Births month dayofweek Births_shift_1 Births_shift_2 Births_shift_3 Births_shift_4 Births_rolling_4
4 1959-01-05 44 1 0 31.0 30.0 32.0 35.0 32.00
5 1959-01-06 29 1 1 44.0 31.0 30.0 32.0 34.25
6 1959-01-07 45 1 2 29.0 44.0 31.0 30.0 33.50
7 1959-01-08 43 1 3 45.0 29.0 44.0 31.0 37.25
学习格式转换
df.set_index(‘Date’, inplace=True)
y = df.Births.values
X = df[df.columns[1:]].values
X
array([[ 1. , 0. , 31. , …, 32. , 35. , 32. ],
[ 1. , 1. , 44. , …, 30. , 32. , 34.25],
[ 1. , 2. , 29. , …, 31. , 30. , 33.5 ],
……,
[12. , 1. , 52. , …, 34. , 44. , 41.75],
[12. , 2. , 48. , …, 37. , 34. , 42.75],
[12. , 3. , 55. , …, 52. , 37. , 48. ]])
干得好!
Jason,
感谢精彩的教程(第二课),我尝试读取了 CSV 文件(Date,Birth)。对于监督学习,也许我们可以删除日期。
现在为了查看季节性,我们至少应该有月份。在印度,月份很重要,因为大多数婚礼安排在 11 月至 1 月季度。
而且我才刚开始接触这个领域几天。
我听说过基于 Transformer 的模型而不是 RNN。Pytorch Forecasting 也取得了很大进展。
请指教。
如果您对 PyTorch forecasting 感兴趣,可以看看 Facebook 的 Prophet 库。
我读了您的文章。感谢分享您的想法。
谢谢。很高兴知道您喜欢它。
#Lesson2
import pandas as pd
data = pd.read_csv(“daily-total-female-births.csv”)
X=[]
Y=[]
result=[]
for i in range(len(data)-3)
X.append(list(data[“Births”][i:i+3]))
Y.append(int(data[“Births”][i+3]))
result=pd.concat([pd.Series(X,name=’X’),pd.Series(Y,name=’Y’)],axis=1)
嗨,Jason,
非常感谢您的教程。我还在第三课,但我看到的是预测值的方差远低于测试集的方差。这正常吗?有什么解释吗?
测试集
253 34
254 40
255 56
256 44
257 53
.. ..
357 37
358 52
359 48
360 55
361 50
ytest.var()
Out[100]
0 52.808189
dtype: float64
预测
253 44.808697
254 40.148918
255 39.204170
256 41.366394
257 44.755791
.. …
357 42.322884
358 40.063240
359 42.569584
360 44.440350
361 43.073093
yhat.var()
Out[101]
0 3.443268
dtype: float32
此致
是的,正常。因为样本外预测很难,而且预计会不那么准确。
谢谢你的回答。我可以看到 MLP 和 CNN 都会发生这种情况。
MLP
https://ibb.co/r3n4qbC
CNN
https://ibb.co/pL3WPHZ
此致
顺便问一下,我该如何添加图表?我该如何以如此漂亮的方式插入代码?
matplotlib?
我的意思是,我该如何在这里的评论中添加图表和代码(而不是纯文本)。
代码可以使用“pre” HTML 标签。至于图表,我认为您需要将它上传到其他地方,然后使用“img” HTML。
再次感谢 Adrian!
嗨!
关于第03课,我仍然不明白为什么我们需要重塑 X。我尝试了两种方法,结果非常相似。
此致
我不这么认为。我看到 Keras 会抱怨形状不匹配,如果跳过重塑的话。
谢谢 Adrian,但请看这个
如果我运行上面的代码 10 次,我会得到这个
然后,我进行了以下修改
如果我运行上面的代码 10 次,包括这些修改,我会得到这个
此致
区别不是很大。我认为这只是代码中的一些随机因素造成的。
Digisol Hub 是一家先进的技术公司,我们可以帮助您解决网站开发、社交媒体营销、应用程序(Apps)开发、平面设计、Google Ads 和软件开发方面的问题。我们的目标是通过使用正确的策略帮助人们解决数字营销方面的问题,并让他们感到自己的价值,从而促进他们的在线业务发展。
Digisol Hub
你好,
在实践中,我们在进行预测时,何时应该使用深度学习而不是传统的时序分析?在我看来,深度学习只适用于“大数据”。这是因为 (1) 样本量 T 很大,还是 (2) 特征(或解释变量 X)数量很多,或者是两者兼而有之?谢谢!!
如果我错了,请纠正我,但我无法想象对于 T=100 这样的样本量,使用深度学习相对于传统时序模型能带来多大的优势。
嗨,Jason,
感谢您的 ML 课程,它们非常有帮助。
我尝试下载“深度学习在时间序列中的应用 7 天速成班”,但在点击按钮并输入我的电子邮件地址后,发送并不成功(发送的旋转符号一直旋转,但没有收到电子邮件)。
“深度学习在时间序列中的应用?
立即参加我的免费 7 天电子邮件速成班(附带示例代码)。”
你能修复发送链接吗?
谢谢你
你好 Ye…你是否在浏览器中为以下网站启用了弹出窗口?
https://machinelearning.org.cn/how-to-get-started-with-deep-learning-for-time-series-forecasting-7-day-mini-course/
您也可以尝试使用其他浏览器。
谢谢 James。我尝试了另一个浏览器,结果也一样。现在我点击了您在回复中提供的链接,它要求我输入电子邮件,然后告诉我几分钟内会收到一封电子邮件。所以您提供的链接有效。再次感谢。
抱歉,又是我。邮件中收到的速成班是关于计算机视觉的,而不是时间序列。您能否修复链接以发送“时间序列速成班”或将“时间序列速成班”发送给我?谢谢。
在 sklearn 中,对于深度学习,我们是否有像 forecast() 这样的函数?
你好 Praveen…以下内容可能对您有帮助
https://machinelearning.org.cn/make-predictions-scikit-learn/
您的帖子非常有帮助,非常感谢分享!
感谢您的反馈和支持 Dudu!我们非常感激!
第01课
这与 RNN 和 CNN 如何帮助人们进行时间序列预测有关。
RNN
当通常需要过去数据来做出未来预测时,RNN 是有效的。RNN 通过考虑过去值来为未来做出决策的特性,使其成为时间序列预测的良好选择。
CNN
CNN 有许多变体,其中之一是一维 CNN (1D CNN)。在这种 CNN 中,卷积核沿一个方向移动,并使用卷积运算从时间序列数据中提取有意义的特征。这类网络的优点是计算成本较低,并且可以轻松地从原始数据中学习特征,从而消除了手动特征工程的需要。
感谢 Muhammad 的反馈!继续加油!
第1课
CNN 在图像识别方面非常出色,因为它们能够识别特定特征。此属性也可以应用于时间序列数据,其中过滤器在 1D CNN 层中沿时间步滑动以捕获局部模式。数据也可以重塑为 2D CNN,时间步作为行,特征作为列。在此上下文中,CNN 可以应用于多元时间序列数据。与基于图像的数据类似,特征图可以进行池化以专注于最重要特征,从而实现准确预测。
RNN 和 LSTM 网络自然适合用于时间序列,因为它们是为顺序数据设计的。它们在需要长期依赖性的情况下特别有效。
我期待学习如何将这两种架构结合起来以实现尽可能准确的预测。
非常感谢!
第2课
# 加载模块
import numpy as np
import pandas as pd
# 读取表格
df = pd.read_csv(‘birth_rates.csv’)
# 函数
def prep_4_time_series (df, element_history=3)
# 定义用于保存特征向量(时间窗口)的列表
X = list()
# 定义用于保存响应变量(窗口之后的下一个)的空列表
y = list()
# 提取有序的出生人数列表
df = df.sort_values(‘Date’)
births = list(df[‘Births’])
# 循环的初始值
min_el = element_history
# 提取滑动窗口和响应变量
while min_el >= element_history
min_el = np.min([els2include,len(births)])
if len(births) >= (els2include+1)
y.append(births[els2include])
a = births[:min_el]
X.append(a)
births = births[1:]
else
break
# 返回 X 和 y
return X, y
# 调用函数
X, y = prep_4_time_series (df)
我们得到一个以 3 个元素为特征的移动窗口,以第 4 个元素为目标,这样我们就可以遍历所有后续日期。
谢谢!
CNN 捕获特征和局部模式,这对于短期预测和趋势可能很重要。例如,数据的波动或突然变化。
而 RNN 捕获序列依赖关系和长期模式。允许它们保留过去观测的记忆。例如,股票价格预测或自然语言应用(其中词语的位置决定了情感)。
你好 Yonas…CNN 在时间序列分类和预测方面也非常出色!
以下资源是一个很好的入门介绍
https://keras.org.cn/examples/timeseries/timeseries_classification_from_scratch/