Как добавить новые векторы слов в gensim.models.keyedvectors и вычислить most_s Similar - PullRequest
0 голосов
/ 18 июня 2019

Согласно странице Gensim на WordEmbeddingKeyedVectors , вы можете постепенно добавлять новую пару ключ-значение новых векторов слов. Однако после инициализации WordEmbeddingKeyedVectors с предварительно обученными векторами и их тегами и добавления в него новых невидимых векторов слов, выведенных из модели, метод most_similar больше не может использоваться.

from gensim.models.keyedvectors import WordEmbeddingsKeyedVectors

test = WordEmbeddingsKeyedVectors(vector_size=3)

test.add(entities=["1", "2"], weights=[np.random.randint(5, size=3), 
                                  np.random.randint(5, size=3)])

test.most_similar("2") #THIS WORKS

test.add(entities=['3'], weights=[np.random.randint(5, size=3)])

test.most_similar("3") #THIS FAILS

Я ожидаю, что на выходе будет список векторных тегов, наиболее похожих на тег ввода, но на выходе получится:

IndexError: индекс 2 выходит за пределы оси 0 с размером 2

Ответы [ 2 ]

0 голосов
/ 18 июня 2019

На самом деле, я нашел решение для этого.

В файле gensim.models.keyedvectors под class WordEmbeddingKeyedVectors мы можем изменить значение с

def init_sims(self, replace=False):
    """Precompute L2-normalized vectors."""
    if getattr(self, 'vectors_norm', None) is None or replace:
        logger.info("precomputing L2-norms of word weight vectors")
        self.vectors_norm = _l2_norm(self.vectors, replace=replace)

на

def init_sims(self, replace=False):
    """Precompute L2-normalized vectors."""
    if getattr(self, 'vectors_norm', None) is None or replace:
        logger.info("precomputing L2-norms of word weight vectors")
        self.vectors_norm = _l2_norm(self.vectors, replace=replace)
    elif (len(self.vectors_norm) == len(self.vectors)): #if all of the added vectors are pre-computed into L2-normalized vectors
        pass 
    else: #when there are vectors added but have not been pre-computed into L2-normalized vectors yet
        logger.info("adding L2-norm vectors for new documents")
        diff = len(self.vectors) - len(self.vectors_norm)
        self.vectors_norm = vstack((self.vectors_norm, _l2_norm(self.vectors[-diff:])))

По сути, если исходная функция выполняетнет self.vectors_norm, рассчитывается по L2-нормализации self.vectors.Однако, если в self.vectors есть какие-либо новые добавленные векторы, которые не были предварительно вычислены в L2-нормализованные векторы, мы должны предварительно вычислить их, а затем добавить к self.vectors_norm.

.это как комментарий к вашему сообщению об ошибке @gojomo и добавление запроса на получение!Спасибо :)

0 голосов
/ 18 июня 2019

Похоже, что операция add() не очищает кэш векторов нормализованной длины, который создается и повторно используется most_similar() -подобными операциями.

Непосредственно перед или после выполнения add() вы можете явно удалить этот кеш с помощью:

del test.vectors_norm

Затем ваш test.most_similar('3') должен работать без IndexError.

добавил отчет об ошибке для этой проблемы в проект gensim.)

...