from transformers import BertTokenizer, BertModel import torch # 初始化BERT模型 tokenizer = BertTokenizer.from_pretrained(bert-base-chinese) model = BertModel.from_pretrained(bert-base-chinese) def text_to_embedding(text): # 文本预处理 inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True) # 获取隐藏状态 with torch.no_grad(): outputs = model(**inputs) # 使用[CLS] token的输出作为句子表示 sentence_embedding = outputs.last_hidden_state[:, 0, :] return sentence_embedding.numpy()[0] # 示例文本 embeddings = [text_to_embedding(text) for text in texts] print(f"向量维度: {len(embeddings[0])}") print(f"向量数量: {len(embeddings)}")
from sentence_transformers import SentenceTransformer # 初始化SBERT模型 model = SentenceTransformer(paraphrase-MPnet-base-v2) # 示例文本 texts = [ "人工智能改变世界", "机器学习推动科技进步", "深度学习突破传统算法" ] # 直接向量化 embeddings = model.encode(texts) print(f"向量维度: {len(embeddings[0])}") print(f"向量数量: {len(embeddings)}") # 计算相似度 similarities = model.similarity(embeddings, embeddings) print(f"相似度矩阵: {similarities.shape}")
索引机制直接影响知识库的检索效率和准确性。不同的索引策略适用于不同的应用场景。
原理:建立词项到文档的映射关系
优点:查询速度快,支持布尔检索
缺点:语义理解能力弱
适用场景:传统搜索引擎,关键词匹配
原理:基于向量相似度的检索
优点:语义理解能力强
缺点:计算复杂度高
适用场景:语义检索,推荐系统
原理:结合倒排索引和向量索引
优点:兼顾速度和语义理解
缺点:实现复杂度高
适用场景:企业级应用,多维度检索
| 索引类型 | 建立时间 | 查询速度 | 语义能力 | 存储开销 | 适用场景 |
|---|---|---|---|---|---|
| 倒排索引 | 快 | 极快 | 弱 | 小 | 关键词搜索 |
| 向量索引 | 慢 | 慢 | 强 | 大 | 语义检索 |
| 混合索引 | 中 | 中 | 中 | 中 | 综合检索 |
特点:多层图结构,高效的近似最近邻搜索
优势:查询速度快,内存占用合理
适用场景:大规模向量检索
特点:基于聚类向量空间划分
优势:查询精度高,支持增量更新
适用场景:高精度要求的检索任务
特点:基于哈希的相似性搜索
优势:内存占用小,查询速度快
适用场景:实时检索系统
原理:将高维向量压缩为低维向量
方法:PQ(Product Quantization),SQ(Scalar Quantization)
优势:减少存储空间,提升查询速度
缺点:轻微损失精度
原理:不同重要性的文档使用不同索引策略
方法:热数据使用HNSW,冷数据使用IVF
优势:平衡性能和资源使用
原理:索引增量更新而非全量重建
方法:LSM树结构,批量更新
优势:减少停机时间,提升用户体验
from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType # 连接Milvus connections.connect("default", host="localhost", port="19530") # 定义schema schema = CollectionSchema([ FieldSchema("id", DataType.INT64, is_primary=True), FieldSchema("vector", DataType.FLOAT_VECTOR, dim=768) ]) # 创建collection collection = Collection("knowledge_base", schema) # 创建HNSW索引 index_params = { "metric_type": "L2", "index_type": "HNSW", "params": {"ef": 40, "M": 16} } collection.create_index("vector", index_params) # 加载数据 collection.load() print("索引创建完成")
import faiss import numpy as np # 创建示例数据 num_vectors = 1000 dimension = 768 vectors = np.random.random((num_vectors, dimension)).astype(float32) # 创建IVF索引 nlist = 100 # 聚类中心数量 quantizer = faiss.IndexFlatL2(dimension) index = faiss.IndexIVFFlat(quantizer, dimension, nlist, faiss.METRIC_L2) # 训练索引 index.train(vectors) # 添加向量 index.add(vectors) print(f"FAISS索引创建完成,包含{index.ntotal}个向量")
检索算法是知识库系统的核心,决定了用户查询的准确性和响应速度。
原理:计算向量间夹角的余弦值
公式:cos(θ) = (A·B) / (|A|·|B|)
优点:对向量长度不敏感,语义匹配效果好
缺点:计算复杂度较高
适用场景:语义相似度计算
原理:计算向量间的欧氏距离
公式:d = √∑(xi-yi)²
优点:几何意义明确
缺点:受向量长度影响
适用场景:距离计算
原理:计算向量的内积
公式:sim = A·B
优点:计算速度快
缺点:受向量长度影响
适用场景:归一化向量的相似度计算
原理:计算集合的交集与并集之比
公式:J(A,B) = |A∩B| / |A∪B|
优点:适合文本相似度计算
缺点:需要预处理
适用场景:文本去重,重复检测
原理:改进的TF-IDF算法
公式:score = log((1-b+b*avgdl/doclen)) * idf * term_freq
优点:传统文本检索的黄金标准
缺点:语义理解能力有限
适用场景:关键词检索
| 算法 | 计算复杂度 | 准确率 | 速度 | 适用场景 |
|---|---|---|---|---|
| 余弦相似度 | O(n) | 高 | 中 | 语义检索 |
| 欧氏距离 | O(n) | 中 | 快 | 距离计算 |
| 内积相似度 | O(n) | 中 | 最快 | 归一化向量 |
| Jaccard | O(n) | 中 | 中 | 文本相似度 |
| BM25 | O(n) | 中 | 快 | 关键词搜索 |
原理:先粗检索再精检索
方法:First-stage + Second-stage检索
优势:平衡准确率和速度
原理:减少向量维度
方法:PCA降维,特征选择
优势:减少计算量,提升速度
原理:缓存热门查询结果
方法:LRU缓存,Redis缓存
优势:提升响应速度
原理:预先加载常用数据
方法:MMap内存映射
优势:减少首次查询延迟
import numpy as np from sklearn.metrics.pairwise import cosine_similarity def cosine_similarity_vec(vec1, vec2): """计算两个向量的余弦相似度""" return np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2)) # 批量计算相似度 def batch_cosine_similarity(query_vec, doc_vectors): """批量计算查询向量与文档向量的相似度""" similarities = [] for doc_vec in doc_vectors: sim = cosine_similarity_vec(query_vec, doc_vec) similarities.append(sim) return similarities # 示例数据 query_vec = np.random.random(768) doc_vectors = [np.random.random(768) for _ in range(100)] # 计算相似度 similarities = batch_cosine_similarity(query_vec, doc_vectors) print(f"相似度范围: {min(similarities):.4f} - {max(similarities):.4f}")
class HybridRetriever: """混合检索器-结合关键词和语义检索""" def __init__(self, bm25_index, vector_index, alpha=0.7): self.bm25_index = bm25_index self.vector_index = vector_index self.alpha = alpha # 语义检索权重 self.beta = 1 - alpha # 关键词检索权重 def search(self, query, top_k=10): # 关键词检索 bm25_results = self.bm25_index.search(query, top_k * 2) # 语义检索 query_vec = self.vector_index.embed(query) semantic_results = self.vector_index.search(query_vec, top_k * 2) # 融合结果 fused_results = self._fusion_results(bm25_results, semantic_results) return fused_results[:top_k] def _fusion_results(self, bm25_results, semantic_results): """融合两种检索结果""" # 这里可以实现复杂的重排序算法 # 简化的版本:直接按加权分数合并 result_scores = {} # BM25分数加权 for doc_id, score in bm25_results: result_scores[doc_id] = result_scores.get(doc_id, 0) + score * self.beta # 语义分数加权 for doc_id, score in semantic_results: result_scores[doc_id] = result_scores.get(doc_id, 0) + score * self.alpha # 按分数排序 sorted_results = sorted(result_scores.items(), key=lambda x: x[1], reverse=True) return sorted_results
定义:检索结果中相关文档的比例
公式:Precision = TP / (TP + FP)
适用场景:评估检索结果的相关性
定义:相关文档被检索到的比例
公式:Recall = TP / (TP + FN)
适用场景:评估检索的覆盖范围
定义:准确率和召回率的调和平均
公式:F1 = 2 × (Precision × Recall) / (Precision + Recall)
适用场景:综合评估检索效果
定义:第一个相关文档位置的倒数
公式:MRR = 1/pos,其中pos是第一个相关文档的位置
适用场景:评估相关文档的排名质量
通过深入理解核心架构设计,我们能够更好地评估不同知识库工具的技术特点,为后续的功能评测打下坚实基础。