python - LSTM 预处理 : Build 3d arrays from pandas data frame based on ID

标签 python pandas numpy keras lstm

我是 keras 机器学习的新手,我计划进行一项机器学习实验,该实验基于具有 lstm 层的递归神经网络预测在视频游戏比赛中购买的前十件商品的序列。

假设给出了一个按gameIdsidetimestamp 预先排序的示例表:

       gameId   side   timestamp  itemId 
   3030038208    100        4260    1055 
   3030038208    100        4648    2010 
   3030038208    100        5036    3340 
   3030038208    100      291561    1001 
   3030038208    100      295807    1083 
   3030038208    100      296457    2010 
   3030038208    200        3257    1055 
   3030038208    200        3516    2003 
   3030038208    200        3775    3340 
   3030038208    200      321461    1038 
   3030038208    200      321818    2003 
   3030038208    200      321979    2003 
   3030038208    200      491099    3006 
   3030038208    200      492238    1042 
   3030038208    200      743864    3086 
   3030038208    200      744773    1043
         ....

我现在想将数据框 reshape 为两个(x 和 y)3d numpy 数组,其中第三维描述购买序列的长度 (ItemId) - 这样基本上每个结果序列中的 2d numpy 数组构成相同 gameIdside

的表

在训练神经网络之前,我还需要插入一个填充,因为上面提到的时间序列为 10。在此示例中,填充值为 0 似乎没问题,但在实际情况中,我使用的是稀疏包含大量 0 值的矩阵。

下面是一些问题:

1) 是否有任何内置函数可用于 numpy、pandas 甚至 keras 以有效实现我的既定目标。我想不出不让我花很多时间想出一个合理的预处理函数的东西。

2) 还有其他需要注意的事项吗?特别是在填充的情况下。在处理稀疏矩阵时填写“-999”不是更有意义吗?

3) 假设模型看起来像那样

model = Sequential()
model.add(LSTM(128, dropout=0.2, recurrent_dropout=0.2, input_dim=1))
model.add(Dense(y.shape[1], activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
monitor = EarlyStopping(monitor='val_loss', min_delta=1e-3, patience=5, verbose=0, mode='auto')
checkpointer = ModelCheckpoint(filepath=filepath + "best_weights.hdf5", verbose=0, save_best_only=True)

与:

history = model.fit(x_train, y_train, epochs=2, validation_split=0.33, callbacks=[monitor, checkpointer], verbose=0).history

我如何才能正确使用处理填充的掩蔽层?

提前感谢您花在该线程上的任何时间!

编辑: 根据要求,这里是我想得到的结果 numpy 数组,以便根据 timestamp 和带有 lstm 层的神经网络预测 itemId keras 填充前:

y = [
[1055, 2010, 3340, 1001, 1083, 2010],
[1055, 2003, 3340, 1038, 2003, 2003, 3006, 1042, 3086, 1043],
...
]

x = [
[[4260], [4648], [5036], [291561], [295807], [296457]],
[[3257], [3516], [3775], [321461], [321818], [321979], [491099], [492238], [743864], [744773] ],
...
]

之后填充:

y = [
[1055, 2010, 3340, 1001, 1083, 2010, 0, 0, 0, 0],
[1055, 2003, 3340, 1038, 2003, 2003, 3006, 1042, 3086, 1043],
...
]

x = [
[[4260], [4648], [5036], [291561], [295807], [296457], [0], [0], [0], [0]],
[[3257], [3516], [3775], [321461], [321818], [321979], [491099], [492238], [743864], [744773] ],
...
]

但是,在实际示例中,除了时间戳之外,还有更多的功能。

最佳答案

您可以通过几个步骤从 pandas groupby 对象中提取数据来实现这一点。在前两步中,我们将创建 groupby 对象,以便稍后在代码中对其进行操作。从 groupby 对象中,我们将找到最大的组,以便我们可以相应地用零填充

gb = df.groupby(['gameId','side']) # Create Groupby object
mx = gb['side'].size().max() # Find the largest group

创建 x 和 y 的步骤非常相似。我们可以使用列表理解来遍历每个组,将数据帧转换为 numpy 数组并使用 np.pad() 填充零.然后将每个数组 reshape 为 3d

x = np.array([np.pad(frame['timestamp'].values,
                     pad_width=(0,mx-len(frame)),
                     mode='constant',
                     constant_values=0) 
                     for _,frame in gb]).reshape(-1,mx,1)

y = np.array([np.pad(frame['itemId'].values,
                     pad_width=(0,mx-len(frame)),
                     mode='constant',
                     constant_values=0) 
                     for _,frame in gb]).reshape(-1,mx,1)

在此示例中,设置用于多对多 lstm。在评论中我曾指出您当前的设置不支持 3d 输出值,因为在 lstm 层中您没有参数 return_sequence=True .

不清楚你在这个问题中寻找的是哪种结构。在决定使用哪个 LSTM 网络时,我喜欢引用下图。假设您添加 return_sequence=True,上面的代码将支持多对多网络。到你的 LSTM 层。如果您想要多对一,请删除 .reshape(-1,mx,1)来自 y,现在你有一个网络 mx输出。

enter image description here


无论哪种设置,您都需要修改 input_shape你的模型的论点。此参数必须指定 x 的第 2 和第 3 维的形状,即

                                                        # v Use input_shape here
model.add(LSTM(128, dropout=0.2, recurrent_dropout=0.2, input_shape=x.shape[1:]))

关于python - LSTM 预处理 : Build 3d arrays from pandas data frame based on ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49803503/

相关文章:

python - 这些 transient 模型的 ID 发生了什么?

python - 无法在 Scrapy 中获取所有 http 请求

pandas - 通过在 Pandas 中调用袖扣来改变身材大小

python - 将一列中的数据分成三列

python - 多索引情况下每个索引的列总和

python - 如何将长字符串的 numpy 数组转换为仅包含一个元素的列表

python - 我需要编写一个 Python 脚本来对图片进行排序,我该怎么做?

python - Django:表单创建时出现表单验证错误

python - Pandas - 在整数轴上按位置正确索引,在另一个轴上按标签正确索引(以避免链式分配)

python - 如何获取二进制掩码的位置真实位