我是keras机器学习的新手,我计划进行机器学习实验,预测基于具有lstm层的递归神经网络在视频游戏匹配中购买的前十个项目的序列。
假设提供了按gameId
,side
和timestamp
预先排序的示例表:
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
....
我现在想将数据帧重新整形为两个(x和y)3d numpy数组,其中第三个维度描述了购买序列的长度(ItemId
) - 这样基本上每个2d numpy数组在结果序列中构成了相同gameId
,side
对
在训练神经网络之前,我还需要插入一个填充,因为上面提到的时间序列是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数组(我想)我想得到的是基于itemId
基于timestamp
预测带有lstm图层的神经网络在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] ],
...
]
但是,在实际示例中,除了时间戳之外,还有更多功能。
答案 0 :(得分:4)
通过从pandas groupby对象中提取数据,您可以通过几个步骤实现此目的。在前两个步骤中,我们将创建groupby对象,以便我们稍后可以在代码中对其进行操作。从groupby对象中,我们将找到最大的组,以便我们可以相应地填充零
gb = df.groupby(['gameId','side']) # Create Groupby object
mx = gb['side'].size().max() # Find the largest group
创建x&的步骤你非常相似。我们可以使用列表推导来遍历每个组,将数据帧转换为numpy数组,并使用np.pad()
使用零填充。然后将每个数组重塑为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图层,上面的代码将支持多对多网络。如果您想要多对一,请从y中删除.reshape(-1,mx,1)
,现在您的网络输出为mx
。
对于任一设置,您需要修改模型的input_shape
参数。该参数必须指定x的第二和第三维的形状,即
# v Use input_shape here
model.add(LSTM(128, dropout=0.2, recurrent_dropout=0.2, input_shape=x.shape[1:]))