如何基于Token Embedding实现SKU商品语义搜索?方案优化问询
问题背景与需求
我有1000条带SKU的商品描述数据,想通过生成逆嵌入映射实现语义搜索。数据示例如下:
item description item1 [word1, word2, word3, word4..........] item2 [word1, word2_2, word3_3, word4_4..........]
可以看到item1和item2共享word1,但语境不同,希望Embedding能捕捉词汇的语境信息。
我用以下代码生成Token级Embedding:
my_description = [] with open('/content/gdrive/My Drive/my.csv', 'r') as data: df = pd.read_csv(data, encoding = ('utf-8'),nrows=100) for index, row in df.iterrows(): my_str = row['description'] my_description.append(my_str) import torch from transformers import BertTokenizer, BertModel %matplotlib inline tokenizer = BertTokenizer.from_pretrained('bert-base-uncased') model = BertModel.from_pretrained('bert-base-uncased', output_hidden_states = True, # Whether the model returns all hidden-states. ) model.eval() text2 = company_description[0] # Add the special tokens. marked_text2 = "[CLS] " + text2 + " [SEP]" # Split the sentence into tokens. tokenized_text2 = tokenizer.tokenize(marked_text2) # Map the token strings to their vocabulary indeces. indexed_tokens2 = tokenizer.convert_tokens_to_ids(tokenized_text2) segments_ids2 = [1] * len(tokenized_text2) tokens_tensor2 = torch.tensor([indexed_tokens2]) segments_tensors2 = torch.tensor([segments_ids2]) with torch.no_grad(): outputs2 = model(tokens_tensor2, segments_tensors2) hidden_states2 = outputs2[2] token_embeddings2 = torch.stack(hidden_states2, dim=0) token_embeddings2.size() token_embeddings2 = torch.squeeze(token_embeddings2, dim=1) token_embeddings2.size() token_embeddings2 = token_embeddings2.permute(1,0,2) token_embeddings2.size() token_vecs_cat2 = [] for token in token_embeddings2: cat_vec = torch.cat((token[-1], token[-2], token[-3], token[-4]), dim=0) token_vecs_cat2.append(cat_vec) token_vecs_sum2 = [] import numpy as np x_token = np.empty((0, 768)) for token in token_embeddings2: sum_vec = torch.sum(token[-4:], dim=0) token_vecs_sum2.append(sum_vec) x_token = np.concatenate((x_token, sum_vec.numpy().reshape((1,-1))), axis=0)
生成的x_token是单条描述中所有Token的Embedding,比如item1有500个Token时,x_token维度为(500×768)。最终每个商品的Token与Embedding对应关系如下:
item token embeddings item 1 token 1 [x1,x2,x3,.....] item 1 token 2 [x1,x2,x3,.....] .... item 2 token 1_2 [x1,x2,x3,.....] item 2 token 2_2 [x1,x2,x3,.....] .... item n token 1_n [x1,x2,x3,.....] item n token 2_n [x1,x2,x3,.....]
核心问题
- 当查询语句是
"word1 word2 word3.....wordn"时,我为每个查询Token生成Embedding,再用ANN搜索每个Token的Top10近邻商品(比如10个查询Token会得到100条候选商品),请问怎么筛选出最终的Top10商品?应该侧重哪些Token?示例如下:
query = [token1, token2.......tokenN] top 10 nearest_neighbor's item, query_token1 -> [itemx1_1, itemx1_2, itemx1_10] query_token2 -> [itemx2_1, itemx2_2, itemx2_10]
- 当前的语义搜索思路是否存在问题?
解决方案与思路分析
一、候选商品筛选方案
1. 综合得分排序法
针对所有候选商品,计算其综合匹配度后排序取Top10,具体有两种实现方式:
- 加权计数得分:统计商品出现在各查询Token Top10结果中的次数,同时给不同排名赋予权重(比如Top1权重10、Top2权重9...Top10权重1),最后累加每个商品的总权重。例如商品A出现在query_token1的Top3(权重8)和query_token3的Top1(权重10),总得分即为18。
- 相似度加权得分:保留每个查询Token与对应商品Token的相似度值,对同一商品的所有相似度值取平均或求和,再按最终值排序。这种方式比单纯计数更精准,能体现匹配的紧密程度。
2. 高价值查询Token的侧重方向
优先关注以下类型的Token:
- 实体类Token:如商品品牌、型号、核心功能词(比如"无线耳机"中的"无线""耳机"),这类Token语境区分度高,对匹配精准商品作用显著。
- 低频率Token:查询中的稀有词、专有名词、特定技术参数,这类词能快速缩小候选范围,提升搜索精准度。
- 直接排除停用词:像"的""是"这类通用停用词,Embedding区分度极低,对搜索帮助很小,可直接跳过此类Token的ANN搜索。
二、当前思路的问题分析
- Token级Embedding冗余:每个商品生成大量Token级Embedding,存储和检索成本高,且多数通用Token对搜索贡献有限。
- 缺乏商品级整体语义表示:当前仅做Token级映射,但用户搜索的是商品整体而非单个Token。建议生成商品描述的整体Embedding(比如用
[CLS]Token的Embedding,或对所有Token Embedding做平均/池化),直接用商品级Embedding做ANN搜索,效率和精准度都会更高。 - 语境捕捉的局限性:使用通用的
bert-base-uncased对电商商品描述适配性不足,建议替换为电商领域预训练BERT模型,能更好捕捉商品语境下的词汇含义,提升Embedding的区分度。 - 代码效率偏低:当前代码单条处理商品描述,建议改为批量处理,减少模型调用次数,提升Embedding生成速度。
内容的提问来源于stack exchange,提问作者olaf
相关产品推荐
相关产品推荐

