第三章:数据预处理与增强——法律文本的“洗剪吹”艺术

大家好,我是你们的老朋友。今天我们来聊聊法律大模型训练中最“脏活累活”的一环——数据预处理与增强。

说实话,很多人觉得模型性能靠的是算法和算力。我一开始也这么想。直到我在一个合同审查项目里,喂了模型一堆带乱码、重复率高达40%的法律文书……结果模型输出了一堆“根据《中华人⺠共和国⺠法典》第X条,以及第X条,以及第X条……”——嗯,它学会了复读。

从那以后,我彻底明白了:数据质量,决定了模型的天花板。 今天我们就来拆解法律文本的清洗、去重、增强三板斧。

核心观点:法律文本预处理不是“打扫卫生”,而是“精装修”。你投入多少心思,模型就回报你多少智商。

3.1 法律文本清洗:把“垃圾”筛出去

法律文本来源五花八门:裁判文书网、法规数据库、扫描件OCR、甚至PDF转出来的乱码。我见过最离谱的,是一份判决书里混进了“第⻚码: 1/2/3/4/5/6/7/8/9/10”这种页码标记,模型硬是把它当成了法条编号。

清洗的核心目标就三个:去噪、标准化、结构化

3.1.1 常见噪声类型

噪声类型 示例 处理方式
OCR乱码 “根据《中华人⺠共和国⺠法典》” 正则替换为正确字符
页码/页眉页脚 “第1页 / 共20页” 正则删除
多余空格/换行 “判决如下:\n\n\n\n一、” 合并连续空白符
HTML/XML标签 “<p>原告主张</p>” 解析后提取纯文本
特殊符号 “★☆★ 判决书 ★☆★” 删除非法律符号

我的小技巧: 清洗前先跑一遍统计——看看文本里出现频率最高的前50个字符。如果“●”、“◆”、“★”这些符号排进了前10,那你的清洗工作还没做完。

3.1.2 法律文本标准化

法律文本里有很多“同义不同形”的表达。比如“民法典”和“《中华人民共和国民法典》”、“第X条”和“第X条(含修正案)”。我个人习惯的做法是:

import re

def normalize_law_text(text):
    # 统一法条引用格式
    text = re.sub(r'《(.*?)民法典》', '《中华人民共和国民法典》', text)
    # 统一“第X条”格式
    text = re.sub(r'第\s*(\d+)\s*条', r'第\1条', text)
    # 删除多余空白
    text = re.sub(r'\s+', ' ', text).strip()
    return text

你想想看,如果模型同时见过“民法典第1条”和“《民法典》第一条”,它就会困惑到底哪个是标准写法。标准化之后,模型学到的规律更干净。

3.2 数据去重:别让模型“背答案”

法律数据有个特点:重复率极高。同一个案由,不同法院的判决书可能90%内容一样,只是当事人名字和金额不同。我曾经处理过一个20G的裁判文书数据集,去重之后只剩6G——你猜那14G是什么?全是“本院认为……本院认为……本院认为……”的复读机。

去重不只是为了省存储,更是为了防止模型过拟合。模型如果反复看到同一段话,它会以为“这就是真理”,而不是“这是一个常见表述”。

3.2.1 去重策略

  • 精确去重: 完全相同的文本直接删除。简单粗暴,但有效。
  • 模糊去重: 使用MinHash或SimHash算法,计算文本相似度。相似度超过阈值(比如0.85)就视为重复。
  • 语义去重: 用BERT等模型提取句子向量,计算余弦相似度。适合处理“表述不同但意思一样”的情况。

避坑指南: 我曾经用精确去重处理一批合同模板,结果把“甲方:张三”和“甲方:李四”当成了不同文本。后来才发现,合同模板里90%内容相同,只有当事人信息不同。这种场景下,应该用模板去重——先提取模板结构,再对结构去重。

3.3 数据增强技术:给模型“加餐”

法律数据标注成本极高。一份合同标注可能需要律师花2小时,成本几百块。所以数据增强在NLP领域很常见,但在法律领域,要格外小心——你不能随便改一个词就改变法律含义。

