
1) 【一句话结论】
根据数据规模和实时性需求选择合适的数据结构:小规模数据用Trie树快速构建词表并计算相似度,大规模/实时场景用倒排索引结合哈希/向量量化优化余弦相似度计算,通过空间换时间提升效率。
2) 【原理/概念讲解】
首先明确文本相似度计算的核心是向量空间模型:将文本转化为词向量(如TF-IDF、词频向量),通过余弦相似度(公式:( \text{sim}(A,B) = \frac{A \cdot B}{|A||B|} ))计算向量夹角余弦值。
3) 【对比与适用场景】
| 数据结构 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| Trie树 | 前缀树,节点存储字符,叶子存词 | 插入/查询快(( O(L) )) | 小规模短文本(如几千条评论) | 空间占用大,不适合百万级数据 |
| 倒排索引 | 词到文档/向量的映射列表 | 快速定位包含某词的集合 | 大规模/实时文本(如百万级新闻) | 构建成本高,需预处理 |
4) 【示例】
以Trie树优化小规模文本相似度为例(伪代码):
class TrieNode:
def __init__(self):
self.children = {} # 字符到子节点的映射
self.is_end = False # 标记是否为词的结尾
def build_trie(words):
root = TrieNode()
for word in words:
node = root
for ch in word:
if ch not in node.children:
node.children[ch] = TrieNode()
node = node.children[ch]
node.is_end = True
def get_word_vector(trie, text, vocab):
vector = [0] * len(vocab)
node = root
for ch in text:
if ch in node.children:
node = node.children[ch]
else:
break # 不匹配则停止
if node.is_end:
vector[vocab.index(text)] += 1 # 统计词频
return vector
# 示例:构建Trie树并计算相似度
words = ["apple", "banana", "apricot"]
vocab = ["apple", "banana", "apricot"]
build_trie(words)
vec1 = get_word_vector(root, "apple", vocab)
vec2 = get_word_vector(root, "apricot", vocab)
sim = (vec1 @ vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2)) # 余弦相似度
5) 【面试口播版答案】
“面试官您好,针对文本相似度计算优化,核心思路是根据数据规模和实时性需求选择合适的数据结构。对于小规模数据(比如几千条短文本),可以用Trie树快速构建词表,通过前缀匹配高效提取词,然后计算词向量(如TF-IDF)并使用余弦相似度,因为Trie树插入查询时间复杂度接近( O(L) ),适合小数据集。对于大规模或实时场景(比如百万级文本,需要秒级响应),则用倒排索引结合哈希/向量量化优化。倒排索引能快速定位包含共同词的文档/向量,结合哈希表减少计算量(比如先通过哈希判断是否有共同词,再计算点积),或者用量化技术(如IVF)将高维向量降维后计算,从而提升实时性。总结来说,小规模选Trie树,大规模/实时选倒排索引+哈希/量化。”
6) 【追问清单】
7) 【常见坑/雷区】