You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何清理NLTK提取的重复及近似重复标题?求最优处理方案

处理提取标题中的重复与近似重复问题

问题场景

提取的标题存在完全重复、冗余前缀(RE:/FW:等)、拼写错误、附加无关后缀等近似重复问题,示例如下:

Daily Update (6/20) REDACTED.,
Daily Update (9/9).,
Daily Update (10/10).,
RE: General/ABC Update.
RE: General/ABC Update RELEASE IN PART BS.
General/ABC Update.
RE: General/ABC Article.
RE: General/ABC Articie.
Wrap Up for Friday, September 2017.,
Wrap Up for Monday, January 2018.,
Wrap Up for Monday, January 2018.

期望输出:

Daily Update (6/20) REDACTED.,
Daily Update (9/9).,
Daily Update (10/10).
General/ABC Article.
Wrap Up for Friday, September 2017.,
Wrap Up for Monday, January 2018.


解决方案

1. 预处理优化(减少后续匹配压力)

在提取阶段先清理冗余内容:

  • 统一移除所有回复/转发前缀(RE:/FW:/Fwd:等,支持大小写及变体)
  • 清理标题末尾多余标点
  • 移除无关后缀标注(如RELEASE IN PART BS这类附加内容)

2. 模糊匹配去重(解决近似重复)

用rapidfuzz(性能优于fuzzywuzzy)计算标题相似度,设定阈值(如85%),只保留首次出现的相似标题。

3. 精确去重(保留首条)

若仅需处理完全重复,直接遍历列表,保留首次出现的标题即可。


完整实现代码

from itertools import chain
from nltk import sent_tokenize, word_tokenize
from nltk.tokenize.treebank import TreebankWordDetokenizer
import re
from rapidfuzz import fuzz

word_detokenize = TreebankWordDetokenizer().detokenize

def preprocess_title(title):
    # 移除回复/转发前缀(支持大小写、变体)
    title = re.sub(r'^\s*(RE:|FW:|Fwd:|Re:|R\.E:)\s*', '', title, flags=re.IGNORECASE)
    # 清理末尾多余标点,统一为单个句号
    title = re.sub(r'\.*$', '.', title.strip())
    # 移除无关后缀标注(可根据实际情况调整正则)
    title = re.sub(r'\s+RELEASE IN PART.*$', '', title, flags=re.IGNORECASE)
    return title

def fuzzy_deduplicate(titles, threshold=85):
    unique_titles = []
    for title in titles:
        # 与已保留标题比对相似度,低于阈值则加入
        is_duplicate = any(fuzz.ratio(title, existing) >= threshold for existing in unique_titles)
        if not is_duplicate:
            unique_titles.append(title)
    return unique_titles

# 原标题提取逻辑
tokenized_text = [word_tokenize(sent) for sent in sent_tokenize(data1)]
sent_idx_with_event = [idx for idx, sent in enumerate(tokenized_text) 
                       if 'Event' in sent or 'Subject' in sent]
window = 1 

list1 = []
for idx in sent_idx_with_event:
    start = max(idx - window, 1)
    end = min(idx+window, len(tokenized_text))
    result = ' '.join(word_detokenize(sent) for sent in tokenized_text[start:end])
    result = re.split("Subject:|Event:", result)[-1]
    # 加入预处理步骤
    result = preprocess_title(result)
    list1.append(result)

# 先模糊去重,若需完全去重可追加精确去重
unique_list = fuzzy_deduplicate(list1)
# 精确去重(保留首条):unique_list = list(dict.fromkeys(unique_list))

# 输出处理后的标题
for title in unique_list:
    print(title)

说明

  • 预处理正则可根据实际标题的冗余类型调整,适配更多场景。
  • 模糊匹配阈值threshold可灵活调整:阈值越高,去重越严格;越低,越容易合并近似标题。
  • 若无需模糊匹配,仅做精确去重,直接用list(dict.fromkeys(list1))即可保留首条完全重复的标题。

内容的提问来源于stack exchange,提问作者Aaron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 02:44:57