#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
?
После этого длинного объяснения, пожалуйста, дайте мне знать, если я сказал что-то не так!