首页 > 解决方案 > 使用 Keras Python 塑造 LSTM 模型的输入

问题描述

我们正在使用 kaggle 数据集:https ://www.kaggle.com/heesoo37/120-years-of-olympic-history-athletes-and-results/version/2 。它拥有120年奥运会的数据。我们的目标是在前一届奥运会的数据上训练我们的模型,并根据训练好的模型预测下一届奥运会可能获得的国家奖牌。我们使用属性:年龄、性别、身高、体重、NOC(国家)、运动、事件来预测我们的输出等级(金牌、银牌、铜牌)。我们希望使用 LSTM 基于前几年的数据而不是 120 年的整个数据集进行预测。

但是我们在使用 LSTM 时面临的主要挑战是如何塑造 LSTM 的输入。LSTM 的时间步长和样本大小应该是多少?应如何对数据进行分组以将其提供给 LSTM。对于每个国家,我们都有对应于每年奥运会和所有运动组合的可变行数。

我们在这一步上停留了几天。

如果有人可以就输入应该如何馈送到 LSTM 提供见解,那就太好了。

我们编写了这样的代码:

def lstm_classifier(final_data):

country_count = len(final_data['NOC'].unique())
year_count = len(final_data['Year'].unique())

values = final_data.values
final_X = values[:, :-1]
final_Y = values[:, -1] 
print(country_count, ' ', year_count)

# reshape - # countries, time series, # attributes
#final_X = final_X.reshape(country_count, year_count, final_X.shape[1])
final_X = final_X.groupby("Country", as_index=True)['Year', 'Sex', 'Age', 'Height', 'Weight', 'NOC', 'Host_Country', 'Sport'].apply(lambda x: x.values.tolist())
final_Y = final_Y.groupby("Country", as_index=True)['Medal' ].apply(lambda x: x.values.tolist())

# define model - 10 hidden nodes
model = Sequential()
model.add(LSTM(10, input_shape = (country_count, final_X.shape[1])))
model.add(Dense(4, activation = 'sigmoid'))
model.compile(optimizer = 'adam', loss = 'mean_squared_error', metrics = ['accuracy'])

# fit network
history = model.fit(final_X, final_Y, epochs = 10, batch_size = 50)

loss, accuracy = model.evaluate(final_X, final_Y)
print(accuracy)

标签: pythonkerastime-serieslstmrnn

解决方案


我也有同样的情况。我想从原始日志数据中进行用户级别的预测。实际上,我不知道正确的解决方案,但我已经掌握了一些技巧。

我认为你的情况很好。首先,您必须将 2D 数据转换为 3D,就像 Jason Brownlee 所做的那样 点击这里

另一个很好的例子 点击这里

他们使用这种方法:

Keras LSTM 层需要一个 3 维(样本、时间步、特征)的 numpy 数组形状的输入,其中样本是训练序列的数量,时间步是回溯窗口或序列长度,特征是特征的数量在每个时间步的每个序列。

# function to reshape features into (samples, time steps, features) 
def gen_sequence(id_df, seq_length, seq_cols):
    """ Only sequences that meet the window-length are considered, no padding is used. This means for testing
    we need to drop those which are below the window-length. An alternative would be to pad sequences so that
    we can use shorter ones """
    data_array = id_df[seq_cols].values
    num_elements = data_array.shape[0]
    for start, stop in zip(range(0, num_elements-seq_length), range(seq_length, num_elements)):
        yield data_array[start:stop, :]

如果您找到了更好的解决方案,请不要犹豫,与我们分享:-)


推荐阅读