如何为 LSTM 重塑数据 - 时间序列多类分类

Posted

技术标签:

【中文标题】如何为 LSTM 重塑数据 - 时间序列多类分类【英文标题】:How to reshape data for LSTM - Time series multi class classification 【发布时间】:2021-09-23 01:11:01 【问题描述】:

我正在使用 ASHRAE RP-1043 冷水机多传感器数据集进行时间序列分类,该数据集针对每个冷水机故障和正常情况有 65 列和 3000 多行。而且我使用过 LSTM,我不确定我在这里使用的数据结构是否适合时间序列分类。下面是我从收集的数据集中创建的数据框的图像,其中包含多个冷水机组条件的记录(7 个故障和正常)。每条记录都标有相关的类(条件)。并从不同的文件构建数据集,服务于故障条件和正常条件。

火车数据形状如下 X_train.shape,y_train.shape

((81600, 65), (81600, 8))

但是对于 LSTM 输入需要是 3D 的。所以改造成如下。 (只有 1 个时间步长) # 使其成为 3d 输入 X_train = X_train.reshape(-1,1,65) X_train.shape,y_train.shape`

((81600, 1, 65), (81600, 8))

def create_nn_model():
  model = Sequential()
  model.add(LSTM(100, dropout=0.2, input_shape=(X_train.shape[1],
  X_train.shape[2]),return_sequences=True))
  model.add(Dense(100, activation='relu'))
  model.add(Dense(8,activation='softmax'))
  model.compile(loss='categorical_crossentropy',
                optimizer='adam', metrics=['accuracy'])
  return model

这适用于我的模型,我可以毫无错误地适应。

但是我怎样才能增加 X_train 的时间步数(100 个时间步)

scaled_x_train.reshape(-1,100,65) X_train.shape,y_train.shape

((816, 100, 65), (81600, 8))

现在 X_train 已经过改造。但由于 X_train 和 y_train 的大小不同,我无法适应这个。我曾尝试以与 X_train 相同的方式重塑 y_train,但随后我将不得不返回序列,这不是我的要求。我的数据集结构(102000 行 65 列)有什么问题吗?我可以直接拆分上图中显示的数据以进行训练和测试,还是需要进行更多操作。感谢任何帮助

P.S 与 Priya 的回答有关

【问题讨论】:

即使在返回序列后,您也可以执行最后一个时间步,例如,如果您有 @Priya 感谢您的回复。但是我的数据框结构是否正确?我有点怀疑 我认为你的 DataFrame 很好,所有的冷水机分别分为故障和正常两类,但是在读入模型时,你需要继承一个 Dataset 类并使用 __getitem__(index) 并采取一次只能采集一台特定冷水机组的数据样本。如果您使用 pytorch 或 MXNet,这将很容易。 该数据集仅属于一台冷水机,有七种故障类型和正常状态。并且有8个类标签。我觉得这应该是一个多类分类 我在下面添加了一个答案。 【参考方案1】:

即使在返回序列后,您也可以执行最后一个时间步,就像您有

num_categories=10
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32, return_sequences=True))
tf.keras.layers.Dense(num_categories)
tf.keras.layers.Dense(1)
ypred = model.predict(x_test)

# Final layer shape after predict would be
# ypred.shape = (Num_samples, 100, 10)
# taking last time step
ypred = ypred[:,-1,:]  # will be of shape (Num_samples, 10)

# Prediction classes
ypred_classes = np.argmax(ypred,axis = -1)

【讨论】:

你能解释一下我们在哪里设置软最大损失函数 如果你有两个以上的类要分类,那么设置 softmax 激活,比如 tf.keras.layers.Dense(num_classes, activation="softmax") 或者你可以设置 loss=keras.losses.SparseCategoricalCrossEntropy (from_logits=True) 在 model.compile() 方法中。 我已经用带有 LSTM 层代码的模型更新了我的问题。你能看看吗 我已经将我的 X 和 Y 重新调整为具有 10 个时间步长,因此批次号不会有所不同,并且当在 [2,2 ,2,2,2,2,2,2,2,2] 如果我们有 10 个时间步长整形输出。所以我可以将最后一个时间步隐藏状态值作为传递的时间序列序列的预测值吗? 是的,没错。对不起,代码中的错字,step_size=time_steps。【参考方案2】:

你不能直接改成这样:

scaled_x_train.reshape(-1,100,65) X_train.shape,y_train.shape

