如何从 pandas 数据帧在 tensorflow v1 中实现 LSTM

Posted

技术标签:

【中文标题】如何从 pandas 数据帧在 tensorflow v1 中实现 LSTM【英文标题】:How to implement LSTM in tensorflow v1 from pandas dataframe 【发布时间】:2021-11-16 22:41:36 【问题描述】:

我已经尝试按照教程来实现这一点,但我一直在 LSTM 层上遇到尺寸错误。

ValueError: 层 LSTM 的输入 0 与层不兼容:预期 ndim=3,发现 ndim=2。收到的完整形状:[无,2]

import random
import numpy as np
import tensorflow as tf
from tensorflow import feature_column as fc
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, DenseFeatures, Reshape
from sklearn.model_selection import train_test_split

def df_to_dataset(features, target, batch_size=32):
    return tf.data.Dataset.from_tensor_slices((dict(features), target)).batch(batch_size)

# Reset randomization seeds
np.random.seed(0)
tf.random.set_random_seed(0)
random.seed(0)

# Assume 'frame' to be a dataframe with 3 columns: 'optimal_long_log_return', 'optimal_short_log_return' (independent variables) and 'equilibrium_log_return' (dependent variable)
X = frame[['optimal_long_log_return', 'optimal_short_log_return']][:-1]
Y = frame['equilibrium_log_return'].shift(-1)[:-1]
X_train, _X, y_train, _y = train_test_split(X, Y, test_size=0.5, shuffle=False, random_state=1)
X_validation, X_test, y_validation, y_test = train_test_split(_X, _y, test_size=0.5, shuffle=False, random_state=1)

train = df_to_dataset(X_train, y_train)
validation = df_to_dataset(X_validation, y_validation)
test = df_to_dataset(X_test, y_test)

feature_columns = [fc.numeric_column('optimal_long_log_return'), fc.numeric_column('optimal_short_log_return')]

model = Sequential()
model.add(DenseFeatures(feature_columns, name='Metadata'))
model.add(LSTM(256, name='LSTM'))
model.add(Dense(1, name='Output'))
model.compile(loss='logcosh', metrics=['mean_absolute_percentage_error'], optimizer='Adam')
model.fit(train, epochs=10, validation_data=validation, verbose=1)
loss, accuracy = model.evaluate(test, verbose=0)
print(f'Target Error: accuracy%')

在其他地方看到此问题后,我尝试设置input_shape=(None, *X_train.shape)input_shape=X_train.shape,均无效。我还尝试在 LSTM 层之前插入一个 Reshape 层 model.add(Reshape(X_train.shape)),它解决了这个问题,但我又遇到了另一个问题:

InvalidArgumentError:reshape 的输入是一个有 64 个值的张量,但请求的形状有 8000 个

...我什至不确定添加 Reshape 图层是否正在做我认为它正在做的事情。毕竟,为什么将数据重塑为自己的形状可以解决问题呢?我的数据发生了一些我无法理解的事情。

另外,我将它用于时间序列分析(股票收益),所以我认为 LSTM 模型应该是有状态的和临时的。在转换为张量之前,我是否需要将时间戳索引移动到熊猫数据库中自己的列中?

不幸的是,我有义务使用 tensorflow v1.15,因为这是在 QuantConnect 平台上开发的,他们可能不会很快更新库。

编辑:我通过使用 TimeseriesGenerator 取得了一些进展,但现在我收到以下错误(在 Google 上没有返回任何结果):

KeyError: '未找到映射或原始键的键。映射键:[];原始密钥:[]'

下面的代码(我确定我错误地使用了 input_shape 参数):

train = TimeseriesGenerator(X_train, y_train, 1, batch_size=batch_size)
validation = TimeseriesGenerator(X_validation, y_validation, 1, batch_size=batch_size)
test = TimeseriesGenerator(X_test, y_test, 1, batch_size=batch_size)

model = Sequential(name='Expected Equilibrium Log Return')
model.add(LSTM(256, name='LSTM', stateful=True, batch_input_shape=(1, batch_size, X_train.shape[1]), input_shape=(1, X_train.shape[1])))
model.add(Dense(1, name='Output'))
model.compile(loss='logcosh', metrics=['mean_absolute_percentage_error'], optimizer='Adam', sample_weight_mode='temporal')
print(model.summary())
model.fit_generator(train, epochs=10, validation_data=validation, verbose=1)
loss, accuracy = model.evaluate_generator(test, verbose=0)
print(f'Model Accuracy: accuracy')

【问题讨论】:

【参考方案1】:

事实证明,这个特定问题与 Quantconnect 为 pandas 数据帧制作的补丁有关,该补丁干扰了旧版本的 tensorflow/keras。

【讨论】:

以上是关于如何从 pandas 数据帧在 tensorflow v1 中实现 LSTM的主要内容,如果未能解决你的问题,请参考以下文章

IP网中,IP分组到达目的网路后,如何转换为MAC帧在LAN中传输

Pandas - 在groupby之后将列转换为新行

Python pandas 绘制带间隙的时间序列

Apache Spark 数据帧在写入镶木地板时不会重新分区

获取每个android.hardware.camera2帧在surfacetexture上显示之前的数据

如何将数据从 mongodb 导入到 pandas?