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

银行邮件命名实体移除与精准识别问题求助(基于Spacy)

银行邮件命名实体识别与修正方案

问题背景

处理银行邮件的命名实体移除与收集任务时,使用Spacy的en_core_web_sm模型出现实体识别偏差:

  • 将账户号识别为日期
  • 把问候语"Hello Team"识别为机构(ORG)
  • 无法正确识别账户类型、联系电话、地址这类业务专属实体

示例场景

示例邮件:
"Hello Team, please convert account 12345678911 to business account, my contact number to reach is 909-500-6000 and address is Client academy aa-77-05-10, 12543. warm regards, vanica be denial."

错误输出(Spacy默认识别)

Hello Team ORG, 12345678911 Date, Business Account ORG, Vanica be Name, Denial Name, 12543 Date, 6000 cardinal

期望输出

12345678911 account number, Business Account Account type, Vanica be denial Name, Client academy aa-77-05-10,12543 address, 909-500-6000 contact number

实用解决方案

针对银行场景的专属实体,推荐规则匹配+模型修正的混合方案,适合新手快速落地:

1. 定义业务专属正则规则

先通过正则匹配有固定格式的实体(账户号、联系电话、地址),这类实体用规则识别比模型更准确:

import re
import spacy

# 定义正则匹配规则,可根据实际邮件格式扩展
patterns = {
    "account number": re.compile(r'\b\d{11}\b'),  # 匹配11位账户号
    "contact number": re.compile(r'\b\d{3}-\d{3}-\d{4}\b'),  # 匹配指定格式手机号
    "address": re.compile(r'Client academy [a-z0-9-]+, \d{5}\b')  # 匹配示例地址格式
}

2. 模型修正与实体合并

加载Spacy模型后,修正错误识别的实体,同时合并规则匹配的结果:

nlp = spacy.load('en_core_web_sm')
text = "Hello Team, please convert account 12345678911 to business account, my contact number to reach is 909-500-6000 and address is Client academy aa-77-05-10, 12543. warm regards, vanica be denial."

# 步骤1:用正则提取规则实体
rule_entities = []
for entity_type, pattern in patterns.items():
    matches = pattern.finditer(text)
    for match in matches:
        rule_entities.append((match.start(), match.end(), entity_type, match.group()))

# 步骤2:用Spacy处理文本,修正错误标签
doc = nlp(text)
corrected_entities = []

# 过滤错误识别的实体(比如Hello Team的ORG标签)
filtered_spacy_ents = [ent for ent in doc.ents if not (ent.text == "Hello Team" and ent.label_ == "ORG")]

for ent in filtered_spacy_ents:
    # 修正被识别为Date的账户号
    if ent.label_ == "DATE" and re.match(r'\b\d{11}\b', ent.text):
        corrected_entities.append((ent.start_char, ent.end_char, "account number", ent.text))
    # 修正被识别为ORG的账户类型
    elif ent.label_ == "ORG" and ent.text == "Business Account":
        corrected_entities.append((ent.start_char, ent.end_char, "Account type", ent.text))
    # 合并拆分的姓名实体
    elif ent.label_ == "PERSON":
        next_ent = doc[ent.end:ent.end+2] if ent.end+2 <= len(doc) else None
        if next_ent and next_ent.label_ == "PERSON":
            full_name = f"{ent.text} {next_ent.text}"
            corrected_entities.append((ent.start_char, next_ent.end_char, "Name", full_name))
        else:
            corrected_entities.append((ent.start_char, ent.end_char, "Name", ent.text))

# 步骤3:合并规则实体和修正后的模型实体,去重
all_entities = rule_entities + corrected_entities
all_entities.sort(key=lambda x: x[0])
unique_entities = []
prev_end = -1
for ent in all_entities:
    if ent[0] >= prev_end:
        unique_entities.append(ent)
        prev_end = ent[1]

# 步骤4:输出期望格式的实体结果
print("output:- " + ", ".join([f"{ent[3]} {ent[2]}" for ent in unique_entities]))

# 步骤5:移除实体,生成剩余处理文本
remaining_text = text
# 按实体结束位置倒序移除,避免索引偏移
for ent in sorted(unique_entities, key=lambda x: x[1], reverse=True):
    remaining_text = remaining_text[:ent[0]] + remaining_text[ent[1]:]
# 清理多余空格
remaining_text = re.sub(r'\s+', ' ', remaining_text).strip()
print("\n剩余处理文本:")
print(remaining_text)

3. 进阶方案:自定义Spacy管道

如果需要更通用的解决方案,可以给Spacy添加自定义实体识别管道,覆盖默认模型的错误识别:

from spacy.language import Language

@Language.component("bank_entity_corrector")
def bank_entity_corrector(doc):
    new_ents = []
    for ent in doc.ents:
        # 移除错误识别的机构
        if ent.text == "Hello Team" and ent.label_ == "ORG":
            continue
        # 修正账户号标签
        elif ent.label_ == "DATE" and re.match(r'\b\d{11}\b', ent.text):
            new_ent = doc.char_span(ent.start_char, ent.end_char, label="ACCOUNT_NUMBER")
            new_ents.append(new_ent)
        # 修正账户类型标签
        elif ent.label_ == "ORG" and ent.text == "Business Account":
            new_ent = doc.char_span(ent.start_char, ent.end_char, label="ACCOUNT_TYPE")
            new_ents.append(new_ent)
        else:
            new_ents.append(ent)
    # 添加正则匹配的自定义实体
    for entity_type, pattern in patterns.items():
        matches = pattern.finditer(doc.text)
        for match in matches:
            span = doc.char_span(match.start(), match.end(), label=entity_type.upper().replace(" ", "_"))
            if span:
                new_ents.append(span)
    doc.ents = new_ents
    return doc

# 将自定义管道添加到Spacy模型
nlp.add_pipe("bank_entity_corrector", after="ner")

# 测试效果
doc = nlp(text)
for ent in doc.ents:
    print(f"{ent.text} {ent.label_.replace('_', ' ').lower()}")

关键说明

  • 正则规则可根据实际银行邮件的格式灵活扩展(比如不同长度的账户号、地区地址格式)
  • 对于姓名这类实体,可通过相邻实体合并解决模型拆分识别的问题
  • 如果有足够的标注数据,可以微调Spacy的en_core_web_sm模型,进一步提升场景适配性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:32:14