3.3.1 回译(Back Translation)

把中文法律文本翻译成英文,再翻译回中文。这样会得到“意思相同但表述不同”的文本。比如:

  • 原句:“甲方应于合同签订后30日内支付首付款。”
  • 回译后:“甲方需在合同签署后的30天内支付首期款项。”

注意:回译可能会引入不准确的法律术语。我建议只对事实描述部分做回译,法条引用和定义部分保持原样。

3.3.2 同义词替换

在法律领域,同义词替换要非常谨慎。比如“应当”和“可以”在法律上含义完全不同——前者是义务,后者是权利。我一般只替换以下类型的词:

原词 可替换词 注意事项
甲方 买方、委托人、出租方 需根据合同类型选择
支付 给付、交付、付款 “给付”偏民法,“付款”偏合同
违约 违反约定、不履行 “违约”是标准术语,慎换

3.3.3 上下文增强

这是我最喜欢的方法。法律文本往往有固定的结构:案情描述 → 争议焦点 → 法院认定 → 判决结果。我们可以通过随机截取段落重排来生成新样本。

举个例子,一份判决书有5个段落。我们可以随机抽取其中3段,组成一个新的训练样本。模型需要学会从局部推断全局——这比死记硬背整篇判决书有用得多。

我的经验: 上下文增强时,一定要保留“争议焦点”和“判决结果”这两个核心段落。否则模型学到的可能是“一堆事实,没有结论”。

3.4 法律领域数据标注规范

标注是数据预处理中最“磨人”的一环。我见过太多团队,花了几十万标注数据,结果标注规范写得像天书,标注员根本看不懂。

好的标注规范,应该像法律条文本身——清晰、无歧义、可执行。

3.4.1 标注规范的核心要素

  • 定义明确: 比如“合同主体”标注为“甲方/乙方/丙方”,而不是“当事人”。
  • 边界清晰: 比如“违约条款”从“一方违约时”开始,到“守约方有权解除合同”结束。
  • 示例丰富: 每个标注类型至少给3个正例和3个反例。
  • 争议处理: 标注员意见不一致时,由资深律师仲裁。

3.4.2 标注质量检查

我习惯用交叉验证:让两个标注员独立标注同一批数据,计算一致性(Kappa系数)。如果Kappa低于0.8,说明规范有问题,需要重新培训。

from sklearn.metrics import cohen_kappa_score

# 假设两个标注员的标注结果
annotator1 = [1, 0, 1, 1, 0, 1]
annotator2 = [1, 0, 1, 0, 0, 1]

kappa = cohen_kappa_score(annotator1, annotator2)
print(f"Kappa系数: {kappa:.2f}")
# 如果 kappa < 0.8,需要重新讨论标注规范

避坑指南: 我曾经遇到一个标注团队,他们把所有“数字”都标注为“金额”。结果模型把“第1条”中的“1”也当成了金额——嗯,模型学会了“第金额条”。所以标注规范里一定要写清楚:“金额”只标注货币数值,不标注序号、日期、数量。

3.5 本章知识体系图

下面这张图,是我自己总结的数据预处理与增强的完整流程。你可以把它贴在工位上,每次做数据清洗时对照着看。

法律文本数据预处理与增强流程 原始法律文本 文本清洗 数据去重 数据增强 标注规范 质量检查 回译 同义词替换 上下文增强 定义明确 边界清晰 交叉验证 Kappa系数

这张图的核心逻辑是:先清洗,再去重,然后根据需求选择增强或标注。 不要跳过任何一步。我见过有人直接对原始数据做增强,结果把乱码也增强了——模型学会了“根据《中华人⺠共和国⺠法典》第★条”。

好了,这一章的内容就到这里。数据预处理虽然枯燥,但它是模型性能的基石。下一章我们会聊模型训练中的“玄学”——超参数调优。到时候见。


公众号:蓝海资料掘金营,微信deep3321