You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gensim Word2Vec报KeyError:'word not in vocabulary'问题排查

问题描述

基于Word2Vec实现商品相似度计算时,已构建键为item_id、值为对应商品名称的映射字典,示例结构如下:

dict_items([
    ('100018', ['GRAVY MIX PEPPER']), 
    ('100025', ['SNACK CHEEZIT WHOLEGRAIN']), 
    ('100040', ['CAULIFLOWER CELLO 6 CT.']), 
    ('100042', ['STRIP FRUIT FLY ELIMINATOR'])
    # 其余商品省略
])

传入字典中存在的item_id调用模型相似度计算逻辑时,触发报错:

KeyError: "word '100018' not in vocabulary"

涉及的核心代码如下:

# 模型训练
model = Word2Vec(window = 10, sg = 1, hs = 0,
             negative = 10, # 负采样配置
             alpha=0.03, min_alpha=0.0007,
             seed = 14)
model.build_vocab(purchases_train, progress_per=200)
model.train(purchases_train, total_examples = model.corpus_count, 
        epochs=10, report_delay=1)

# 相似度查询函数
def similar_products(v, n = 6):
    # 提取输入向量最相似的商品
    ms = model.similar_by_vector(v, topn= n+1)[1:]
    # 拼接商品名和相似度得分
    new_ms = []
    for j in ms:
        pair = (products_dict[j[0]][0], j[1])
        new_ms.append(pair)
    return new_ms    

函数调用方式:

similar_products(model['100018'])
报错根因

Word2Vec的词汇表仅由传入model.build_vocab()的训练语料purchases_train生成,和后续做名称映射的products_dict完全独立,二者不存在自动同步机制。触发KeyError的核心原因共三类:

  • 训练语料格式不匹配:purchases_train的标准格式为二维列表,每个外层元素对应一个用户的购买行为序列,内层列表元素必须是与products_dict键完全一致的字符串类型item_id。如果语料中存储的是整数类型ID、商品名称文本,或是存在多余的列表嵌套,字符串'100018'就不会被识别为有效训练词元,自然不会加入词汇表。
  • 低频商品被默认规则过滤:当前模型初始化代码未显式设置min_count参数,Gensim实现的Word2Vec默认min_count=5,即仅当某个item_id在全量购买序列中累计出现不少于5次时,才会被纳入词汇表,出现次数不足的低频商品会在词表构建阶段被直接丢弃,即便该ID存在于products_dict中也无法查询。
  • 新版本接口兼容问题:Gensim 4.0及以上版本调整了词向量的存储与调用逻辑,旧版本直接通过model['xxx']读取词向量的写法存在兼容问题,也会触发词不存在的报错。
修复方案

按以下步骤逐一排查修复即可:

  1. 校验训练语料格式
    随机抽取purchases_train中的3-5条序列打印检查,确认格式符合要求,无类型错误、嵌套错误。正确格式示例如下:
    # purchases_train 正确格式参考
    [
        ['100018', '100025', '100040'], # 第一个用户的购买序列
        ['100042', '100018', '100090']  # 第二个用户的购买序列
    ]
    
  2. 显式设置词频过滤阈值
    初始化Word2Vec模型时,根据自身数据集规模设置min_count参数,小数据集可直接设为1,保证所有出现过的商品ID都能被纳入词汇表,修改后的模型初始化代码:
    model = Word2Vec(
        window = 10, 
        sg = 1, 
        hs = 0,
        negative = 10,
        alpha=0.03, 
        min_alpha=0.0007,
        seed = 14,
        min_count=1 # 新增:词频过滤阈值设为1,不丢弃低频商品
    )
    
  3. 适配新版本Gensim接口
    模型训练完成后,统一通过model.wv属性访问词向量、调用相似度方法,替换旧版直接调用model的写法。首先做词表校验,确认目标ID存在后再做查询:
    # 词表校验
    print("词表总商品数:", len(model.wv.key_to_index))
    print("100018是否在词表中:", '100018' in model.wv.key_to_index)
    
    # 修正后的相似度查询调用
    similar_products(model.wv['100018'])
    
    同时修改相似度函数内的相似查询逻辑,适配新版接口:
    def similar_products(v, n = 6):
        # 修正为通过wv属性调用相似查询
        ms = model.wv.similar_by_vector(v, topn= n+1)[1:]
        new_ms = []
        for j in ms:
            pair = (products_dict[j[0]][0], j[1])
            new_ms.append(pair)
        return new_ms
    

内容的提问来源于stack exchange,提问作者Neo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 23:13:00