我尝试将LSTM模型用于下一个篮子推荐。我想应用与本文相同的方法:A Dynamic Recurrent Model for Next Basket Recommendation
在我的情况下,我有一些用户,他们在不同时间购买一些商品。 所以我设计了我的X数据,如:
user ID timestep sequence items
user1 1 array(1, 20)
user1 2 ...
user2 1 ...
user2 2 ...
user2 3 ...
user3 1 ...
user3 1 ...
序列项表示具有形状(1,20)的数组。这些向量是在每个序列期间购买的每个项目(使用word2vec生成)的平均表示。
然后我将我的标签设计为:
user ID label
user1 np.array(1, 6000)
user2 ...
user3 ...
标签用户表示每个用户的下一个订单,在他们过去的订单之后表示X数据。此外,标签是[1 0 1 0 0 0 .. 1]等向量,其中1表示用户购买了该项目,否则为0.
因此,我想使用LSTM训练每个用户的过去序列以预测下一个购买序列。 下面,我定义了一个LSTM模型,我没有返回序列,因为我有一个用户标签。
model_rnn = Sequential()
model_rnn.add(LSTM(20, return_sequences=False, input_shape=(None, 20)))
model_rnn.add(Dropout(0.2))
model_rnn.add(Dense(nb_classes))
model_rnn.add(Activation("sigmoid"))
model_rnn.compile(loss='binary_crossentropy', optimizer="Adagrad")
n_index = X.index.values
n_sample = int(len(X.index.values)*0.7)
user_index = np.random.choice(n_index, n_sample, replace=False)
n_epochs = 10
for _ in range(n_epochs):
for index in user_index:
X_train = X.ix[index, "sequence_items"]
X_train.reshape(1, X_train.shape[0], X_train.shape[1])
y_train = y[index, :].toarray()
model_rnn.fit(X_train, y_train, batch_size=1, epochs=1, shuffle=1)
如您所见,我使用batch_size = 1训练LSTM,因为用户之间的时间步长不同。 我在70%的用户身上安装了该模型,并在其余部分测试了该模型。
我的结果非常差,模型为每个用户测试推荐的前n项非常相似。例如,对于特定用户,模型会推荐从未出现在旧序列中的项目。虽然规范,它必须预测最后序列比较的项目,因此,它应该预测过去购买的项目的高概率。
显然,我的方法似乎不对。也许设计和培训数据不适合我的目标。 您是否有任何想法或建议来适应数据,以达到我的目标?
注意:当我只使用一个用户的LSTM模型时,每次都有他的序列和标签(代表每个时间序列的下一个顺序),我得到了很好的结果来预测下一个用户订单的顺序。但是这种方法迫使我训练N用户的LSTM模型,所以不对。
谢谢你,
答案 0 :(得分:1)
我不是专家,但我不确定批量大小。据我所知,Keras LSTM在每批后重置其状态。因此,当批量大小为1时,LSTM会重置其内存。因此,您在处理时间步长2时忘记了用户1在时间步长1时所做的事情。最大购买次数可以是您的批量大小。您可以使用遮罩来避免填充效果。
答案 1 :(得分:0)
通过将网络安装到循环中的所有用户,您将为所有用户创建一个通用模型。这可能是您获得测试数据类似结果的原因。
你提到的论文旨在捕捉: 1)每个用户对过去篮子数据的一般兴趣 和 2)购买时的顺序信息(例如:买面包,下次购买黄油)
看一下图1)
的描述输入图层包含a的一系列篮子表示 用户。可以在隐藏中获得用户的动态表示 层。最后,输出层显示该用户对所有用户的分数 项目
我相信他们会为每个用户动态训练模型并从中进行预测。 他们使这个可行的方式是在每个篮子里汇集物品。
对于他们的数据,max_pooling工作得更好,但你也可以尝试avg_pooling,就像在论文中一样。 希望这可以帮助。试着自己实施这篇论文,如果你有任何进展,请告诉我们。