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

时间:2018-09-18 14:27:24

标签: python machine-learning keras time-series lstm

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

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

我要做的是对多元时间序列数据进行分类,其原始形式如下:

  • 我有200个样本

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

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

  • 每个功能的值在固定时间内被“跟踪” 比方说100个步骤(即每个csv文件正好有100行)。

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

所以我的当前状态如下:

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

# 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
]

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

  • “好” = 0
  • “太小” = 1
  • “太大” = 2
[0, 2, 2, 1, 0, 1, 2, 0, 0, 0, 1, 2, ... ] # up to label no. 200

然后使用keras的to_categorical函数对这个“ labels” 数组进行编码

to_categorical(labels, len(np.unique(labels)))

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

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'])
  • 现在仅随机选择LSTM层中的5个单元
  • 我的三个班级的致密层中有3个输出神经元

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

samples_train, samples_test, labels_train, labels_test = train_test_split(samples, labels, test_size=0.33)

这留下了134个用于训练的样本和66个用于测试的样本。

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

model.fit(samples_train, labels_train, epochs=1, batch_size=1)

错误如下:

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)

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

现在我要了解的是:

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

2 个答案:

答案 0 :(得分:0)

我相信Keras的输入形状应为:

input_shape =(样本数,nb_time_steps,max_nb_features)

通常nb_time_steps = 1

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

答案 1 :(得分:0)

LSTM模型需要以[样本,时间步长,特征]形式的3D输入

定义LSTM模型的第一层时,我们只需要指定时间 步骤功能。即使看起来像是2D,实际上还是3D,因为样本的大小,即在模型拟合时指定了批量大小。

features = x_train_d.shape[1]

因此,我们首先需要以3D格式重塑输入内容:

x_train_d = np.reshape(x_train_d, (x_train_d.shape[0], 1, x_train_d.shape[1]))

这是LSTM第一层:

model.add(LSTM(5,input_shape=(1, features),activation='relu'))

并且模型拟合指定LSTM期望的样本 = 50

model.fit(x_train_d,y_train_d.values,batch_size=50,epochs=100)

对于使用可变长度输入的问题,在https://datascience.stackexchange.com/questions/26366/training-an-rnn-with-examples-of-different-lengths-in-keras处进行了讨论