python - 使用 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)
解决方案
我也有同样的情况。我想从原始日志数据中进行用户级别的预测。实际上,我不知道正确的解决方案,但我已经掌握了一些技巧。
我认为你的情况很好。首先,您必须将 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, :]
如果您找到了更好的解决方案,请不要犹豫,与我们分享:-)
推荐阅读
- sql - SQL 计数和连接
- ios - 添加 tabBarController、iOS、Swift 后导航消失
- javafx - 如何将侦听器附加到两个仅在两者都更改时触发一次的属性?
- c# - 使用 XSD.exe 的多个版本 C# 类/XSD
- python - 如何将子菜单项添加到 wxPython 中的弹出菜单项?
- amazon-web-services - 如何限制 AWS 自动缩放以不允许使用特定角色?
- laravel - (VueJS, Axios) 捕获错误的不同方法
- java - 单调法
- javascript - 文件系统访问 API createWritable() 方法在控制台中有效,但在脚本中无效
- mysql - 如何从具有旋转 IP 地址的 EC2 实例访问 Amazon RDS 上的 MySQL?