Как вручную изменить векторные размеры слова в Gensim Word2Vec
У меня есть модель Word2Vec с большим количеством векторов слов. Я могу получить доступ к слову вектор как так.
word_vectors = gensim.models.Word2Vec.load(wordspace_path)
print(word_vectors['boy'])
Выход
[ -5.48055351e-01 1.08748421e-01 -3.50534245e-02 -9.02988110e-03...]
Теперь у меня есть правильное векторное представление, которым я хочу заменить word_vectors['boy'].
word_vectors['boy'] = [ -7.48055351e-01 3.08748421e-01 -2.50534245e-02 -10.02988110e-03...]
Но выдается следующая ошибка
TypeError: 'Word2Vec' object does not support item assignment
Есть ли способ или обходной путь для этого? То есть вручную управлять векторами слов после обучения модели? Возможно ли это на других платформах, кроме Gensim?
1 ответ
Так как векторы word2vec, как правило, создаются только итеративным процессом обучения, затем осуществляется доступ, gensim Word2Vec
Объект не поддерживает прямое присвоение новых значений по своим индексам слов.
Однако, как и в Python, все его внутренние структуры полностью доступны для просмотра / взлома вами, и, поскольку он является открытым исходным кодом, вы можете точно увидеть, как он выполняет все свои существующие функции, и использовать его в качестве модели того, как делать новые вещи.
В частности, необработанные слова-векторы (в последних версиях gensim) хранятся в свойстве Word2Vec
объект называется wv
, и это wv
свойство является экземпляром KeyedVectors
, Если вы изучите его исходный код, вы можете увидеть доступ к словам-векторам по строковому ключу (например, 'boy'
), в том числе []
Индексирование осуществляется __getitem__()
метод, пройти его метод word_vec()
, Вы можете просмотреть источник этого метода либо в вашей локальной установке, либо на Github:
Там вы увидите, что слово фактически преобразуется в целочисленный индекс (через self.vocab[word].index
) затем используется для доступа к внутреннему syn0
или же syn0norm
массив (в зависимости от того, обращается ли пользователь к необработанному или единичному нормализованному вектору). Если вы посмотрите в другом месте, где они установлены, или просто изучите их в своей консоли / коде (как если бы word_vectors.wv.syn0
), вы увидите это numpy
массивы, которые поддерживают прямое назначение по индексу.
Таким образом, вы можете напрямую изменять их значения целочисленным индексом, как если бы:
word_vectors.wv.syn0[word_vectors.wv.vocab['boy'].index] = [ -7.48055351e-01 3.08748421e-01 -2.50534245e-02 -10.02988110e-03...]
А потом, будущие доступы word_vectors.wv['boy']
вернет ваши обновленные значения.
Заметки:
• Если ты хочешь syn0norm
быть обновленным, иметь правильные единичные векторы (которые используются в most_similar()
и другие операции), вероятно, было бы лучше изменить syn0
сначала, затем отбросить и пересчитать syn0norm
, с помощью:
word_vectors.wv.syn0norm = None
word_vectors.wv.init_sims()
• Добавление новых слов потребует более сложного вмешательства в объект, потому что это потребует увеличения syn0
(заменив его большим массивом) и обновив vocab
ДИКТ