Как найти похожие слова в слое Keras Word Embedding

Из курса Стэнфорда CS244N я знаю, что Gensim предоставляет фантастический метод для игры с данными встраивания: most_similar

Я пытался найти эквивалент в слое Keras Embedding, но не смог. Это невозможно из коробки от Кераса? Или это была какая-то обертка поверх него?


person kee    schedule 17.06.2019    source источник


Ответы (1)


Простая реализация будет:

def most_similar(emb_layer, pos_word_idxs, neg_word_idxs=[], top_n=10):
    weights = emb_layer.weights[0]

    mean = []
    for idx in pos_word_idxs:
        mean.append(weights.value()[idx, :])

    for idx in neg_word_idxs:
        mean.append(weights.value()[idx, :] * -1)

    mean = tf.reduce_mean(mean, 0)

    dists = tf.tensordot(weights, mean, 1)
    best = tf.math.top_k(dists, top_n)

    # Mask words used as pos or neg
    mask = []
    for v in set(pos_word_idxs + neg_word_idxs):
        mask.append(tf.cast(tf.equal(best.indices, v), tf.int8))
    mask = tf.less(tf.reduce_sum(mask, 0), 1)

    return tf.boolean_mask(best.indices, mask), tf.boolean_mask(best.values, mask)

Конечно, вам нужно знать индексы слов. Я предполагаю, что у вас есть отображение word2idx, поэтому вы можете получить их так: [word2idx[w] for w in pos_words].

Чтобы использовать его:

# Assuming the first layer is the Embedding and you are interested in word with idx 10
idxs, vals = most_similar(model.layers[0], [10])

with tf.Session() as sess:
    init = tf.global_variables_initializer()
    sess.run(init)
    idxs = sess.run(idxs)
    vals = sess.run(vals)

Некоторые потенциальные улучшения для этой функции:

  • Убедитесь, что он возвращает top_n слов (после маски он возвращает меньше слов)
  • gensim использует нормализованные вложения (L2_norm)
person spadarian    schedule 18.06.2019