知识库 / 数据治理
GitHub
← 数据治理

LAYER 02 / DATA ENGINEERING

文本解析、规范化与基础清洗

所属: 数据治理层。本页边界: 原始网页、文档和日志怎样变成含义尽量不失真的训练文本。

#核心处理关系

xclean=ffilter∘fnormalize∘fparse(xraw) x_{\mathrm{clean}}=f_{\mathrm{filter}}\circ f_{\mathrm{normalize}}\circ f_{\mathrm{parse}}(x_{\mathrm{raw}})

这是一条处理顺序而非可优化的数学目标,因此不把它解释为模型核心公式:解析先恢复结构,规范化统一可安全转换的表面形式,过滤再决定保留哪些内容。

#符号说明

符号 含义
xrawx_{\mathrm{raw}} 原始 PDF、HTML、日志、扫描件或其他源文档
fparsef_{\mathrm{parse}} 从原始格式恢复文本、版面与结构的解析变换
fnormalizef_{\mathrm{normalize}} Unicode、空白、标点等规范化变换
ffilterf_{\mathrm{filter}} 删除损坏、无效或不符合规则内容的过滤变换
xcleanx_{\mathrm{clean}} 供后续去重、过滤或训练使用的输出
s, T(s)s,\ T(s) 后文中的原始结构及其解析后的文本表示
S,D,I,NS,D,I,N 字符错误率中的替换、删除、插入数与参考字符数

函数复合的执行顺序从右向左;真实系统还应保留来源位置与处理版本。

#技术要点

  • 解析保留正文、标题、代码、表格和文档结构。
  • 规范化处理编码、空白、Unicode、模板噪声和格式残留。
  • 基础过滤去除损坏、过短、乱码和明显无信息文本。
  • 清洗规则本身会改变数据分布。
  • HTML 解析需区分正文与模板(boilerplate),常用 DOM 树遍历或基于文本密度的启发式。
  • PDF 解析存在三条路线:文本层直接抽取、版面分析后抽取、OCR 识别后抽取,选择取决于 PDF 是否含文本层以及版面复杂度。
  • Unicode 规范化有 NFC、NFD、NFKC、NFKD 四种形式,训练语料通常保留原始形式,仅在比较视图做规范化。
  • 基础过滤的经典规则集包括 C4 启发式和 Gopher 规则,二者都只处理高确定性的坏样本。
  • 代码、表格、公式的结构保真需要类型特定的解析器,通用文本抽取器会破坏这些结构。

#原理与演进

#三步各解决什么

步骤 输入到输出 容易损失的信息
解析 PDF/HTML/日志 → 正文与结构 多栏阅读顺序、表格单元、代码缩进
规范化 编码、空白、特殊字符统一 数学符号、大小写、语言特有字符
基础过滤 移除明显损坏与无信息样本 短但有价值的公式、函数或告警
  • 公式中的复合函数按从右往左执行:先解析,再规范化,最后过滤。
  • “只抽正文”对普通文章可能有效,对代码、论文表格和日志会破坏任务所需结构。
  • 保留原文与清洗后文本的映射,才能复查误删和追踪异常样本。

#从规则到结构感知

最初的字符规则能处理乱码和重复模板;遇到 PDF、多栏、表格和代码后,需要结合文档布局与类型选择解析器。复杂模型清洗也会引入偏差,因此质量判定应在独立的过滤与配比模块讨论。

#1. 解析先于“清洗”

原始 HTML、PDF、Office 文档、代码库与日志的结构不同。解析的任务是把有用内容与其顺序、边界保留下来。

输入 应保留 常见解析错误
网页 HTML 标题、正文、列表、链接语境 导航栏、广告混入正文
多栏 PDF 段落阅读顺序、图表标题、公式 左右栏交叉、页眉页脚插入句中
代码 缩进、文件边界、注释与依赖 去空格后语法损坏
表格 行列、表头与单位 单元格线性拼接后关系丢失
日志 时间、设备、事件边界 时间戳与事件内容脱钩
  • 只要丢失了结构,后续质量分类器也无法从纯文本恢复原来的表格列关系。
  • 对训练语料可在文本中保留结构标记;对 RAG 还要保留可回溯到原页面/段落的定位信息。

