如何对新闻数据进行模糊去重

什么是新闻模糊去重

新闻场景里大量转载稿件:标题加【快讯】【最新】、修改标点、删减导语、微调部分语句,但整篇新闻本质是同一篇。完全字符串相等、MD5是精准去重,处理不了这种改写转载,需要模糊去重

模糊去重目标:内容高度相似、局部修改的新闻识别为重复,不完全依赖字符串完全一致

痛点:

  1. 标题改几个字,MD5直接失效
  2. 正文删改几句话,直接比对文本不相等
  3. 不能把主题相似但完全不同的新闻误判重复

主流工业方案:SimHash(局部敏感哈希)是新闻/舆情领域模糊去重首选;备选:文本相似度算法、向量语义去重。

前置:文本清洗(模糊去重必须做)

网页新闻自带HTML标签、换行、空格、特殊符号【】《》、广告尾注,这些噪声会直接毁掉指纹计算,所有模糊去重前先清洗。

python 复制代码
import re
import jieba

def clean_news(text: str) -> str:
    if not text:
        return ""
    # 去除html标签
    text = re.sub(r"<.*?>", "", text)
    # 去除特殊符号、换行、制表符
    text = re.sub(r"[【】《》『』「」#@\n\r\t]", "", text)
    # 压缩全部空白字符
    text = re.sub(r"\s+", "", text)
    return text.strip()

方案一:SimHash 局部敏感哈希(新闻最常用)

核心原理:相似文本生成的指纹,汉明距离很小;文本差异越大,汉明距离越大。

相同含义,少量文字改动,指纹依然接近;完全不同文本指纹差异巨大。

完整可运行代码:

python 复制代码
import hashlib
import jieba

def get_md5_hash(s: str):
    return int(hashlib.md5(s.encode("utf-8")).hexdigest(), 16)

def simhash(text: str, bit=64) -> int:
    """
    jieba分词版simhash,适合中文新闻
    :param text:清洗之后的文本(标题/正文摘要)
    :param bit:指纹位数,默认64位
    :return:simhash指纹整数
    """
    words = jieba.lcut(text)
    v = [0] * bit
    for word in words:
        h = get_md5_hash(word)
        for i in range(bit):
            if h >> i & 1:
                v[i] += 1
            else:
                v[i] -= 1
    fingerprint = 0
    for i in range(bit):
        if v[i] > 0:
            fingerprint |= 1 << i
    return fingerprint

def hamming_distance(fp1: int, fp2: int) -> int:
    """计算两个指纹汉明距离,数值越小越相似"""
    return bin(fp1 ^ fp2).count("1")

业务阈值(新闻项目实测经验)

汉明距离 = 两个指纹二进制位不一样的数量

  • ≤2:几乎完全相同,判定重复
  • 3‑4:转载改写新闻,业务直接判定重复
  • ≥5:判定为不同新闻
python 复制代码
# 测试案例:转载新闻
news_a = clean_news("央行宣布下调存款准备金率0.5个百分点")
news_b = clean_news("【快讯】央行宣布下调存款准备金率0.5个百分点!")

fp_a = simhash(news_a)
fp_b = simhash(news_b)
dist = hamming_distance(fp_a, fp_b)
print(f"汉明距离:{dist}")
if dist <=4:
    print("✅判定为重复新闻")

内存中批量模糊去重示例

⚠️注意:直接双重循环 O(n²),只适合小数据集(几千条以内)

python 复制代码
news_data = [
    {"title":"央行宣布下调存款准备金率0.5个百分点","content":"xxx"},
    {"title":"【快讯】央行宣布下调存款准备金率0.5个百分点!","content":"xxx"},
    {"title":"油价迎来年内第七次上调","content":"yyy"}
]

distinct = []
for curr in news_data:
    t = clean_news(curr["title"])
    curr_fp = simhash(t)
    is_dup = False
    for exist in distinct:
        d = hamming_distance(curr_fp, exist["fp"])
        if d <=4:
            is_dup = True
            break
    if not is_dup:
        distinct.append({"data":curr,"fp":curr_fp})

print(f"原始 {len(news_data)} ,模糊去重后 {len(distinct)}")

海量数据问题说明

上面直接双重循环,1万条新闻就要1亿次比对,性能爆炸。

百万新闻生产环境不能直接两两比对,解决方案:SimHash分桶。