当 timesteps=1 时这不会出错,因为 x_train.shape = (num_samples,time_steps,num_features) 中的 num_samples 不会改变。由于 dim=1 可以在任何轴上创建。

但是当time_steps>1num_samples=len(dataset)-time_steps.

假设最后一列是您的目标变量,我将包含一个为 Lstm 模型创建输入数据的代码 sn-p。我认为您的模型代码的其余部分都很好。

import numpy as np 

# FUNCTION TO CREATE 1D DATA INTO TIME SERIES DATASET
def new_dataset(dataset, time_steps):
    data_X, data_Y = [], []
    for i in range(len(dataset)-time_steps):
        a = dataset[i:(i+time_steps), :-1]
        data_X.append(a)
        data_Y.append(dataset[i + time_steps, -1])
    return np.array(data_X), np.array(data_Y)

【讨论】:

得到一个错误提示 step_size 没有定义 抱歉打错了,step_size=time_steps 这就是我想要的。即使由于从数据集长度中减去时间步长,我们将丢失数据中的最后一个时间步长记录,但这使我们能够将数据集分组为包含定义的时间步长数量和该批次的类标签的批次。非常感谢你;) 实际上,我们不会丢失数据中的任何记录,因为data=dataset[i:i+time_steps] 行将覆盖整个数据范围。假设我们有 100 条数据记录,time_steps=10,那么“i”值的范围是(0-89),所以(i+time_steps)=89+10=99……这意味着我们的最后一条记录……无论如何很高兴它帮助了你! 我认为代码有问题。附加到 X 时数据已重复。请检查【参考方案3】:

我认为您错过了 RNN 或 LSTM 的基本工作原理。这不是数据重复……这是 RNN 的工作方式。

我这里举个简单的例子,假设我们的数据由三个特征和一个目标组成。

Temperature humidity pressure   target(binary, whether it will rain or not)
    
    63        89       29.8       1
    88        21.2     40.5       0
    72        90.3     48.7       1
    45        23.2     67.2       0
    90        10.8     32.6       0

然后假设我们希望我们的模型回顾3 timesteps 以了解我们数据中的模式。因此,我们构建输入数据的方式是将 3 个时间步组合在一起。

# 0,1,2 index
[63, 89, 29.8,       Target data:
 88, 21.2, 40.5,     # datapoint at 3rd index in target
 72, 90.3, 48.7]     [0]

# 1,2,3 index
[88, 21.2, 40.5,     # datapoint at 4th index in target
 72, 90.3, 48.7       [0]
 45, 23.2, 67.2]

 # 2,3,4 index       # model should predict datapoint at 5th index in target
[72, 90.3, 48.7
 45, 23.2, 67.2       
 90, 10.8, 37.6]

所以现在输入数据shape=(3,3,3) 请在实施之前阅读有关 RNN 的文档,否则会很混乱。

【讨论】:

您好,我查看了许多教程,但找不到与您在此处提到的重复时间步长值相关的任何学习材料。如果可能的话,你能不能提一下。非常感谢 当然。这里有一个很棒的博客colah.github.io/posts/2015-08-Understanding-LSTMs 非常感谢。我会查的。但是我遇到的另一个问题是我已经重塑了我当前的数据框(如在此处发布的第一张图片中)在一个批次中没有按时间步长重复的值? (我已经重塑了 X_train 和 Y_train)。这有什么问题吗? cCurrenlty 我正在获取 2D 数组的最后一个值作为输出。 不,没有错,这意味着您的 time_steps=1。如果 time_steps=1,网络只会回顾过去一个 time_step 并预测下一个值。您可以尝试使用不同的 time_steps 值并检查模型的工作方式。 但是我将我的 X_train 重塑(调用 pandas reshape 函数)形状为 (816, 100, 65),这意味着 816 个批次,每批次包含 100 个时间步长(我的数据集中有 100 条记录)和 65 列。这是否意味着我的模型没有经过训练可以回顾 100 个时间步?

以上是关于如何为 LSTM 重塑数据 - 时间序列多类分类的主要内容,如果未能解决你的问题,请参考以下文章

如何为 LSTM 实现 Keras 自定义损失函数

如何为 LSTM keras 重塑 X_train 和 y_train

如何为多对一二元分类 LSTM 准备数据?

使用 LSTM Keras 的序列数据进行多类分类不起作用

如何使用 lstm 执行多类多输出分类

如何处理极长的 LSTM 序列长度?