1. 项目背景与核心问题
在大规模数据处理领域,相似性搜索是个经典难题。想象你手头有100万篇新闻稿,需要快速找出内容相似的报道;或者你管理着千万级用户画像,要识别兴趣相似的用户群体。传统暴力比对法需要计算O(N²)次比较,当N=1,000,000时,这相当于5万亿次运算——即便用现代服务器也需要数天时间完成。
MinHash+LSH这对黄金组合,能在保持可接受精度损失的前提下,将时间复杂度降至O(N*K)。我在实际业务中处理过网页去重场景,原始方案需要8小时完成的任务,改用该算法后仅需12分钟,效率提升40倍。其核心价值在于:
用概率换时间,通过精心设计的哈希策略,让相似对象以高概率碰撞到相同存储桶,从而避免全量比对
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法原理深度解析
2.1 Jaccard相似度计算基础
给定两个集合A和B,其Jaccard相似度定义为:
code复制J(A,B) = |A∩B| / |A∪B|
例如:
- A =
- B =
- J(A,B) = 3/5 = 0.6
直接计算需要存储原始集合,当元素量巨大时(如文本的shingle集合),内存消耗会成为瓶颈。
2.2 MinHash的数学魔法
MinHash的精妙之处在于:通过哈希函数转换后,两个集合最小哈希值相等的概率恰好等于它们的Jaccard相似度。即:
code复制P[min(h(A)) = min(h(B))] = J(A,B)
我们通过以下步骤构造签名:
- 准备K个独立哈希函数h₁,h₂,...,hₖ
- 对每个集合S,计算signature = [min(h₁(S)), min(h₂(S)),..., min(hₖ(S))]
- 此时两个签名向量中相同位置值相等的比例 ≈ Jaccard相似度
2.3 LSH的分段加速策略
即使有了MinHash签名,直接比较所有签名对仍是O(N²)复杂度。LSH的核心思想是:
- 将K维签名分为b个band,每个band包含r=K/b个值
- 对每个band单独哈希,相同band值落入相同桶
- 只有至少有一个band碰撞的集合对才进入候选
这种策略的妙处在于:
- 相似度高的集合:多个band都会碰撞
- 相似度低的集合:大概率所有band都不碰
