Keras LSTM 索引顺序(升序或降序)并在二进制分类中查看附加到 1 的字符串

Keras LSTM index order (ascending or decending) and seeing string attached to 1 in binary classification

在做 LSTM 时,日期时间索引应该升序还是降序?我的意思是数据集的头部应该是 2014 年,尾部是 2020 年还是相反?我问这个的原因是因为LSTM的回溯期,恐怕如果排序不正确,那么它会看到错误的时间范围。

我在执行 print(df) 时的当前时间范围索引如下所示:

2014-21-3 XYZ
2014-22-3 XYZ
2014-23-3 XYZ

为了让 LSTM 能够“工作”,是否应该改成这个顺序?

2014-23-3 XYZ
2014-22-3 XYZ
2014-21-3 XYZ

此外,当我加载一个数据集时,该数据集的二进制响应变量在两个字符串“Up”和“Down”之间波动。 在做 keras 模型时,它会输出 1 值的概率,但是我怎么知道哪个字符串是 1,哪个是 0?

此外,如果答案是 predict_classification,那么很抱歉,这不是我在这里要找的(请注意,因为我已经看到与该答案类似的问题)。

future/present靠的是过去而不是相反。进行当前预测的 LSTM 单元将使用过去的记忆。因此,日期应按升序排列。

第 2 部分:

因为你有两个可能的标签 UpDown,你将不得不放置一个大小为 1 的线性层(或最后一层大小为 1 的多层神经网络)在 LSTM 的输出上。您可以将 Up 编码为 class 1,将 Down 编码为 class 0。当您训练模型时,每个时间步将产生一个预测并基于它的值您可以将其解释为 1 (UP) 或 0(Down)

样本:

import numpy as np

from keras.models import Sequential
from keras.layers import LSTM, Dense, TimeDistributed
from keras.layers import LSTM

model = Sequential()
model.add(LSTM(8, input_shape = (10, 1), return_sequences = True))
model.add(TimeDistributed(Dense(1))) 
model.compile(loss='mean_squared_error', optimizer='adam')

# 4 samples each of 10 timesteps with 1 feature each
X = np.random.randn(4,10,1) 
# Each timestep has a label 1 for UP and 0 for down
y = np.random.randint(0,2, size=(4,10, 1))

model.fit(X, y, epochs=2)
print (model.predict(X).shape)

输出:

Epoch 1/2
4/4 [==============================] - 0s 76ms/step - loss: 0.4758
Epoch 2/2
4/4 [==============================] - 0s 2ms/step - loss: 0.4704
(4, 10, 1)

如您所见,预测的大小为 4 X 10 X 1 即对于每个样本的每个时间步,它预测它属于 class 1 的概率。如果您想预测 class直接用

model.predict_classes(X)

你必须使用递增顺序...

2014-21-3 XYZ
2014-22-3 XYZ
2014-23-3 XYZ

编辑(如何解释概率)

你可以将 Up 编码为 class 1,将 Down 编码为 class 0

label = ['up','down','up','up','down']

map_label = {'up':1,'down':0}

[map_label[l] for l in label]
# ===> [1, 0, 1, 1, 0]

关于如何解释 class化问题的输出,您有两种选择。这取决于您选择的激活输出(sigmoid 或 softmax)

S 形激活函数用于生成二进制 class化问题的概率。在这种情况下,模型输出一个概率数组,其形状等于要预测的样本的长度。我们可以检索预测的 class 只需检查概率得分...如果它高于 0.5(这是一种常见的做法,但您也可以根据需要更改它)样本属于 class 1否则它属于 class 0。如果是 sigmoid,你的最后一个输出层必须是 Dense(1, activation='sigmoid')

n_sample = 10
timestemp = 5
n_features = 3
X = np.random.uniform(0,1, (n_sample, timestemp, n_features))
y = np.random.randint(0,2, n_sample)

inp = Input((timestemp,n_features))
x = LSTM(8, activation='relu')(inp)
out = Dense(1, activation='sigmoid')(x)

model = Model(inp, out)
model.compile('adam', 'binary_crossentropy')
model.fit(X,y, epochs=3)

preds = model.predict(X) # (n_samples, 1)
y_classes = ((preds > 0.5)+0).ravel() # Up == 1 and Down == 0

在 softmax 的情况下,使用 argmax 检索预测的 class 并且您的最后一个输出层必须是 Dense(n_classes, activation='softmax')

n_sample = 10
timestemp = 5
n_features = 3
X = np.random.uniform(0,1, (n_sample, timestemp, n_features))
y = np.random.randint(0,2, n_sample)

inp = Input((timestemp,n_features))
x = LSTM(8, activation='relu')(inp)
out = Dense(2, activation='softmax')(x)

model = Model(inp, out)
model.compile('adam', 'sparse_categorical_crossentropy')
model.fit(X,y, epochs=3)

preds = model.predict(X) # (n_samples, n_class)
y_classes = np.argmax(preds , axis=1)  # Up == 1 and Down == 0

我随时待命