Minhash 与 Simhash 在做文章去重时的区别 ?

1. 算法原理

  • MinHash
    • MinHash 主要用于集合相似性的计算,特别是计算 Jaccard 相似度。它通过对集合进行哈希操作来近似计算集合的交集与并集的比例,从而估算两个集合的相似性。
    • 每个文档被表示为一组特征(比如单词集合),然后通过一组不同的哈希函数来映射这些特征到一个小的签名(即哈希值)。两个文档的签名越相似,它们的 Jaccard 相似度越高。
  • SimHash
    • SimHash 通过将文档转换成一个高维向量(通常是二进制向量),然后对文档的特征(如词语、词频)进行加权,最后将这些加权特征的值通过哈希函数映射成一个二进制签名。两个文档的 Hamming 距离(即两个二进制签名之间的不同位数)可以用来判断它们的相似度。
    • SimHash 适用于 近似余弦相似度 计算,适合文本的 语义去重

2. 适用场景

  • MinHash
    • 适用于基于集合的相似度计算,如两个文档共享的单词或其他特征的比例。
    • 更适合 集合重合度 比较,如两篇文章的关键词、词汇的重合度。
  • SimHash
    • 更适合文档的 近似文本相似度计算,例如检测两篇文章内容的相似度。
    • 适用于 大规模数据的去重,因为它产生的哈希签名通常比较小(通常是64位或者128位),计算效率较高。

3. 输出格式

  • MinHash
    • MinHash 输出的是一个固定长度的签名,通常是整数或短字符串,表示集合的特征。签名的相似性反映了两个集合的 Jaccard 相似度。
  • SimHash
    • SimHash 输出的是一个二进制字符串或整数,代表文档的特征向量。通过比较 Hamming 距离来度量两个文档之间的相似性。

4. 性能与计算

  • MinHash
    • 计算复杂度较高,尤其是需要多个哈希函数来逼近 Jaccard 相似度,尤其对于文档内容较多时,性能要求较高。
  • SimHash
    • 计算更为高效,适合大规模数据的快速去重,因为其输出的哈希值较短,且计算过程可以通过加权和简单的哈希函数来完成。

5. 优缺点

  • MinHash
    • 优点:对集合相似度计算精度高,适用于词集合去重、关键词匹配等。
    • 缺点:可能不适用于需要处理语义层次的文本相似度,因为它依赖于集合的重合度,而不是具体的文本语义。
  • SimHash
    • 优点:适合语义层面的文本去重,计算效率高,特别适合大规模文本去重。
    • 缺点:可能不如 MinHash 在集合相似度计算方面精准,且在某些复杂文本的语义对比中,可能无法完全准确地捕捉相似度。

6. 应用实例

  • MinHash:广泛应用于 搜索引擎去重广告点击去重文档相似度分析等领域,尤其是在处理文本集合(如关键词、标签等)时非常有效。
  • SimHash:常用于 网页去重新闻聚合文档相似度分析大规模数据去重等。

7. 代码实例

7.1. 使用 Spark 进行 MinHash 计算
from pyspark.sql import SparkSession
from datasketch import MinHash
from pyspark.rdd import RDD

# 创建 Spark 会话
spark = SparkSession.builder.appName("MinHashExample").getOrCreate()

# 示例文档
documents = [
    "The quick brown fox jumps over the lazy dog",
    "The fast brown fox jumps over the lazy dog",
    "The quick brown dog jumped over the lazy fox",
    "A lazy dog jumps quickly over the brown fox"
]

# 将文档加载到 Spark RDD
rdd: RDD = spark.sparkContext.parallelize(documents)

# MinHash 函数
def minhash_document(doc: str) -> MinHash:
    m = MinHash()
    for word in set(doc.split()):
        m.update(word.encode('utf8'))
    return m

# 使用 MinHash 计算每个文档的签名
minhash_signatures = rdd.map(minhash_document)

# 计算两个 MinHash 签名之间的相似度
def compute_jaccard_similarity(pair):
    minhash1, minhash2 = pair
    return minhash1.jaccard(minhash2)

# 将 MinHash 签名两两组合进行相似度计算
minhash_pairs = minhash_signatures.cartesian(minhash_signatures)
similarities = minhash_pairs.map(compute_jaccard_similarity)

# 获取结果
similarity_results = similarities.collect()

# 打印相似度结果
print("MinHash Similarities:")
for similarity in similarity_results:
    print(similarity)

# 停止 Spark 会话
spark.stop()
7.2. 使用 Spark 进行 SimHash 计算
from pyspark.sql import SparkSession
from simhash import Simhash
from pyspark.rdd import RDD

# 创建 Spark 会话
spark = SparkSession.builder.appName("SimHashExample").getOrCreate()

# 示例文档
documents = [
    "The quick brown fox jumps over the lazy dog",
    "The fast brown fox jumps over the lazy dog",
    "The quick brown dog jumped over the lazy fox",
    "A lazy dog jumps quickly over the brown fox"
]

# 将文档加载到 Spark RDD
rdd: RDD = spark.sparkContext.parallelize(documents)

# SimHash 函数
def simhash_document(doc: str) -> Simhash:
    return Simhash(doc)

# 使用 SimHash 计算每个文档的签名
simhash_signatures = rdd.map(simhash_document)

# 计算两个 SimHash 签名的汉明距离
def compute_hamming_distance(pair):
    simhash1, simhash2 = pair
    return simhash1 - simhash2

# 将 SimHash 签名两两组合进行汉明距离计算
simhash_pairs = simhash_signatures.cartesian(simhash_signatures)
hamming_distances = simhash_pairs.map(compute_hamming_distance)

# 获取结果
hamming_results = hamming_distances.collect()

# 打印汉明距离结果
print("SimHash Hamming Distances:")
for hamming_distance in hamming_results:
    print(hamming_distance)

# 停止 Spark 会话
spark.stop()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值