Как предсказать следующий элемент на основе исторических данных с помощью LSTM Keras

#python #keras #lstm

#python #keras #lstm

Вопрос:

У меня есть исторические визуализации электронной коммерции каждого пользователя. Поскольку я хочу предсказать, какой следующий элемент будет визуализирован (на самом деле я хочу предсказать следующие 10 визуализируемых элементов, но я пытаюсь начать с более простой модели), я преобразовал каждый элемент в уникальное целое число. Теперь элементы кодируются с уникальными индексами 0, 1, 2, …, num_unique_integers.
Вопрос 1: Должен ли я начинать индексы с 1 ?

Некоторые пользователи просматривают 10 элементов, другие просматривают 2 элемента, другие просматривают 5 элементов…Таким образом, временные интервалы различны для каждого пользователя.

Предположим, что пользователь 1 просмотрел эти элементы (закодированные как индексы):

 [3, 10, 230, 1, 222, 98]
 

И я знаю, что в будущем он будет просматривать этот элемент:

 [65]
 

Теперь предположим, что пользователь 2 просмотрел эти элементы:

 [5, 10, 12]
 

И я знаю, что в будущем он будет просматривать этот элемент:

 [3]
 

Так что я прав, добавляя каждому пользователю одинаковую длину.
Я маскируюсь, -1 потому что я начинаю с индексов 0 .
Вопрос 2: Должен ли я начинать индексы с 1 и маскировать эти недостающие временные интервалы 0 ?

Предположим, что я могу замаскировать -1 , пользовательские 2 элемента теперь:

 [5, 10, 12, -1, -1, -1]
 

nan У меня нет последовательностей in, и я исправляю каждого пользователя в правильном формате.
К данным обучения у меня есть 177182 пользователи. Поскольку я буду использовать LSTM из Keras для построения модели последовательности «многие к одному», я изменил форму каждого пользователя в 3D. Это X_train выглядит так:

 [[[1818554]
  [1818554]
  [1488094]
  ...
  [     -1]
  [     -1]
  [     -1]]

 [[1003556]
  [1496514]
  [ 444647]
  ...
  [     -1]
  [     -1]
  [     -1]]

 [[ 394651]
  [ 708912]
  [  36967]
  ...
  [     -1]
  [     -1]
  [     -1]]

 ...

 [[1216588]
  [1216588]
  [1216588]
  ...
  [     -1]
  [     -1]
  [     -1]]

 [[ 149401]
  [ 331973]
  [  97939]
  ...
  [     -1]
  [     -1]
  [     -1]]

 [[1628493]
  [ 339106]
  [1553924]
  ...
  [     -1]
  [     -1]
  [     -1]]]
 

X_train shape: (117182, 18, 1)
Question 3: This is the right shape? I’m using 18 timesteps to each user, and just 1 feature.
Question 4: What 1 feature here means? I think that means that I have only information of the sequence to predict next item. If I would like to incorporate metadata’s item (like category, or price) it would be 2 features or 3 features?

This is what y_train looks like:

 [[[1845675]]

 [[ 915969]]

 [[ 574660]]

 ...

 [[1450189]]

 [[ 179777]]

 [[1125658]]]
 

y_train shape: (117182, 1, 1)
Question 5: This is the right shape for the target? I will output only 1 item for eery user by now.

Now let’s begin the model:

 # number of timesteps 
timesteps = 18

# masking value
MASKING = -1

# number of unique items (-1 because the masking value)
unique_items = len(item2idx_mapping.keys()) - 1

model = Sequential()

# masking empty timesteps
model.add(Masking(mask_value=MASKING, input_shape=(timesteps, 1)))

# LSTM layer with 18 time steps and one feature
model.add(LSTM(100, input_shape=(timesteps, 1)))

model.add(Dense(unique_items))

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
 

This is the model summary:

 Layer (type)                 Output Shape              Param #   
=================================================================
masking_7 (Masking)          (None, 18, 1)             0         
_________________________________________________________________
lstm_7 (LSTM)                (None, 100)               40800     
_________________________________________________________________
dense_7 (Dense)              (None, 2102276)           212329876 
=================================================================
Total params: 212,370,676
Trainable params: 212,370,676
Non-trainable params: 0
 

I’m using sparse_categorical_crossentropy because my classes are integers (indexes).
As I understood, the Dense() layer will output 2102276 (num_unique_items) probabilities, and the sparse_categorical_crossentropy will use the max value to find the class (in this case, an integer representing the item index)

Question 6: Should I use categorical_crossentropy here and one-hot my data? I have 2102277 unique items on my data.

Question 7: My Dense layer is right? I will output only one item from each user. If I would like to output the top-10 items, what Dense() should looks like?

So now let’s to the fit part:

 history = model.fit(X_train, y_train, epochs=10, batch_size=1, validation_data=(X_val, y_val), verbose=1)
 

In the beginning oth the preprocess data, I splitted in train, validation and test sets in the right format (that’s ok for me). That’s why I’m passing validation_data here.
This is what looks X_val :

 array([[[1246829],
        [1223718],
        [1246829],
        ...,
        [     -1],
        [     -1],
        [     -1]],

       [[1372502],
        [     -1],
        [     -1],
        ...,
        [     -1],
        [     -1],
        [     -1]],

       [[ 290857],
        [ 590159],
        [ 590159],
        ...,
        [     -1],
        [     -1],
        [     -1]],

       ...,

       [[1049576],
        [1049576],
        [1049576],
        ...,
        [     -1],
        [     -1],
        [     -1]],

       [[ 486021],
        [ 785693],
        [ 486021],
        ...,
        [     -1],
        [     -1],
        [     -1]],

       [[1314096],
        [1314096],
        [1314096],
        ...,
        [1267549],
        [2075858],
        [2075858]]])
 

И это то, что выглядит y_val :

 array([[[1868124]],

       [[ 846133]],

       [[ 332563]],

       ...,

       [[2071300]],

       [[1457682]],

       [[ 790620]]])
 

Конечные формы:

 print(X_train.shape)
print(y_train.shape)
print(X_val.shape)
print(y_val.shape)
(117182, 18, 1)
(117182, 1, 1)
(3859, 18, 1)
(3859, 1, 1)
 

Вопрос 8: Правильно ли я прохожу мимо X_val и y_val на правильном ли пути?

Это то, что я получаю при обучении.
Я не использую графический процессор, но я буду использовать:

 Epoch 1/10
33/117182 [..........................] - ETA: 30:00:00 - loss: 14.90 - accuracy 0.000e 00
 

Вопрос 9: Должен ли я использовать accuracy здесь в качестве показателя? Как я понял, метрика предназначена только для исследования моей модели после обучения. Это не влияет на периоды обучения.

Вопрос 10: Почему потери велики? Это не должно быть между [0, 1] ? Или он распадется после стольких эпох?

Вопрос 11: Поскольку мои данные большие, как вы думаете, есть ли другой способ вычислять быстрее (я могу использовать графический процессор). Но без учета GPU, что я мог сделать? Могу ли я использовать больше пакетов в обучении, например batch_size=64 ?


После этого длинного объяснения, пожалуйста, дайте мне знать, если я сказал что-то не так!