#1.1 HTML 解析:正文抽取与模板移除

HTML 解析的核心问题是区分正文(main content) 与模板(boilerplate) :导航栏、广告、页脚、相关文章链接、评论区。模板内容在网页间高度重复,如果混入训练语料,会放大特定模板的梯度影响,且不携带实质信息。

Trafilatura 是当前广泛使用的开源网页正文抽取工具。其方法组合了多种信号:DOM 树中的文本密度、链接密度(链接文本占该节点总文本的比例)、标签类型(<article>、<main> 优先于 <div>)、段落长度和标点密度。Trafilatura 在多个基准数据集上达到或超过商业工具(如 Diffbot)的抽取精度,同时保持开源可复现。

Readability 是 Mozilla 的正文抽取算法,最初用于 Firefox 的阅读模式。其核心启发式是:给每个 DOM 节点打分,分数基于文本长度、逗号数量、段落标签数量和链接密度,选择得分最高的节点作为正文容器。Readability 对新闻和博客效果良好,但对结构化页面(如产品页、表格密集型页面)容易遗漏内容。

DOM 树遍历方法 的通用流程:将 HTML 解析为 DOM 树;自底向上计算每个节点的文本密度和链接密度;识别正文候选节点;对候选节点内的段落按文档顺序输出。相比纯文本正则匹配,DOM 方法能保留标题层级和列表结构。

模板移除的评估:常用指标是正文/模板比例(content-to-boilerplate ratio)和抽取文本在原始页面中的覆盖率。但这两个指标都只是代理,最终需要人工抽样检查。

#1.2 PDF 解析:三条技术路线

PDF 与 HTML 的本质区别在于:PDF 是排版格式而非结构格式。PDF 文件描述的是“在页面某个坐标画某个字形”,而非“这是一个段落”。因此 PDF 解析需要从坐标信息中重建阅读顺序和结构。

路线一:文本层直接抽取。 适用于含文本层的 PDF(绝大多数原生数字 PDF)。工具如 PyMuPDF(fitz)、pdfplumber、pdfminer 直接读取 PDF 中的文本对象和坐标,按阅读顺序重排。文本层抽取速度快、不引入 OCR 误差,但对多栏布局、页眉页脚、脚注的处理需要额外逻辑。

多栏阅读顺序是文本层抽取的主要挑战。PDF 中文本框的坐标顺序不等于阅读顺序。简单的按 y 坐标排序在单栏文档中有效,但在双栏文档中会把左右栏交错。解决方案包括:检测栏边界(通过文本块的 x 坐标聚类);按栏分组后逐栏输出;对跨栏元素(如通栏标题)特殊处理。

路线二:版面分析后抽取。 使用版面检测模型识别页面中的区域类型(标题、段落、表格、图片、公式),再按区域类型分别抽取。代表工具:

  • GROBID:专为学术 PDF 设计,能识别标题、作者、摘要、章节、参考文献、公式和表格。输出 TEI XML 结构化文档。在学术文献解析中精度最高。
  • LayoutParser:基于 Detectron2 的版面检测库,支持多种预训练模型(PubLayNet、HJDataset),可检测文本、标题、列表、表格、图片区域。
  • Nougat(Meta):基于视觉 Transformer 的学术 PDF 解析模型,直接输出 Markdown 格式,支持公式(LaTeX)和表格。对扫描版学术 PDF 效果好,但可能“幻觉”生成原文没有的内容。

路线三:OCR 识别。 适用于扫描版 PDF 或纯图像 PDF。OCR 引擎(Tesseract、PaddleOCR、TrOCR)先识别字符,再按坐标重排。OCR 引入识别误差,需要与版面分析结合。

表格解析是 PDF 解析的独立难点。表格的单元格值依赖行名和列名,线性拼接后关系丢失。工具如 Camelot、Tabula 专门处理 PDF 表格,但只对有明确表格线的表格有效。无框线表格需要基于文本对齐和空白间距推断。

#1.3 代码解析:缩进与语法保真

代码的缩进是语法的一部分(Python、YAML),换行和符号也承载语义。通用文本解析器会做空白规范化,可能破坏代码。

