Dense Passage Retrieval — 密集段落检索:超越关键词的语义搜索基础设施
Skill-Dense-Passage-Retrieval · 08-知识图谱
causalexperimentrecommendationragknowledge_graph广告与投放客服与VOC推荐与搜索知识图谱与RAGWF-B 广告优化WF-C 客服分诊WF-D 选品扫描WF-I 智能体工程WF-J DTC 独立站增长
年化 ROI¥15-45 万
实现难度⭐⭐⭐☆☆
业务视角
适用角色选品负责人 / 运营负责人 · 数据分析师 · 供应链负责人
适用平台Amazon 品类体系 · 竞品 ASIN 网络分析
什么情况下用品类很多,不清楚品类间的关联,没法做系统性类目扩张规划;竞品矩阵太复杂,品牌/SKU/渠道理不清
成功是什么样的建立品类知识图谱,清晰看到哪些是入口品/引流品/利润品,指导下一步选品扩张方向
业务痛点
1. 解决的问题
独立站搜索「安静吸奶器」找不到「low noise breast pump」的产品因为BM25只做关键词匹配——DPR密集向量检索捕捉语义相似度,搜索Recall@10提升25-40%长尾查询和多语言搜索大幅改善年化GMV增益15-45万元
2. 核心算法逻辑
BM25 vs DPR:
3. 业务应用场景
业务问题:独立站的 BM25 搜索对以下场景效果差: - "portable pump"找不到"wearable breast pump"(同义词) - "hospital grade"找不到"医院级"(多语言) - 长句查询:"pump that won't wake sleeping baby"
用 DPR 改造后,这些查询都能找到正确的商品。
数据要求: - 商品标题+要点(用于生成商品向量) - 可选:查询-商品相关性数据(用于微调)
4. 输入数据要求
请查看原始代码模板获取输入规格。
5. 输出结果
请查看原始代码模板获取输出规格。
6. 业务价值 / ROI
- ROI 预估:
- 搜索 Recall@10 提升 25-40%:搜索转化率提升,月增 GMV ¥5-15 万
- 长尾查询覆盖:原来找不到的词现在能找到,新增潜在转化
- 多语言搜索改善(英文搜索找到中文产品)
- 年化综合 ROI:¥15-45 万
- 实施难度:⭐⭐⭐☆☆(sentence-transformers 有开源预训练模型;FAISS 成熟;约 3-4 周)
7. 代码模板
代码块数量:5 · 路径:未检测到
"""
Dense Passage Retrieval
DPR语义搜索:超越BM25的密集向量检索
生产: pip install faiss-cpu sentence-transformers
"""
import numpy as np
import re
from collections import defaultdict
def simple_bm25_score(query: str, doc: str, k1: float = 1.5, b: float = 0.75) -> float:
"""简化版 BM25 评分(生产用 rank_bm25 库)"""
query_terms = query.lower().split()
doc_terms = doc.lower().split()
doc_len = len(doc_terms)
avg_doc_len = 50 # 假设平均文档长度
tf_dict = defaultdict(int)
for term in doc_terms:
tf_dict[term] += 1
score = 0
for term in query_terms:
tf = tf_dict.get(term, 0)
# BM25 TF 归一化
tf_norm = tf * (k1 + 1) / (tf + k1 * (1 - b + b * doc_len / avg_doc_len))
# IDF 近似(假设简单值)
idf = 1.0 if tf > 0 else 0
score += idf * tf_norm
return score
class SimpleDPR:
"""
DPR 简化实现(无需 BERT,用 TF-IDF 近似嵌入)
生产代码:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('multi-qa-MiniLM-L6-cos-v1')
embeddings = model.encode(documents)
"""
def __init__(self, embed_dim: int = 64):
self.embed_dim = embed_dim
self.doc_embeddings = {}
self.doc_texts = {}
self.vocab = {}
def _text_to_embedding(self, text: str) -> np.ndarray:
"""TF-IDF 近似嵌入(生产替换为 BERT 嵌入)"""
text_lower = text.lower()
words = re.findall(r'\w+', text_lower)
# 简单字符 n-gram 嵌入
vec = np.zeros(self.embed_dim)
for word in words:
for i in range(0, len(word), 2):
gram = word[i:i+4]
gram_hash = hash(gram) % self.embed_dim
vec[gram_hash] += 1.0 / len(words)8. 论文来源
- 2004.04906
- 2004.12832