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

什么是新闻模糊去重

新闻场景里大量转载稿件:标题加【快讯】【最新】、修改标点、删减导语、微调部分语句,但整篇新闻本质是同一篇。完全字符串相等、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 就是性价比最高的模糊去重方案。

相关推荐
oyguyteggytrrwwwrt3 小时前
3dgs渲染部分详细注释
python
天天爱吃肉82185 小时前
【重磅发布:拿下新超仁达代理权 】
大数据·人工智能·python·功能测试·汽车
神王宝宝 王者小学5 小时前
面向领域驱动架构的查询实现方式
前端·python·架构
ningmengjing_6 小时前
Redis 从入门到实战:Python操作全攻略
数据库·redis·python
️学习的小王6 小时前
智能文档助手:基于RAG的本地化文档问答系统实战指南
人工智能·python·机器学习
不瘦80斤不改名6 小时前
05-vibe-coding-向agentic-engineering演进
人工智能·笔记·python·prompt
笨鸟先飞,勤能补拙7 小时前
AI 安全的下一个 5 年:从 Agent 到 AGI 的攻防博弈
人工智能·python·安全·web安全·网络安全·github·agi
Logintern097 小时前
LangSmith如何根据id关系,在服务端把扁平列表重建为树形结构,用于页面渲染Trace视图
python