代码解析的保真要求:保留缩进(空格和 Tab 的区别在某些语言中重要)、保留换行、保留注释、保留文件边界。Tree-sitter 是增量解析器,能生成代码的抽象语法树(AST),用于验证解析后的代码是否语法有效。如果解析后的代码无法通过编译器或解析器,说明清洗过程破坏了语法。

代码去重还需注意:不同仓库可能包含相同代码(fork、复制粘贴),生成式模型可能产出与训练集相似的代码。具体去重方法见去重。

#1.4 日志解析:模板抽取

日志解析的目标是从非结构化日志行中抽取模板(固定部分)和参数(可变部分)。例如:

2024-01-15 10:23:45 ERROR Connection refused to 192.168.1.1:8080

模板为 <timestamp> ERROR Connection refused to <ip>:<port>。

Drain 是基于固定深度解析树的在线日志解析算法。它将日志按 token 数分组,每组维护一棵解析树,新日志与已有模板匹配时更新参数位置。Drain 速度快、无需训练,是工业界广泛使用的日志解析基线。

日志解析的难点在于:不同服务的日志格式差异大;多行日志(如堆栈跟踪)需要合并;时间戳和事件内容可能脱钩。

#2. 规范化:哪些可以统一,哪些不能

#2.1 Unicode 规范化的四种形式

Unicode 标准定义了四种规范化形式:

形式 全称 作用
NFC Canonical Composition 将分解的字符组合为预组合字符(如 e + ´ → é)
NFD Canonical Decomposition 将预组合字符分解为基础字符 + 组合标记
NFKC Compatibility Composition 在 NFC 基础上应用兼容性映射(如全角 → 半角、连字 → 字母)
NFKD Compatibility Decomposition 在 NFD 基础上应用兼容性映射

训练语料通常保留原始形式,因为 NFKC 会合并视觉上不同但语义有别的符号(如数学减号 − 与连字符 -、希腊字母 α 与拉丁字母 a 在某些字体下相似但 Unicode 不同)。对模型而言,学习区分这些符号是有价值的。

比较视图与训练视图分离是推荐做法:用于去重和检索的比较视图 Nc(x)N_c(x) 可以应用 NFKC 来合并表面变体;用于训练和生成的保真文本 Nt(x)N_t(x) 保留原始 Unicode。两者不必相同。

ftfy(fixes text for you)是常用的文本修复库,能自动检测和修复 mojibake(编码错误导致的乱码),如将 ’ 修复为 '。它基于对乱码模式的统计识别,比简单的编码转换更稳健。

#2.2 空白与标点规范化的边界

  • 字符编码错误要尽早检测;把乱码当普通文本训练会让模型学习无意义片段。
  • Unicode 规范化可合并等价写法,但不应无条件替换数学符号、全半角变量、代码中的大小写。
  • 空白规范化对网页有益,对 Python 缩进、Markdown 表格和公式换行可能是破坏性的。
  • 页眉、版权脚注、站点导航可按文档类型处理;把所有重复短句都删掉会误删标题和重要警告。

示例: P = U × I 中的乘号、单位与变量需要保留;“把所有非 ASCII 字符删除”会直接损坏中文和数学内容。

#3. 基础过滤与质量过滤分开

#3.1 高确定性坏样本的识别

基础过滤只处理高确定性的坏样本:无法解码、主体为空、损坏严重、明显模板噪声。这些样本的判定不需要语义理解,规则即可覆盖。

C4 启发式规则(用于构建 C4 数据集)是经典的基础过滤规则集:

  • 只保留以标点符号结尾的行。
  • 丢弃少于 3 个词的页面。
  • 丢弃包含任何“不良词”的页面。
  • 丢弃代码行占比过高的页面。
  • 丢弃包含 lorem ipsum 的页面。
  • 丢弃包含花括号 {} 的页面(可能为代码或模板)。

Gopher 规则(用于构建 Gopher 数据集)是另一套广泛使用的规则:

  • 词数在 50–100,000 之间。
  • 平均词长在 3–10 个字符之间。
  • 符号与词的比例低于 0.1。
  • 以省略号结尾的行占比低于 0.1。
  • 80% 以上的词包含至少一个字母字符。
  • 包含至少两个常见停用词。

这两套规则的共同特点是高精度、低召回:它们只删除确定有害的样本,不尝试判断“质量高低”。主题相关性、写作质量、事实性与语言价值需要更复杂判断,归质量过滤。

