使用 Gensim Word2Vec 改进搜索

Using Gensin Word2Vec to improve search

我有一个包含数百万个数组的数据集,如下所示:

  sentences=[
    [
     'query_foo bar',
     'split_query_foo',
     'split_query_bar',
     'sku_qwre',
     'brand_A B C',
     'split_brand_A',
     'split_brand_B',
     'split_brand_C',
     'color_black',
     'category_C1',
     'product_group_clothing',
     'silhouette_t_shirt_top',
  ],
  [...]
  ]

您在哪里可以找到查询、执行查询的用户获得的 sku 以及 SKU 的一些属性。我的想法是做一个基于 word2vec 的非常基本的模型,在那里我可以找到相似的东西。

简单来说,如果我在模型上搜索 t-shirt,我希望查询附近有 T 恤 SKU。

我尝试使用具有不同属性的 gensim(我是这个库的新手)来构建模型:

from gensim.models.callbacks import CallbackAny2Vec

class callback(CallbackAny2Vec):
    '''Callback to print loss after each epoch.'''

    def __init__(self):
        self.epoch = 0
        self.loss_to_be_subed = 0

    def on_epoch_end(self, model):
        loss = model.get_latest_training_loss()
        loss_now = loss - self.loss_to_be_subed
        self.loss_to_be_subed = loss
        print('Loss after epoch {}: {}'.format(self.epoch, loss_now))
        self.epoch += 1

model = Word2Vec(
  sentences=sentences, 
  vector_size=100, 
  window=1000, 
  min_count=2, 
  workers=-1,
  epochs=10,
#   negative=5,
  compute_loss=True,
  callbacks=[callback()]
)

我得到了这个输出:

Loss after epoch 0: 0.0
Loss after epoch 1: 0.0
Loss after epoch 2: 0.0
Loss after epoch 3: 0.0
Loss after epoch 4: 0.0
Loss after epoch 5: 0.0
Loss after epoch 6: 0.0
Loss after epoch 7: 0.0
Loss after epoch 8: 0.0
Loss after epoch 9: 0.0

全部亏损0!!! 我开始怀疑这一点。

注意:sentences 的每个元素都是独立的,我希望图书馆不要尝试在不同的数组中混合不同的术语。

为了测试模型,我尝试了一个非常频繁的查询,如 model.wv.most_similar('query_t-shirt', topn=100),结果完全荒谬。

是我的想法很疯狂还是我使用的库不正确?

workers=-1 不是有效的参数值。如果有一个例子表明某处是负计数,那它就是一个不好的例子。如果您觉得 Gensim 官方文档中的某些内容可以工作,请将该文档报告为要修复的错误。

更一般地说:在 INFO 级别启用日志记录将显示有关正在发生的事情的更多详细信息,并且在使用此类日志记录时,诸如“阻止任何训练发生的错误参数”之类的内容可能会变得更加明显。

分开:

  • Gensim 的 Word2Vec 损失跟踪有很多未解决的问题(包括无法按纪元计算,您的 Callback 试图纠正)。我建议不要对损失显示感到困惑 unless/until 没有它你已经取得了一些成功。

  • 如此低的 min_count=2 对于 word2vec 算法通常是个坏主意,至少在正常的自然语言设置中是这样。出现次数如此之少的词缺乏各种对比用法示例来实现可概括的词向量,或者与数量更多的其他词相比,单独地影响模型。但是,这些不常见的词加在一起数量相当多——本质上是 'noise' 使其他词变得更糟。丢弃更多此类稀有词通常会显着改善剩余词和整体模型。因此,如果您有足够的原始训练数据来使 word2vec 值得应用,那么 增加 高于默认值 min_count=5 的截止值应该比降低它更常见。

  • 对于由不完全类似于自然语言的伪文本提供的类似推荐的系统,使用 ns_exponent 参数进行试验可能特别值得。根据 the research paper linked in the class docs,原始 ns_exponent=0.75 值在早期的 word2vec 实现中是一个不可更改的常量,对于推荐系统等其他应用程序可能并不理想。