4.2.2 分层召回架构(下) — AI搜索技术内幕 高级召回策略 本节导读:继续深入理解分层召回架构的高级实现,包括召回质量评估、性能调优和最佳实践,构建完整的分层召回解决方案。 步骤 5:召回质量评估系统 建立完善的召回质量评估体系: 步骤 6:完整分层召回系统实现 下面是一个完整的分层召回系统实现: 常见问题 FAQ Q1:分层召回和多级检索有什么区别? A:分层召回是一个更广泛的概念,包含多级检索、混合检索等多种策略。多级检索特指按照严格顺序进行多级过滤的策略。 Q2:如何确定各层的最佳参数?
本节导读:继续深入理解分层召回架构的高级实现,包括召回质量评估、性能调优和最佳实践,构建完整的分层召回解决方案。
建立完善的召回质量评估体系:
import matplotlib.pyplot as plt import seaborn as sns from sklearn.metrics import precision_score, recall_score, f1_score import pandas as pd class RecallEvaluation: """召回质量评估系统""" def __init__(self): """初始化评估系统""" self.evaluation_results = [] self.ground_truth = None def set_ground_truth(self, ground_truth: Dict): """设置 ground truth""" self.ground_truth = ground_truth def evaluate_recall(self, predicted_indices: List[int], k: int) -> Dict: """评估召回质量""" if self.ground_truth is None: raise ValueError("未设置 ground truth") # 获取预测的相关结果 predicted_relevant = set(predicted_indices[:k]) # 获取实际的相关结果 actual_relevant = set(self.ground_truth['relevant_indices']) # 计算 TP, FP, FN tp = len(predicted_relevant & actual_relevant) fp = len(predicted_relevant - actual_relevant) fn = len(actual_relevant - predicted_relevant) # 计算指标 precision = tp / (tp + fp) if (tp + fp) > 0 else 0 recall = tp / (tp + fn) if (tp + fn) > 0 else 0 f1 = 2 * precision * recall / (precision + recall) if (precision + recall) > 0 else 0 return { 'k': k, 'precision': precision, 'recall': recall, 'f1': f1, 'tp': tp, 'fp': fp, 'fn': fn, 'precision_at_k': precision, 'recall_at_k': recall } def evaluate_multiple_methods(self, results: Dict, k: int) -> Dict: """评估多种方法的召回质量""" evaluation_summary = {} for method_name, method_results in results.items(): if method_results: evaluation = self.evaluate_recall(method_results['indices'], k) evaluation_summary[method_name] = evaluation return evaluation_summary def plot_evaluation_results(self, evaluation_results: Dict): """绘制评估结果""" # 准备数据 methods = list(evaluation_results.keys()) precision_scores = [evaluation_results[m]['precision'] for m in methods] recall_scores = [evaluation_results[m]['recall'] for m in methods] f1_scores = [evaluation_results[m]['f1'] for m in methods] # 创建图表 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6)) # 精确率和召回率对比 x = np.arange(len(methods)) width = 0.35 ax1.bar(x - width/2, precision_scores, width, label='Precision') ax1.bar(x + width/2, recall_scores, width, label='Recall') ax1.set_xlabel('Methods') ax1.set_ylabel('Score') ax1.set_title('Precision and Recall Comparison') ax1.set_xticks(x) ax1.set_xticklabels(methods, rotation=45) ax1.legend() # F1分数对比 ax2.bar(methods, f1_scores) ax2.set_xlabel('Methods') ax2.set_ylabel('F1 Score') ax2.set_title('F1 Score Comparison') ax2.set_xticklabels(methods, rotation=45) plt.tight_layout() plt.savefig('/tmp/recall_evaluation.png') print(f"评估图表已保存到 /tmp/recall_evaluation.png") def generate_evaluation_report(self, evaluation_results: Dict) -> str: """生成评估报告""" report = "=== 召回质量评估报告 ===\n\n" # 总体统计 report += "总体统计:\n" report += f"评估方法数: {len(evaluation_results)}\n" report += f"平均精确率: {np.mean([r['precision'] for r in evaluation_results.values()]):.4f}\n" report += f"平均召回率: {np.mean([r['recall'] for r in evaluation_results.values()]):.4f}\n" report += f"平均F1分数: {np.mean([r['f1'] for r in evaluation_results.values()]):.4f}\n\n" # 各方法详细结果 report += "各方法详细结果:\n" for method, result in evaluation_results.items(): report += f"\n{method}:\n" report += f" Precision@{result['k']}: {result['precision']:.4f}\n" report += f" Recall@{result['k']}: {result['recall']:.4f}\n" report += f" F1 Score: {result['f1']:.4f}\n" report += f" TP: {result['tp']}, FP: {result['fp']}, FN: {result['fn']}\n" return report # 测试召回质量评估 print("\n=== 召回质量评估测试 ===") evaluation = RecallEvaluation() # 设置 ground truth(模拟) ground_truth = { 'relevant_indices': [1, 5, 10, 15, 20, 25, 30, 35, 40, 45] } evaluation.set_ground_truth(ground_truth) # 模拟不同方法的召回结果 method_results = { 'exact_search': { 'indices': [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] }, 'hnsw_search': { 'indices': [1, 4, 5, 8, 10, 12, 15, 18, 20, 22] }, 'ivf_search': { 'indices': [2, 5, 6, 9, 10, 14, 15, 16, 21, 25] }, 'hybrid_search': { 'indices': [1, 5, 10, 15, 20, 25, 30, 35, 40, 45] } } # 评估各种方法 evaluation_results = evaluation.evaluate_multiple_methods(method_results, k=10) print(evaluation.generate_evaluation_report(evaluation_results)) # 绘制评估结果 evaluation.plot_evaluation_results(evaluation_results)
下面是一个完整的分层召回系统实现:
class AdvancedHierarchicalRecallSystem: """高级分层召回系统""" def __init__(self, vectors: np.ndarray): """初始化系统""" self.vectors = vectors self.multi_stage_system = MultiStageRetrieval(vectors, self._get_stage_configs()) self.hybrid_system = HybridRetrieval(vectors) self.distributed_system = DistributedRetrieval() self.adaptive_system = AdaptiveRetrieval(None, SystemMonitor()) self.evaluation_system = RecallEvaluation() # 设置评估的ground truth self.evaluation_system.set_ground_truth({ 'relevant_indices': np.random.choice(len(vectors), 20, replace=False).tolist() }) def _get_stage_configs(self) -> List[Dict]: """获取多级检索配置""" return [ { 'name': '粗粒度召回', 'type': 'hnsw', 'k': 1000, 'M': 32 }, { 'name': '中等精度筛选', 'type': 'ivf', 'k': 100, 'nprobe': 10 }, { 'name': '精确排序', 'type': 'exact', 'k': 10 } ] def compare_strategies(self, query_vector: np.ndarray, k: int = 10) -> Dict: """比较不同召回策略""" results = {} # 多级检索 start_time = time.time() indices, scores = self.multi_stage_system.search(query_vector, k) results['multi_stage'] = { 'indices': indices, 'scores': scores, 'time': time.time() - start_time } # 混合检索 start_time = time.time() indices, scores = self.hybrid_system.search(query_vector, k) results['hybrid'] = { 'indices': indices, 'scores': scores, 'time': time.time() - start_time } # 分布式检索 start_time = time.time() indices, scores = self.distributed_system.search_distributed(query_vector, k) results['distributed'] = { 'indices': indices, 'scores': scores, 'time': time.time() - start_time } # 自适应检索 start_time = time.time() indices, scores = self.adaptive_system.search(query_vector, k) results['adaptive'] = { 'indices': indices, 'scores': scores, 'time': time.time() - start_time } return results def generate_comprehensive_report(self, query_vector: np.ndarray, k: int = 10): """生成综合性能报告""" print("=== 分层召回系统综合测试 ===") # 比较策略 results = self.compare_strategies(query_vector, k) # 评估质量 evaluation_results = self.evaluation_system.evaluate_multiple_methods(results, k) # 生成报告 report = self.evaluation_system.generate_evaluation_report(evaluation_results) # 添加性能信息 report += "\n性能信息:\n" for method, result in results.items(): report += f"{method}: {result['time']:.4f}秒\n" # 绘制评估结果 self.evaluation_system.plot_evaluation_results(evaluation_results) print(report) return report # 使用示例 print("\n=== 完整分层召回系统测试 ===") system = AdvancedHierarchicalRecallSystem(vectors) # 测试查询 query_vector = np.random.randn(128).astype('float32') query_vector = query_vector / np.linalg.norm(query_vector) # 生成综合报告 report = system.generate_comprehensive_report(query_vector, k=10) # 保存报告 with open('/tmp/hierarchical_recall_report.md', 'w', encoding='utf-8') as f: f.write(report) print("综合报告已保存到 /tmp/hierarchical_recall_report.md")
A:分层召回是一个更广泛的概念,包含多级检索、混合检索等多种策略。多级检索特指按照严格顺序进行多级过滤的策略。
A:参数确定需要考虑:
A:权重设置方法:
A:保证一致性的方法:
A:切换策略设计要点:
本节深入介绍了分层召回架构的高级技术,涵盖:
通过本节的学习,读者应该能够设计和实现高性能的分层召回系统,掌握各种高级召回策略的实现方法和优化技巧。
下一步:在下一节中,我们将深入探讨召回策略的第三个核心技术模块,包括召回质量评估和性能调优等内容。