seq2seq预测下一时间步

2024-06-07 21:55:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正试图预测客户在下一个时间段可能购买的下一批商品。下面的示例是为了说明(我的实际数据集有大约600万个客户id和5000种不同的产品)

我当前的数据如下所示:

date  customer_nbr  products_bought
201701  123 ["product_1","product_5","product_15"]
201704  123 ["product_4","product_10","product_11"]
201721  123 ["product_1","product_6"]
201713  456 ["product_7","sproduct_11","product_12","product_15"]
201714  456 ["product_1","product_3"]
201721  456 ["product_4","product_9","product_10","product_13","product_15"]

数据的频率是按周计算的。因此,客户id 123在2017年第一周购买了商品“产品1”、“产品5”和“产品15”(因此给定年份最多有52周)。在获得输入变量后,我的最终数据帧如下所示:

date  customer_nbr  products_bought_last_period   products_bought
201704  123 ["product_1","product_5","product_15"]  ["product_4","product_10","product_11"]
201721  123 ["product_4","product_10","product_11"]  ["product_1","product_6"]
201714  456 ["product_7","sproduct_11","product_12","product_15"]   ["product_1","product_3"]
201721  456 ["product_1","product_3"]  
["product_4","product_9","product_10","product_13","product_15"]

因此,对于我的seq2seq模型,我希望使用products_bought_last_period预测客户购买日期为201721的产品的顺序,因此products_bought_last_period是我的输入,products_bought现在是我的目标变量。 然后,我对我的产品ID进行编码,并在数据帧中填充products_bought_last_periodproducts_bought数组(基于产品最多的数组)。后来,我把所有的东西np.阵列. 最后,我的实际数据集中的产品总数是5000,因此我设置了total_nbr_of_products = 5000,并尝试执行以下操作:

train = df[df['date'] < 201721].set_index('date')
test = df[df['date'] >= 201721].set_index('date')
X = train["products_bought_last_period"].copy()  
X_test = test["products_bought_last_period"].copy()


y = train['products_bought'].copy()  
y_test = test['products_bought'].copy()


X = np.array(X)
X_test = np.array(X_test)
y = np.array(y)
y_test = np.array(y_test)

# Encoder model
total_nbr_of_products = 5000
encoder_input = Input(shape=(None,total_nbr_of_products))
encoder_LSTM = LSTM(256,return_state = True)
encoder_outputs, encoder_h, encoder_c = encoder_LSTM (encoder_input)
encoder_states = [encoder_h, encoder_c]
# Decoder model
decoder_input = Input(shape=(None,total_nbr_of_products))
decoder_LSTM = LSTM(256,return_sequences=True, return_state = True)
decoder_out, _ , _ = decoder_LSTM(decoder_input, initial_state=encoder_states)
decoder_dense = Dense(total_nbr_of_products,activation='softmax')
decoder_out = decoder_dense (decoder_out)


model = Model(inputs=[encoder_input, decoder_input],outputs=[decoder_out])

model = Model(inputs=[encoder_input, decoder_input],outputs=[decoder_out])
model.compile(optimizer='adam', loss='categorical_crossentropy')
model.fit(X,y, 
          validation_data=(X_test, y_test),
          batch_size=64,
          epochs=5)

但是,当我尝试这样做时,出现了以下错误:

