无法从 vector_ngrams 中重现预训练的词向量
Cannot reproduce pre-trained word vectors from its vector_ngrams
只是出于好奇,但我正在调试 gensim 的 FastText 代码以复制词汇外 (OOV) 词的实现,但我无法完成它。
所以,我遵循的过程是用玩具语料库训练一个小模型,然后比较词汇表中一个词的结果向量。这意味着如果整个过程没问题,输出数组应该是相同的。
这是我用于测试的代码:
from gensim.models import FastText
import numpy as np
# Default gensim's function for hashing ngrams
from gensim.models._utils_any2vec import ft_hash_bytes
# Toy corpus
sentences = [['hello', 'test', 'hello', 'greeting'],
['hey', 'hello', 'another', 'test']]
# Instatiate FastText gensim's class
ft = FastText(sg=1, size=5, min_count=1, \
window=2, hs=0, negative=20, \
seed=0, workers=1, bucket=100, \
min_n=3, max_n=4)
# Build vocab
ft.build_vocab(sentences)
# Fit model weights (vectors_ngram)
ft.train(sentences=sentences, total_examples=ft.corpus_count, epochs=5)
# Save model
ft.save('./ft.model')
del ft
# Load model
ft = FastText.load('./ft.model')
# Generate ngrams for test-word given min_n=3 and max_n=4
encoded_ngrams = [b"<he", b"<hel", b"hel", b"hell", b"ell", b"ello", b"llo", b"llo>", b"lo>"]
# Hash ngrams to its corresponding index, just as Gensim does
ngram_hashes = [ft_hash_bytes(n) % 100 for n in encoded_ngrams]
word_vec = np.zeros(5, dtype=np.float32)
for nh in ngram_hashes:
word_vec += ft.wv.vectors_ngrams[nh]
# Compare both arrays
print(np.isclose(ft.wv['hello'], word_vec))
对于比较数组的每个维度,此脚本的输出均为 False。
如果有人能指出我遗漏了什么或做错了什么,那就太好了。提前致谢!
一个完整单词的 FastText 单词向量的计算不只是只是它的字符 n-gram 向量的总和,而且也是一个原始的完整单词向量,它也经过训练词汇中的单词。
您从 ft.wv[word]
返回的已知词的全词向量已经预先计算了这个组合。有关此完整计算的示例,请参阅 adjust_vectors()
方法:
raw 全词向量位于 model.wv
对象的 .vectors_vocab
数组中。
(如果这还不足以协调问题:确保您使用的是最新的 gensim
,因为最近有许多 FT 修复。并且,确保您的 ngram-hashes 列表与输出相匹配库的 ft_ngram_hashes()
方法——如果不是,您的手动 ngram-list-creation 和后续散列可能会做一些不同的事情。)
只是出于好奇,但我正在调试 gensim 的 FastText 代码以复制词汇外 (OOV) 词的实现,但我无法完成它。 所以,我遵循的过程是用玩具语料库训练一个小模型,然后比较词汇表中一个词的结果向量。这意味着如果整个过程没问题,输出数组应该是相同的。
这是我用于测试的代码:
from gensim.models import FastText
import numpy as np
# Default gensim's function for hashing ngrams
from gensim.models._utils_any2vec import ft_hash_bytes
# Toy corpus
sentences = [['hello', 'test', 'hello', 'greeting'],
['hey', 'hello', 'another', 'test']]
# Instatiate FastText gensim's class
ft = FastText(sg=1, size=5, min_count=1, \
window=2, hs=0, negative=20, \
seed=0, workers=1, bucket=100, \
min_n=3, max_n=4)
# Build vocab
ft.build_vocab(sentences)
# Fit model weights (vectors_ngram)
ft.train(sentences=sentences, total_examples=ft.corpus_count, epochs=5)
# Save model
ft.save('./ft.model')
del ft
# Load model
ft = FastText.load('./ft.model')
# Generate ngrams for test-word given min_n=3 and max_n=4
encoded_ngrams = [b"<he", b"<hel", b"hel", b"hell", b"ell", b"ello", b"llo", b"llo>", b"lo>"]
# Hash ngrams to its corresponding index, just as Gensim does
ngram_hashes = [ft_hash_bytes(n) % 100 for n in encoded_ngrams]
word_vec = np.zeros(5, dtype=np.float32)
for nh in ngram_hashes:
word_vec += ft.wv.vectors_ngrams[nh]
# Compare both arrays
print(np.isclose(ft.wv['hello'], word_vec))
对于比较数组的每个维度,此脚本的输出均为 False。
如果有人能指出我遗漏了什么或做错了什么,那就太好了。提前致谢!
一个完整单词的 FastText 单词向量的计算不只是只是它的字符 n-gram 向量的总和,而且也是一个原始的完整单词向量,它也经过训练词汇中的单词。
您从 ft.wv[word]
返回的已知词的全词向量已经预先计算了这个组合。有关此完整计算的示例,请参阅 adjust_vectors()
方法:
raw 全词向量位于 model.wv
对象的 .vectors_vocab
数组中。
(如果这还不足以协调问题:确保您使用的是最新的 gensim
,因为最近有许多 FT 修复。并且,确保您的 ngram-hashes 列表与输出相匹配库的 ft_ngram_hashes()
方法——如果不是,您的手动 ngram-list-creation 和后续散列可能会做一些不同的事情。)