使用Keras理解多元时间序列分类

fel*_*lix 5 python machine-learning time-series lstm keras

我试图了解如何正确地将数据输入到我的keras模型中,以使用LSTM神经网络将多元时间序列数据分为三类。

我已经查看了不同的资源-主要是Jason Brownlee发表的这三篇优秀的博客文章post1post2post3),其他SO 问题和不同的论文,但是那里提供的信息都不完全适合我的问题情况,因此我无法弄清楚如果我的数据预处理/输入到模型中的数据是正确的,那么我想如果在这里指定确切的条件可能会得到一些帮助。

我正在尝试对多元时间序列数据进行分类,其原始形式的结构如下:

  • 我有200个样本

  • 一个示例是一个csv文件。

  • 一个样本可以具有1到50个功能(即,csv文件具有1到50列)。

  • 每个功能的值在固定的时间步长上被“跟踪”,比如说100(即,每个csv文件恰好有100行)。

  • 每个csv文件都有以下三个类之一(“好”,“太小”,“太大”)

因此,我的当前状态如下:

我有一个具有以下结构的numpy数组“样本”

# array holding all samples
[
    # sample 1        
    [
        # feature 1 of sample 1 
        [ 0.1, 0.2, 0.3, 0.2, 0.3, 0.1, 0.2, 0.4, 0.5, 0.1, ... ], # "time series" of feature 1
        # feature 2 of sample 1 
        [ 0.5, 0.6, 0.7, 0.6, 0.4, 0.3, 0.2, 0.1, -0.1, -0.2, ... ], # "time series" of feature 2
        ... # up to 50 features
    ],
    # sample 2        
    [
        # feature 1 of sample 2 
        [ 0.1, 0.2, 0.3, 0.2, 0.3, 0.1, 0.2, 0.4, 0.5, 0.1, ... ], # "time series" of feature 1
        # feature 2 of sample 2 
        [ 0.5, 0.6, 0.7, 0.6, 0.4, 0.3, 0.2, 0.1, -0.1, -0.2, ... ], # "time series" of feature 2
        ...  # up to 50 features
    ],
    ... # up to sample no. 200
]
Run Code Online (Sandbox Code Playgroud)

我也有一个numpy数组“ labels”,其长度与“ samples”数组(即200)相同。标签以以下方式编码:

  • “好” = 0
  • “太小” = 1
  • “太大” = 2
[0, 2, 2, 1, 0, 1, 2, 0, 0, 0, 1, 2, ... ] # up to label no. 200
Run Code Online (Sandbox Code Playgroud)

然后,使用“ keras” 函数对该“标签”数组进行编码to_categorical

to_categorical(labels, len(np.unique(labels)))
Run Code Online (Sandbox Code Playgroud)

我的模型定义当前如下所示:

max_nb_features = 50
nb_time_steps = 100

model = Sequential()
model.add(LSTM(5, input_shape=(max_nb_features, nb_time_steps)))
model.add(Dense(3, activation='softmax'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
Run Code Online (Sandbox Code Playgroud)
  • 现在仅随机选择LSTM层中的5个单元
  • 在我的三个班级的密集层中输出3个神经元

然后,我将数据分为训练/测试数据:

samples_train, samples_test, labels_train, labels_test = train_test_split(samples, labels, test_size=0.33)
Run Code Online (Sandbox Code Playgroud)

剩下的134个样本用于培训,66个样本用于测试。

我当前遇到的问题是以下代码无法正常工作:

model.fit(samples_train, labels_train, epochs=1, batch_size=1)
Run Code Online (Sandbox Code Playgroud)

错误如下:

Traceback (most recent call last):
  File "lstm_test.py", line 152, in <module>
    model.fit(samples_train, labels_train, epochs=1, batch_size=1)
  File "C:\Program Files\Python36\lib\site-packages\keras\models.py", line 1002, in fit
    validation_steps=validation_steps)
  File "C:\Program Files\Python36\lib\site-packages\keras\engine\training.py", line 1630, in fit
    batch_size=batch_size)
  File "C:\Program Files\Python36\lib\site-packages\keras\engine\training.py", line 1476, in _standardize_user_data
    exception_prefix='input')
  File "C:\Program Files\Python36\lib\site-packages\keras\engine\training.py", line 113, in _standardize_input_data
    'with shape ' + str(data_shape))

ValueError: Error when checking input: expected lstm_1_input to have 3 dimensions, but got array with shape (134, 1)
Run Code Online (Sandbox Code Playgroud)

对我来说,这似乎不起作用,因为我的示例可能具有可变数量的功能。如果我使用“伪”(生成的)数据,其中所有参数都相同,除了每个样本具有完全相同的特征量(50个),代码就可以工作。

现在我想了解的是:

  1. 我对LSTM输入数据结构的一般假设是否正确?参数(batch_sizeinput_shape)是否正确/合理?
  2. 一般而言,keras LSTM模型是否能够处理具有不同特征量的样本?
  3. 如果是,我该如何调整我的代码以使其能够使用不同数量的功能?
  4. 如果否,则对特征少于50个的样本列进行“零填充”(填充)工作吗?还有其他实现我目标的首选方法吗?

小智 2

我相信 Keras 的输入形状应该是:

input_shape =(样本数,nb_time_steps,max_nb_features)。

最常见的是 nb_time_steps = 1

PS:我尝试为实习职位解决一个非常相似的问题(但结果证明是错误的)。你可以看看这里: https: //github.com/AbbasHub/Deep_Learning_LSTM/blob/master/2018-09-22_Multivariate_LSTM.ipynb(看看你是否能发现我的错误!)