把64位指纹切分成4段,每段16bit;同一段指纹相同才放入同一个桶。只比对同一个桶内的指纹,大幅减少比对次数。

方案二:difflib 序列相似度(小数据备选)

不需要第三方库,直接计算文本相似度比值,适合几千条以内小规模数据。

python 复制代码
from difflib import SequenceMatcher

def text_similarity(a:str,b:str)->float:
    return SequenceMatcher(None,a,b).ratio()

t1 = clean_news("央行宣布下调存款准备金率0.5个百分点")
t2 = clean_news("【快讯】央行宣布下调存款准备金率0.5个百分点!")
score = text_similarity(t1,t2)
print(f"相似度:{score:.2f}")
# 业务阈值:大于0.85视为重复
if score >=0.85:
    print("判定重复")

缺点:数据量大O(n²)很慢;长文本改动局部内容,分数会暴跌,不如SimHash稳定。

方案三:向量语义模糊去重(大模型路线)

SimHash是字面层面,改写幅度很大,换表达方式但是语义相同的新闻,SimHash会失效

这时使用Embedding向量:

  1. 调用中文向量模型(bge‑small等),每条新闻生成向量
  2. 计算向量余弦相似度,大于阈值判定重复
  3. 海量数据存入向量数据库(FAISS / Milvus / ES向量)

优点:真正语义层面识别;缺点:算力开销大,需要模型,速度慢,适合舆情高级分析。

生产落地实践要点

  1. 用标题还是正文?
  • 短标题:只拿标题做simhash,阈值汉明距离≤3
  • 长新闻:建议取标题+前200字正文摘要生成指纹,不要用全文,全文太长会稀释特征。
  1. 不要丢掉精准去重

    流程:先MD5精准命中完全一样新闻;命中不到,再走SimHash模糊比对。兼顾速度和模糊识别。

  2. 踩坑点

  • 不要不清洗直接丢给simhash,特殊符号会直接改变指纹;
  • 短文本不要把汉明距离阈值调太大,容易误判;
  • 禁止直接双重循环处理上万条新闻,性能爆炸,必须分桶。

数据库存储设计

MySQL存储simhash指纹,方便爬虫入库去重:

sql 复制代码
CREATE TABLE news (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  title VARCHAR(512),
  content TEXT,
  title_md5 CHAR(32),
  simhash_fp BIGINT UNSIGNED COMMENT '64位simhash指纹',
  INDEX idx_md5(title_md5)
);

业务逻辑:

  1. 新新闻清洗文本,生成title_md5、simhash_fp
  2. 查询md5,命中直接判定重复;
  3. md5无命中,再做simhash分桶比对,判断是否模糊重复。

方案对比总结

方案 能力 适用场景 缺点
SimHash 字面模糊,抗转载改写 爬虫、舆情新闻,工业首选 大幅度语义改写识别弱,大数据需要分桶优化
difflib相似度 字面相似度 几千条以内小数据集 大数据性能差
Embedding向量 语义层面模糊去重 高级舆情分析 需要模型,算力消耗大

绝大多数新闻爬虫业务,清洗 + jieba版SimHash 就是性价比最高的模糊去重方案。

相关推荐
荷蒲6 小时前
【小白量化Qbuddy】利用AI学习中文Python
人工智能·python·学习
数据狐(Datafox)7 小时前
京东商品列表API技术解析与落地应用(含标准 JSON 示例)
java·大数据·前端·人工智能·python·数据分析·json
量化吞吐机7 小时前
2026年下半年手工交易规则走向量化表达,产品该先接住哪一步
人工智能·python
Metaphor6928 小时前
使用 Python 读取和删除 Excel 文件属性
python·excel
迷迭香yy9 小时前
Python构建转融券多空识别系统从接口到因子的全流程 IG50免费开源股票数据API接口
开发语言·python·开源
月光船幽幽9 小时前
真实即粗糙,光滑是伪造
人工智能·python
一次旅行9 小时前
Attention机制从数学到工程:拆解缩放点积+多头注意力|附可运行PyTorch实现与踩坑指南
人工智能·pytorch·python
泡干脆面就番茄10 小时前
NumPy 科学计算完全指南:从数组创建到广播机制
python·numpy
denggun1234510 小时前
信号量(DispatchSemaphore vs AsyncSemaphore)、swift协作式线程池 and python信号量
开发语言·python·swift
起光10 小时前
Python类与对象(一)
python