Сходство документов с Word Mover Distance и Bert-Embedding - PullRequest
2 голосов
/ 11 марта 2019

Я пытаюсь вычислить сходство документов (ближайший сосед) для двух произвольных документов, используя вложения слов на основе BERT от Google .Чтобы получить вложения слов от Берта, я использую bert-as-a-service .Сходство документа должно основываться на Word-Mover-Distance с пакетом python wmd-relax .

Мои предыдущие попытки ориентированы по этому уроку из репозитория wmd-relax github: https://github.com/src-d/wmd-relax/blob/master/spacy_example.py

import numpy as np
import spacy
import requests
from wmd import WMD
from collections import Counter
from bert_serving.client import BertClient

# Wikipedia titles
titles = ["Germany", "Spain", "Google", "Apple"]

# Standard model from spacy
nlp = spacy.load("en_vectors_web_lg")

# Fetch wiki articles and prepare as specy document
documents_spacy = {}
print('Create spacy document')
for title in titles:
    print("... fetching", title)
    pages = requests.get(
        "https://en.wikipedia.org/w/api.php?action=query&format=json&titles=%s"
        "&prop=extracts&explaintext" % title).json()["query"]["pages"]
    text = nlp(next(iter(pages.values()))["extract"])
    tokens = [t for t in text if t.is_alpha and not t.is_stop]
    words = Counter(t.text for t in tokens)
    orths = {t.text: t.orth for t in tokens}
    sorted_words = sorted(words)
    documents_spacy[title] = (title, [orths[t] for t in sorted_words],
                              np.array([words[t] for t in sorted_words],
                                       dtype=np.float32))


# This is the original embedding class with the model from spacy
class SpacyEmbeddings(object):
    def __getitem__(self, item):
        return nlp.vocab[item].vector


# Bert Embeddings using bert-as-as-service
class BertEmbeddings:
    def __init__(self, ip='localhost', port=5555, port_out=5556):
        self.server = BertClient(ip=ip, port=port, port_out=port_out)

    def __getitem__(self, item):
        text = nlp.vocab[item].text
        emb = self.server.encode([text])
        return emb


# Get the nearest neighbor of one of the atricles
calc_bert = WMD(BertEmbeddings(), documents_spacy)
calc_bert.nearest_neighbors(titles[0])

К сожалению, вычисления не выполняются из-за несоответствия размеров при расчете расстояния: ValueError: shapes (812,1,768) and (768,1,812) not aligned: 768 (dim 2) != 1 (dim 1)

1 Ответ

0 голосов
/ 13 марта 2019

bert-as-service Форма вывода: (batch_size, sequence_len, embedding_dimension. В вашем случае sequence_len равно 1, так как вы объединяете результаты.

Теперь вы можете транспонировать другой, чтобы соответствовать этому, используяtranspose метод numpy.ndarray.

...