Doc2Vec使用与模型选择:商品分类向量转换问题求助
商品分类任务中词嵌入(Word2Vec/Doc2Vec)问题解决
一、你的Doc2Vec代码核心错误
当前tagged_document函数逻辑完全偏离了Doc2Vec的要求:
- Doc2Vec要求每个物品名作为一个独立文档,对应一个
TaggedDocument,其中words是该物品名拆分后的单词列表,tags是该文档的唯一标识(比如数据集中的行索引)。 - 但你的代码把每个物品名拆成单个单词,每个单词单独生成
TaggedDocument,还将单词在句子中的位置作为标签。这会导致Gensim将单个字符当作"单词"处理(因为传入的word是字符串,会被拆分为字符序列),最终wv.vocab里全是单个字符,完全不符合预期。
修正后的代码实现
from gensim.models import Doc2Vec import pandas as pd # 示例数据集(替换为你的真实数据) df = pd.DataFrame({ 'item_name': ['unsalted butter', 'cheese', 'peanut butter cream'], 'category': ['dairy and eggs', 'dry grocery', 'dry grocery'] }) # 正确生成训练用的TaggedDocument def generate_tagged_docs(text_series): for idx, text in enumerate(text_series): # 每个物品名对应一个文档,标签用唯一索引,words是拆分后的单词列表 yield Doc2Vec.TaggedDocument(words=text.split(), tags=[idx]) training_data = list(generate_tagged_docs(df['item_name'])) # 初始化并训练Doc2Vec模型 # 注意:min_count设为1,避免低频商品词汇被过滤 model = Doc2Vec(vector_size=150, window=4, min_count=1, workers=10, epochs=30) model.build_vocab(training_data) model.train(training_data, total_examples=model.corpus_count, epochs=model.epochs) # 保存模型 model.save('item_category_doc2vec.model') # 查看正常的词汇表 print(list(model.wv.vocab.keys()))
二、Doc2Vec的正确使用方式
训练完成后,可通过两种方式获取物品名的向量:
- 获取已训练文档的向量:直接通过训练时的文档标签(行索引)提取
# 获取第一条数据"unsalted butter"的向量 item_vec = model.dv[0] - 推断新物品名的向量:对未出现在训练集中的物品名,用
infer_vector生成向量new_item = "salted butter" new_item_vec = model.infer_vector(new_item.split())
三、自有数据集训练vs预训练模型选择
- 自有数据集足够大(万级以上物品名):优先用自有数据训练。预训练模型(如Google Word2Vec)基于通用文本训练,对商品领域的专业词汇(如食品细分术语)语义理解远不如领域专属数据精准。
- 自有数据集较小(千级以内):建议复用预训练词向量。加载预训练Word2Vec模型后,将物品名中所有单词的向量取平均(或加权平均),作为该物品的特征向量,这样能利用通用语义知识弥补数据量不足的问题。
四、Word2Vec的效果验证
Word2Vec是无监督模型,没有直接的"准确率"指标,可通过两种方式验证效果:
- 语义相似度验证:检查同类商品词汇的向量相似度是否更高。比如"butter"和"unsalted"的相似度应高于"butter"和"cheese"的相似度。
from sklearn.metrics.pairwise import cosine_similarity from gensim.models import Word2Vec # 训练Word2Vec模型 word_corpus = [text.split() for text in df['item_name']] word2vec_model = Word2Vec(sentences=word_corpus, vector_size=150, window=4, min_count=1, workers=10, epochs=30) # 计算词汇相似度 sim_butter_unsalted = cosine_similarity([word2vec_model.wv['butter']], [word2vec_model.wv['unsalted']])[0][0] sim_butter_cheese = cosine_similarity([word2vec_model.wv['butter']], [word2vec_model.wv['cheese']])[0][0] print(f"butter与unsalted相似度: {sim_butter_unsalted:.4f}") print(f"butter与cheese相似度: {sim_butter_cheese:.4f}") - 下游分类任务验证:将生成的向量输入KNN模型,通过分类任务的准确率、F1值等指标验证效果——这是最直接的方式,因为词嵌入的最终目标是提升下游任务性能。拆分数据集为训练集和测试集,训练KNN后评估即可。
内容的提问来源于stack exchange,提问作者Mayar Alzerki
相关产品推荐
相关产品推荐