ValueError: Error when checking model input: the list of Numpy arrays that you are passing to your model is not the size the model expected. Expected to see 2 array(s), but instead got the following list of 1 arrays: [array([[array([1209, 2280, 1066, 3308, 3057, 4277, 3000, 4090,    0,    0,    0,

我不确定两件事:

1.)在匹配尺寸方面,我可能做错了什么

2.)以及我的seq2seq方法一开始是否正确

理想情况下,我希望预测一个客户(大约600万客户)可能购买的下一篮子商品。我非常感谢您的帮助


Tags: of数据testencoderinputdatemodel客户
1条回答
网友
1楼 · 发布于 2024-06-07 21:55:24
  1. 在匹配我的维度方面,我可能做错了什么?你知道吗

查看如何定义模型。你知道吗

model = Model(inputs=[encoder_input, decoder_input], outputs=[decoder_out])

您需要两个输入([encoder_inputdecoder_input]和decoder_out)来适合您的数据。你的model.fit()应该如下所示

model.fit([train_encoder_input, train_decoder_input], train_decoder_output)
  1. 这里的seq2seq正确吗?你知道吗

对我来说,这似乎是seq2seq的非常规用法,但很好。你必须看看如果滞后1是最佳选择,将不得不一个热编码你的产品清单购买。你知道吗

编辑:在下面添加了一个简单的示例。你知道吗

如果您查看以下链接,将有几个很好的示例进行说明。有关与keras的seq2seq的进一步查询,请参阅这些。你知道吗

https://blog.keras.io/a-ten-minute-introduction-to-sequence-to-sequence-learning-in-keras.html

https://github.com/philipperemy/keras-seq2seq-example


为了便于说明,我写了一个小例子。让我们考虑这样一种情况,我们想把一个字符串转换成一个字符串。比如说,我们正在引进一种新的邮政编码系统。你知道吗

import numpy as np
from keras.layers import Input, LSTM, Dense
from keras.models import Model

df = {'old': ['ABCDBA', 'EFFEBA', 'CDDCAA', 'BBBBAA', 'FFDDCD', 'DCFEEF', 
              'AAFFBA'],
      'new': ['XYX', 'ZZX', 'YYX', 'XXX', 'ZYY', 'YZZ', 'XZX']}

为方便起见,我已将令牌数和序列长度设置为固定值。我们为输入解码器的数据设置开头('M')和结尾字符('N')。你知道吗

encoder_texts = [[char for char in word] for word in df['old']]
decoder_texts = [[char for char in word] for word in df['new']]

old_char = ['A', 'B', 'C', 'D', 'E', 'F']
new_char = ['M', 'N', 'X', 'Y', 'Z']

encoder_seq_length = 6
decoder_seq_length = 4
num_encoder_tokens = len(old_char)
num_decoder_tokens = len(new_char)

old_token_index = dict((c, i) for i, c in enumerate(old_char))
new_token_index = dict((c, i) for i, c in enumerate(new_char))

'XYZ'为例。作为解码器的输入,它是'MXYZ',作为解码器的输出,它是XYZN'。最终我们必须对这一系列字符进行热编码,所以我做了如下工作

encoder_input_data = np.zeros((7, encoder_seq_length, num_encoder_tokens), dtype='float32')
decoder_input_data = np.zeros((7, decoder_seq_length, num_decoder_tokens), dtype='float32')
decoder_output_data = np.zeros((7, decoder_seq_length, num_decoder_tokens), dtype='float32')

for i, (encoder_text, decoder_text) in enumerate(zip(encoder_texts, decoder_texts)):
    for t, char in enumerate(encoder_text):
        encoder_input_data[i, t, old_token_index[char]] = 1
    for t, char in enumerate(decoder_text):
        decoder_input_data[i, t+1, new_token_index[char]] = 1

        if t > 0:
            decoder_output_data[i, t-1, new_token_index[char]] = 1

        decoder_input_data[i, 0, new_token_index['M']] = 1
        decoder_output_data[i, 3, new_token_index['N']] = 1

然后,你可以继续你的代码。你知道吗

encoder_input = Input(shape=(None, num_encoder_tokens))
encoder_LSTM = LSTM(units=128, return_state = True)
encoder_output, encoder_h, encoder_c = encoder_LSTM(encoder_input)
encoder_states = [encoder_h, encoder_c]

decoder_input = Input(shape=(None, num_decoder_tokens))
decoder_LSTM = LSTM(128, return_sequences=True, return_state=True)
decoder_output, _, _ = decoder_LSTM(decoder_input, initial_state=encoder_states)
decoder_dense = Dense(num_decoder_tokens, activation='softmax')
decoder_output = decoder_dense(decoder_output)

model = Model(inputs=[encoder_input, decoder_input], outputs=[decoder_output])
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit([encoder_input_data, decoder_input_data], decoder_output_data)

为了进一步回答第二个问题,您可以使用购买的滞后系列产品作为解码器的输入和输出。我对此没有理论依据,但通过seq2seq方案共享一个状态的两个结果序列似乎没问题(至少可以试一试)

相关问题 更多 >

    热门问题