Я пытаюсь создать систему рекомендаций с помощью модели SkipGram, я создал вариант Word2vec, адаптированный к моим данным (аниме), где я использую список просмотра аниме таких пользователей, как
data =[]
for key, chunk in ratings.groupby('user_id'):
data.append(chunk.sort_values('user_rating').anime_id.values)
мои рейтинги датафрейм имеет 30 тыс. Уникальных пользователей, 12 тыс. Уникальных аниме, пользовательский рейтинг и некоторые лайки метаданных (anime_tags, год, количество эпизодов, синопсис и т. Д.)
Я пытаюсь найти способ добавить эти метаданные в мою модель "Anime2Vec".
Могу ли я построить другую модель (concat / blend / sum ???) вложения
о моей базовой модели, это конструкция, подобная той, о которой я говорил ранее просмотренная сессия пользователей, затем я использую следующие функции:
def get_batch(seq, rel_window_size=.2):
"""get a batch of data for a single user sequence.
data will be chosen randomly from within a anime
window relative to the size of the entire sequence.
with the initial point chosen at random.
"""
window = math.floor(len(seq) * rel_window_size) +1
x = []
y = []
i = random.randint(0, len(seq)-1)
for _ in range(batch_size):
x.append(seq[i])
moves = list(range(max(i-window, 0), i)) + list(range(i+1, min((i+window + 1, len(seq)))))
j = random.choice(moves)
y.append(seq[j])
i = j
return x, y
def gen_batch(data, batch_size, rel_window_size=.2, shuffle=True):
"""make a generator for data using each 'user' as a document."""
while True:
for doc_index, doc in enumerate(data):
x, y = get_batch(doc, rel_window_size)
yield np.array(x, 'int32'), np.expand_dims(np.array(y,'int32'), 1)
if shuffle:
random.shuffle(data)
Тогда я попробовал несколько образцов, если моя модель работает нормально
val_anime = ['Naruto',
'Bleach',
"Clannad",
"Air",
"Code Geass Hangyaku no Lelouch",
"Overlord",
"Mononoke Hime",
"Hajime no Ippo",
"Fullmetal Alchemist"]
val_ids = [reverse_dictionary[s] for s in val_anime]
val_set = np.array(val_ids, 'int32')
Тогда я определяю модель и данные
# valid_examples = np.array(random.sample(range(1, valid_window+1), valid_size))# valid_e
vocab_size = len(dictionary)
batch_size = 128
embedding_size = 50 # Dimension of the embedding vector.
val_size =len(val_set)
lr = 1.
model = SkipGramModel(vocab_size, val_set, embedding_dims=embedding_size,
batch_size=batch_size, sample_factor=1., lr=lr, optimizer= tf.train.AdagradOptimizer)
# create the data generator
data_gen = gen_batch(data, batch_size, rel_window_size = .2, shuffle=True)
Параметры для обучения.
steps_per_cycle = (len(data) // batch_size)
n_iter = 300 # number of full cycles through data
num_steps = int(n_iter * steps_per_cycle)
lstep = steps_per_cycle # steps to show average loss
vstep = steps_per_cycle * 20 # steps to show val data
Я определяю функцию для ближайших пунктов
def show_n_similar(item, sim, k=5):
item_name = dictionary[item]
nearest = (-sim).argsort()[1:k + 1]
log_str = '\nNearest to - {}:\n'.format(item_name)
for k in range(k):
log_str += '\t{},\n'.format(dictionary[nearest[k]])
print(log_str)
losses = []
Наконец я тренирую модель, чтобы найти ближайших соседей в моем ранее определенном списке
with tf.Session() as sess:
sess.run(model.init_op())
print('initialized ...')
# set so we can watch average loss during training
for step in tqdm(range(num_steps)):
batch_inputs, batch_labels = next(data_gen)
feed_dict = {model.x: batch_inputs,
model.y: batch_labels}
_, loss_ = sess.run([model.optimize, model.loss], feed_dict=feed_dict)
losses.append(loss_) # for plotting
sim = model.similarity.eval()
for i in range(len(val_ids)):
show_n_similar(model.val_data[i], sim[i], k=5)
out_embeddings = model.normalized_embeddings.eval()
Я хотел бы получить совет по добавлению метаданных в модель, в первую очередь просто добавьте anime_tags.
Мои anime_tags представлены списком ключевых слов, подобных этому:
anime_id | tags
8 | action, historical, sci-fi, comedy
12 | comedy, romance