如何为序列项目训练 LSTM 模型?

Posted

技术标签:

【中文标题】如何为序列项目训练 LSTM 模型?【英文标题】:How training LSTM model for sequences items ? 【发布时间】:2017-11-15 18:45:54 【问题描述】:

我尝试将 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         ... 

标签 user 代表每个用户的下一个订单,在他们过去的订单之后,代表 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% 的用户上拟合了模型,并在其余的用户上测试了模型。

我的结果很差,模型推荐给每个用户测试的top-n项非常相似。例如,对于特定用户,该模型会推荐从未出现在其旧序列中的项目。虽然通常情况下,它必须预测最后一个序列比较的项目,因此,它应该预测过去购买的项目的高概率。

显然,我的方法似乎是错误的。也许设计和训练数据不适合我的目标。 您对拟合数据以达到我的目标有任何想法或建议吗?

注意:当我拟合一个只有一个用户的 LSTM 模型时,每次使用他的序列和他的标签(代表每个时间序列的下一个订单),我得到很好的结果来预测下一个用户订单的下一个订单.但是这种方法,迫使我训练 N-user LSTM 模型,所以是不对的。

谢谢你,

【问题讨论】:

【参考方案1】:

通过将网络拟合到循环中的所有用户,您正在为所有用户创建一个通用模型。这可能是您获得类似测试数据结果的原因。

您提到的论文旨在捕捉: 1) 来自过去购物篮数据的每个用户的普遍兴趣 和 2)购买中的顺序信息(例如:买了面包,下次会买黄油)

看一下图1)的描述

输入层包括一系列篮子表示 用户。可以在隐藏中获取用户的动态表示 层。最后输出层显示该用户对所有人的分数 项目。

我相信他们会即时为每个用户训练模型并据此进行预测。 他们使这成为可能的方式是将每个篮子中的物品汇集在一起​​​​。

对于他们的数据,max_pooling 效果更好,但您也可以像论文中一样尝试 avg_pooling。 希望这可以帮助。尝试自己实施这篇论文,所以如果您有任何进展,请告诉我们。

【讨论】:

【参考方案2】:

我不是专家,但我不确定批量大小。据我所知,Keras LSTM 在每批之后都会重置其状态。因此,当您的批量大小为 1 时,LSTM 会重置其内存。因此,您在处理时间步 2 时忘记了用户 1 在时间步 1 所做的事情。购买的最大数量可以是您的批量大小。您可以使用遮罩来避免填充的影响。

【讨论】:

以上是关于如何为序列项目训练 LSTM 模型?的主要内容,如果未能解决你的问题,请参考以下文章

如何为语言翻译重新训练序列到序列神经网络模型?

基于LSTM的序列预测: 飞机月流量预测

基于LSTM的序列预测: 飞机月流量预测

如何为多对一二元分类 LSTM 准备数据?

如何为 LSTM 重塑数据 - 时间序列多类分类

Keras 在训练分类 LSTM 序列到序列模型时给出 nan