#3.2 误删率的类别差异

若过滤器误删率为 FPR\mathrm{FPR},低资源类别样本本就少,则相同 FPR 造成的覆盖损失可能更严重。例如,某低资源语言在语料中只有 1% 的占比,FPR 为 5% 时,该语言损失 5% 的样本;但如果 FPR 对低资源语言的样本有系统性偏差(如规则依赖英文停用词),损失可能远高于 5%。

因此需按类别观察误删,而非只报告总准确率。评估基础过滤时,应分别统计不同语言、不同文档类型的保留率。

#4. 结构保真怎样衡量

样本类型 可检查信号 为什么有用
代码 解析器/编译器可接受比例 检查缩进与符号损坏
表格 行列数、表头与单位保留率 检查数据关系
PDF 文本 段落顺序、断词、乱码率 检查阅读顺序
网页 主体/模板比例 检查导航污染

这些指标都只是代理;仍要抽样查看真实文档,尤其是公式、代码与多栏页面。

#5. 演进:文本抓取到结构感知

纯文本抽取便宜,但多栏与表格信息丢失 → 版面/DOM 感知解析保留结构,但系统更复杂 → 模型辅助解析可处理难页面,却可能生成原文没有的内容。因此应区分可验证的原文提取与模型推断。

边界: 本页处理“原始内容变成可用文本”;去重处理重复,Tokenizer处理离散 token 化。

#6. 结构丢失为何会改变学习目标

原文若为表格,单元格值依赖列名与行名;纯文本拼接后,模型可能把相邻列错误配对。公式中的上下标、代码缩进、日志时间顺序也具有同样问题。设原始结构为 ss、解析文本为 T(s)T(s),若不同的 s1,s2s_1,s_2 被映射为同一个结果(如下式所示),则解析不可逆;训练模型无法从文本中恢复被丢掉的关系。

T(s1)=T(s2) T(s_1)=T(s_2)
文档类型 必须保留的关系 典型解析错误
表格 行、列、表头、单位 指标与数值错位
公式 上下标、分式、矩阵结构 x2→x2x^2\to x2
代码 缩进、换行、符号 语法和控制流改变
日志 时间、来源、事件序列 多线程事件错序
多栏 PDF 阅读顺序 左右栏文字交错

#7. OCR 质量不能只看可读性

字符错误率定义如下,其中 S,D,IS,D,I 是替换、删除、插入字符数,NN 为参考字符数。低 CER 也可能在关键数字/负号/单位上出错;技术文档应对实体、公式和表格单独统计。若无人工参考文本,可做版面完整性、语言异常和抽样复核,但不能声称已测得真实 CER。

CER=(S+D+I)/N \mathrm{CER}=(S+D+I)/N

OCR 引擎的代际差异:

  • Tesseract:传统 OCR 引擎,基于 LSTM 和规则,对清晰印刷体效果好,对复杂版面和手写体弱。
  • PaddleOCR:百度开源,支持多语言,检测+识别两阶段,对中文和表格效果好。
  • TrOCR:基于 Transformer 的 OCR,使用预训练视觉编码器和文本解码器,对模糊和倾斜文本更稳健。
  • Donut:端到端文档理解模型,直接输出结构化 JSON,无需单独的 OCR 步骤,但需要针对文档类型微调。

模型辅助解析可修复复杂版面,但若它“猜出”扫描模糊处,会把未经证实内容混入语料。应保留原页坐标或图像区域,让训练/检索文本可追溯到来源片段。这一要求与RAG的溯源需求一致。

#8. 规范化的可逆性选择

统一 Unicode、空白或标点能降低表面重复,但部分变换会合并原本不同的符号:希腊字母与拉丁字母、数学减号与连字符、全角与半角在某些语境下意义不同。可将规范化分为用于去重的比较视图 Nc(x)N_c(x) 和用于训练的保真文本 Nt(x)N_t(x);两者不必相同。这样既能比较近似文本,又不必牺牲模型学习原文格式的机会。

#原始资料

本页由仓库中的 Markdown 生成。具体技术结论请结合正文引用与实验条件理解。

输入关键词,探索整个知识库

↑ ↓ 选择 ↵ 打开36 篇笔记,一次搜索