词嵌入模型

Word Embedding Model

我一直在搜索并尝试实现一个词嵌入模型来预测词之间的相似度。我有一个由 3,550 个公司名称组成的数据集,其想法是用户可以提供一个新词(不会出现在词汇表中)并计算新名称与现有名称之间的相似度。

在预处理过程中,我去掉了停用词和标点符号(连字符、点、逗号等)。此外,我应用了词干提取和分隔前缀,希望获得更高的精度。然后 BIOCHEMICAL 这样的词最终变成了 BIO CHEMIC ,这个词一分为二(前缀和词干)

平均公司名称长度由 3 个词组成,频率如下:

作为预处理结果的标记被发送到 word2vec:

#window: Maximum distance between the current and predicted word within a sentence
#min_count: Ignores all words with total frequency lower than this.
#workers: Use these many worker threads to train the model
#sg: The training algorithm, either CBOW(0) or skip gram(1). Default is 0s
word2vec_model = Word2Vec(prepWords,size=300, window=2, min_count=1, workers=7, sg=1)

模型收录了vocab中的所有单词后,计算每个公司名称的平均句向量: df['avg_vector']=df2.apply(lambda 行:avg_sentence_vector(行,模型=word2vec_model,num_features=300,index2word_set=set( word2vec_model.wv.index2word)).tolist())

然后,保存矢量以供进一步查找:

##Saving name and vector values in file
df.to_csv('name-submission-vectors.csv',encoding='utf-8', index=False)

如果经过预处理(去除停用词和标点符号)后词汇中没有包含新的公司名称,那么我将再次创建模型并计算平均句向量并再次保存。

我发现这个模型没有按预期工作。例如,计算最相似的词 pet 得到以下结果:

ms=word2vec_model.most_similar('pet')

('fastfood', 0.20879755914211273)
('hammer', 0.20450574159622192)
('allur', 0.20118337869644165)
('wright', 0.20001833140850067)
('daili', 0.1990675926208496)
('mgt', 0.1908089816570282)
('mcintosh', 0.18571510910987854)
('autopart', 0.1729743778705597)
('metamorphosi', 0.16965581476688385)
('doak', 0.16890916228294373)

在数据集中,我有爪子或宠物护理等词,但其他词正在与 pet 个词建立关系。

这是 pet 的近词分布:

另一方面,当我使用 GoogleNews-vectors-negative300.bin.gz 时,我无法将新词添加到词汇中,但 pet 与周围词的相似度符合预期:

ms=word2vec_model.most_similar('pet')
('pets', 0.771199643611908)
('Pet', 0.723974347114563)
('dog', 0.7164785265922546)
('puppy', 0.6972636580467224)
('cat', 0.6891531348228455)
('cats', 0.6719794869422913)
('pooch', 0.6579219102859497)
('Pets', 0.636363685131073)
('animal', 0.6338439583778381)
('dogs', 0.6224827170372009)

这是最近词的分布:

我想就以下问题征求您的意见:

谢谢

Word2vec 不会推广到看不见的单词。

它甚至不能很好地用于看到但 罕见 的守卫。这真的取决于有很多单词用法的例子。此外,您需要左右足够的上下文,但您只使用公司名称 - 这些太短了。这可能就是您的嵌入表现如此糟糕的原因:数据太少,文本太短。

因此,这对您来说是错误的方法。用新公司名称重新训练模型是不够的——你仍然只有一个数据点。你还不如省去没见过的词,word2vec cannot 即使你重新训练也比那个更好。

如果您只想计算单词之间的相似度,可能不需要在词汇表中插入新单词。

通过观察,我认为您也可以使用 FastText 而无需对单词进行词干处理。它还计算未知词的向量。

来自 FastText FAQ

One of the key features of fastText word representation is its ability to produce vectors for any words, even made-up ones. Indeed, fastText word vectors are built from vectors of substrings of characters contained in it. This allows to build vectors even for misspelled words or concatenation of words.

FastText 似乎对您有用。 对于您的任务,您可以关注 FastText supervised tutorial.

如果您的语料库太小,您可以从可用的预训练向量 (pretrainedVectors parameter) 开始构建模型。

3500 条文本(公司名称),每个文本只有约 3 个单词,总共只有大约 10k 个训练单词,唯一单词的词汇表要少得多。

这对于 word2vec 和相关算法来说非常非常小,它们依赖大量数据和充分变化的数据来训练有用的向量排列。

通过使用比默认 epochs=5 多 且 小得多的训练时期,您可以从有限的数据中提取一些有意义的训练 比默认值 size=100 向量。通过这些调整,您可能会开始看到更有意义的 most_similar() 结果。

但是,目前尚不清楚 word2vec,特别是在您的平均名字的单词比较中的 word2vec,是否与您的最终目标相匹配。

Word2vec 需要大量数据,不查看子词单元,并且无法说明训练期间未见的词标记。许多词向量的平均数通常可以作为比较多词文本的简单基线,但与其他方法相比,也可能会削弱某些词的影响。

需要考虑的事项可能包括:

  • 与 Word2vec 相关的算法,如 FastText,它们也学习子词单元的向量,因此可以 bootstrap 不错地猜测训练中未见过的词的向量。 (但是,这些也是数据饥渴的,要在小型数据集上使用,您需要再次减少向量大小,增加纪元,并另外减少用于子词学习的 buckets 的数量。)

  • 更复杂的多词文本比较,例如 "Word Mover's Distance"。 (对于较长的文本,这可能会非常昂贵,但对于 names/titles 来说,几个单词可能是实用的。)

  • 寻找更多符合您的目标的数据以获得更强大的模型。更大的公司名称数据库可能会有所帮助。如果您只想让您的分析理解英语 words/roots,更通用的培训文本也可能有效。

  • 出于多种目的,单纯的词典比较 - 编辑距离、共享字符 n-gram 的计数 - 可能也有帮助,尽管它不会检测到所有 synonyms/semantically-similar 个单词。