我一直在搜索并尝试实现单词嵌入模型来预测单词之间的相似性。我有一个由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)
模型在词汇中包含所有单词之后,针对每个公司名称计算平均句子向量: df ['avg_vector'] = df2.apply(lambda row:avg_sentence_vector(row,model = 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)
在数据集中,我有诸如爪子或petcare之类的词,但是其他词正在与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
创建与GoogleNews相同类型的关系,例如在相似的单词之间正确设置了单词pet
?fasttext
是否可行?谢谢
答案 0 :(得分:1)
Word2vec不能泛化为看不见的单词。
对于见过的病房,甚至稀有,它甚至都无法正常工作。这实际上取决于是否有许多单词用法示例。此外,您需要左右足够的上下文,但是您仅使用公司名称-这些名称太短。这可能就是您的嵌入效果如此差的原因:数据太少,文本太短。
因此,这对您来说是错误的方法。用新的公司名称重新训练模型是不够的-您仍然只有一个数据点。您也可以省去看不见的单词,即使重新培训,word2vec 的效果也不会更好。
答案 1 :(得分:1)
如果您只想计算单词之间的相似度,则可能不需要在词汇表中插入新单词。
肉眼上看,我认为您也可以使用FastText而不需要阻止单词。它还计算未知单词的向量。
来自FastText FAQ:
fastText单词表示的关键特征之一是它的功能 为任何单词甚至是虚构单词生成向量。确实,fastText 单词向量是根据字符子串的向量构建的 包含在其中。这甚至可以为拼写错误构建向量 单词或单词串联。
FastText似乎对您有用。 对于您的任务,您可以遵循FastText supervised tutorial。
如果语料库过小,则可以从可用的预训练向量(pretrainedVectors parameter)开始构建模型。
答案 2 :(得分:1)
3500个文本(公司名称)中的每个单词仅约3个单词,总共仅约10k训练单词,而独特单词的词汇量则少得多。
对于word2vec及其相关算法来说,这非常小,它依赖大量数据和足够多的数据来训练有用的向量排列。
您可以通过使用比默认epochs=5
多得多的 个训练时期和比size=100
小得多的 个向量,从有限的数据中获得一些有意义的训练。默认为most_similar()
。通过这些调整,您可能会开始看到更有意义的buckets
结果。
但是,目前尚不清楚word2vec(尤其是名字平均单词比较中的word2vec)是否与最终目标相匹配。
Word2vec需要大量数据,不会查看子词单位,也无法说出在训练中看不到的单词标记。平均多个单词向量通常可以用作比较多单词文本的简单基准,但是与其他方法相比,它也可以稀释某些单词的影响。
要考虑的事情可能包括:
与Word2vec相关的算法(例如FastText)也可以学习子词单元的向量,因此可以为训练中未出现的词引导不太坏的猜测向量。 (但是,这些也需要大量数据,要在较小的数据集上使用,您再次想要减小向量大小,增加历元并另外减少用于子词学习的char s[] = "OK";
的数量。)
多词文本的更复杂的比较,例如“移词器的距离”。 (对于较长的文本而言,这可能会非常昂贵,但对于仅包含几个单词的名称/标题来说,这是可行的。)
查找更多与您的目标兼容的数据,以建立更强大的模型。较大的公司名称数据库可能会有所帮助。如果您只是想让分析理解英语单词/词根,那么也可以使用更多通用的培训课本。
出于很多目的,尽管它无法检测到所有同义词/语义相似的单词,但仅按字典顺序进行比较(编辑距离,共享字符n-gram的计数)也可能会有所帮助。