4. NLP基础入门

在交易备注分析场景中,我们面对的往往不是规整的表格字段,而是柜员、客户经理或系统自动生成的一段段自由文本,例如“客户转入货款,对方为XX贸易公司”“疑似分拆转账,规避大额申报”。要让机器理解这些内容,就必须先完成自然语言处理的基础工序。本章围绕四个核心环节展开:基本概念、文本预处理、分词、词性标注与命名实体识别,并始终以“可疑用途识别”为目标牵引。

一、核心原理:从字符到语义的逐层抽象

自然语言处理(NLP)本质上是把非结构化的语言符号,转化为计算机可计算的特征表示。在交易备注场景中,这一转化链条通常表现为:原始文本 → 规范化文本 → 词序列 → 词性序列 → 实体与关系 → 业务标签。每一层都在丢失部分表面信息,同时获得更强的泛化能力。

需要建立三个基本认知。第一,语言是离散符号系统,模型无法直接计算“转账”和“汇款”的相似度,必须通过词向量、共现统计或预训练语言模型将其映射到向量空间。第二,上下文决定含义,“苹果”在“买苹果手机”和“采购苹果水果”中指向不同实体,这正是命名实体识别需要上下文的原因。第三,领域语料显著影响效果,通用分词工具可能把“他行汇入”切成“他/行/汇入”,而金融领域词典能将其识别为完整业务短语。

在可疑用途识别中,NLP基础工序的直接价值是:把“备注文本”变成“可检索、可统计、可建模”的结构化信号,为后续规则引擎和分类模型提供输入。

二、方法流程:文本预处理的标准动作

文本预处理的目标是降噪与归一化,使同一业务含义的不同写法收敛到统一形式。常见动作包括:去除多余空白与控制字符、统一全半角、繁简转换、大小写归一、去除无意义符号、替换敏感信息占位符、以及构建领域同义词表。

以下是一个可复用的预处理函数示例,适用于交易备注的批量清洗:

import re
import unicodedata

# 领域同义词归一表
SYNONYM_MAP = {
    "汇款": "转账",
    "打款": "转账",
    "转入": "转账",
    "他行汇入": "跨行转账",
    "分拆": "拆分",
}

def normalize_text(text: str) -> str:
    if not isinstance(text, str):
        return ""
    # 全角转半角
    text = unicodedata.normalize("NFKC", text)
    # 去除控制字符与多余空白
    text = re.sub(r"[\x00-\x1f\x7f]", " ", text)
    text = re.sub(r"\s+", " ", text).strip()
    # 脱敏:手机号、账号
    text = re.sub(r"1[3-9]\d{9}", "[PHONE]", text)
    text = re.sub(r"\d{12,}", "[ACCOUNT]", text)
    # 同义词归一
    for k, v in SYNONYM_MAP.items():
        text = text.replace(k, v)
    return text

raw = "  客户  他行汇入 货款,账号 6222020202020202,电话13800138000 "
print(normalize_text(raw))
# 输出:客户 跨行转账 货款,账号 [ACCOUNT],电话[PHONE]

预处理之后,文本长度、字符集和表达形式都更稳定,后续分词与实体识别的误差会明显下降。实践中建议把预处理规则版本化,因为规则变更会直接影响下游模型的输入分布。

三、分词、词性标注与命名实体识别

分词是把连续文本切分为词序列的过程。中文没有天然空格,因此分词质量直接决定后续任务上限。常用方法包括基于词典的最大匹配、基于统计的隐马尔可夫模型与条件随机场,以及基于深度学习的BiLSTM-CRF和预训练模型微调。在交易备注中,建议采用“通用分词器 + 领域词典”的混合策略。

词性标注为每个词赋予语法类别,如名词、动词、数量词、时间词。它的价值在于过滤与模式构造:可疑用途描述中,动词往往承载行为意图(“拆分”“规避”“代持”),数量词和时间词则提供金额与频次线索。

命名实体识别(NER)用于抽取文本中的关键实体,如机构名、人名、金额、账号、时间、业务类型。在可疑用途识别中,NER输出可直接作为特征,例如“对方为XX贸易公司”中的机构名,可用于关联交易网络分析。

下面使用jieba演示分词、词性标注与基于词典的实体抽取:

import jieba
import jieba.posseg as pseg

text = "客户他行汇入货款,对方为华信贸易有限公司,疑似拆分转账规避大额申报"

# 加载领域词典
jieba.load_userdict("finance_dict.txt")  # 每行:词语 词频 词性

words = pseg.cut(text)
for w in words:
    print(w.word, w.flag)

# 简易实体抽取:机构名与可疑行为词
ORG_SUFFIX = ("公司", "银行", "集团", "中心")
SUSPICIOUS = {"拆分", "规避", "代持", "分拆", "套现"}

orgs, behaviors = [], []
for w in pseg.cut(text):
    if w.word.endswith(ORG_SUFFIX):
        orgs.append(w.word)
    if w.word in SUSPICIOUS:
        behaviors.append(w.word)

print("机构:", orgs)
print("可疑行为:", behaviors)

运行结果中,“华信贸易有限公司”被识别为机构,“拆分”“规避”被识别为可疑行为词。这些结构化输出可以直接进入规则引擎,例如命中“拆分 + 规避 + 大额”组合时提升风险评分。

四、案例、误区与复盘

假设一条真实备注:“客户分三笔转入,每笔4.9万,对方为不同个人,疑似规避大额申报。”经过预处理、分词、词性标注与NER后,可得到如下结构化清单:

处理阶段 输出示例 在可疑识别中的作用
预处理 客户分三笔转账,每笔4.9万,对方为不同个人,疑似规避大额申报 统一“转入”为“转账”,保留金额与频次
分词 客户 / 分 / 三笔 / 转账 / 每笔 / 4.9万 / 对方 / 不同 / 个人 切分出金额、频次、对象类型
词性标注 客户/n,分/v,三笔/m,转账/v,4.9万/m 动词识别行为,数量词识别金额与笔数
命名实体识别 金额:4.9万;频次:三笔;对象:个人;行为:规避 直接生成风险特征

常见误区有四个。第一,过度依赖通用工具,未加载金融领域词典,导致“他行汇入”“大额申报”被切碎。第二,忽略预处理的一致性,训练与推理阶段使用不同清洗规则,造成特征漂移。第三,把NER当作万能抽取器,实际上NER对嵌套实体和长距离依赖仍有限,需要规则兜底。第四,只关注单条文本,忽略同一客户多笔备注的聚合关系,而可疑用途往往体现在模式而非单句中。

复盘建议:建立“备注文本 → 预处理 → 分词 → 词性 → 实体 → 风险标签”的流水线日志,定期抽样人工核对,重点检查分词边界错误和实体漏抽,这两类问题对可疑识别召回率影响最大。
注意:预处理中的脱敏替换会改变文本长度和字符分布,若后续使用基于字符的模型,应在脱敏后重新训练或微调,避免训练与推理不一致。

掌握本章内容后,你应能独立完成交易备注的基础NLP流水线搭建,并为后续的文本分类、意图识别与可疑用途建模准备好高质量输入。