如何标注文档与 PDF
把合同、报告和论文当作文档来标注,而不是压平成纯文本,让版面、页码和跨页引用都保留下来。
在文档渲染出来的页面上标注,而不是在从中抽取的文本上标注,因为版面承载着抽取会丢掉的意义,也因为复核的人需要在页面上找到那个标签。 把一份合同压平成一个字符串,页码、分栏顺序、表格结构以及脚注和正文的区别都会丢失。
文档标注正是常规文本标注那套做法失效的场合。PDF 描述的是页面上的标记,而不是一串字符,所以两个不同的抽取器会从同一个文件里给出两个不同的字符串。多栏页面会相互穿插,页眉页脚会出现在正文流中间,表格会变成一长串空白。在那个字符串上打标签的标注者,实际上是在给抽取器的产物打标签,而后来打开原件的复核者,并不总能判断某个片段指的是哪一段。
位置、页码和引用结构
文档有三项属性只在页面上留存,在抽取出的文本里不留存。位置告诉复核者某个条款是标题、脚注还是正文,而抽取会把三者压成同一串没有区别的字符。页码是此后每一位读者引用这段话的依据,而它只在页面存在时才存在。引用结构记录一段话指向什么,只要某一页上的论断依赖于九页之后的一张表,这一点就很重要。
最常逼人换工具的是第三项属性。文档内部的引用结构是两个位置之间的关系,而把文档建模成一个扁平字符串的工具,没有地方放第二个位置。法律审查、科学论断核实和财报分析,都围绕着这种关系。
三种锚定方式
文档上的标注有三种锚定方式,选哪一种取决于问题本身,而不是偏好。
- 文本片段锚定在选中的词上,适合关于措辞的问题。片段要求文档带有文本层,原生数字 PDF 有这一层,扫描件没有。
- 区域框锚定在页面坐标上,适合图、表、印章、签名,以及任何文本层从未捕获的内容。它在完全没有文本抽取的扫描件上也能用。
- 链接连接两个锚点,适合引用结构。一条链接记录文档中两个位置之间带类型、可选带方向的关系。
在一个任务里混用多种锚定方式很常见。论断核实任务把论断标为文本片段,把表格标为区域框,再用链接把二者连起来。
在 Potato 中的配置
Potato 的 pdf 显示类型用 PDF.js 渲染文件,并把标注层放在渲染后的页面上。annotation_mode 选项决定锚定方式,取值为 span、bounding_box 或 link。回答引用问题的是链接模式,它把锚点和链接记在两个不同的 schema 名下,所以导出时二者可以区分开。
instance_display:
fields:
- key: pdf
type: pdf
label: "Document"
display_options:
annotation_mode: link
view_mode: scroll
zoom: page-width
enable_text_anchors: true
enable_region_anchors: true
anchor_schema: pdf_anchors
link_schema: pdf_links
anchor_labels:
- name: claim
color: "#dc2626"
- name: figure
color: "#2563eb"
link_types:
- name: refers_to
directed: true
allowed_source_labels: [claim]
allowed_target_labels: [figure]view_mode: scroll 把各页堆叠在一个容器里,于是第 2 页和第 9 页之间的链接可以画成、也看成一道完整的弧线。分页的那种方式一次只显示一页,长文档读起来更舒服,但标注者画跨页链接时看不到另一端。
allowed_source_labels 和 allowed_target_labels 是把一条指南变成界面会强制执行的东西。按上面的配置,refers_to 链接只能从论断出发、只能落在图上,标注者没法把这种关系记反。只写在文档里的指南,执行程度参差不齐,而工具施加的约束,执行起来不花成本。
Word 或 Markdown 文件改用 document 显示类型,它保留标题和段落结构,并接受 span_target,所以片段 schema 可以直接指向它。
扫描文档
扫描件不带文本层,文本锚点没有可以附着的东西。有两个选择,各自适合不同的语料。按区域标注完全不需要文本,可以立刻上手。开启 OCR 会在服务端生成一层文本,让文本锚点成为可能,代价是一次缓慢的处理过程和对 Tesseract 的依赖。
instance_display:
fields:
- key: pdf
type: pdf
display_options:
annotation_mode: link
ocr: autoauto 只在内嵌文本层返回为空时才运行 OCR,混有原生数字文件和扫描件的语料就该用这个设置。Potato 只在链接模式下读取 ocr 选项。
OCR 的输出并不完美,锚定在识别错误的词上的标注会继承这个错误。在识别质量较差的语料上,区域锚点比文本锚点留下的记录更耐久,因为围着一段内容画出的框,无论底下的字符被读成什么,都还是对的。
拿标签去核对原件
每条标注返回时都带着它所在的页,这正是标签可以拿回原件核对的原因。拿到页码和区域的复核者,可以打开原件确认这个判断。拿到拼接字符串中字符偏移量的复核者通常做不到,因为要复现那个偏移量,就得复现生成它的那个抽取器及其版本。
这种做法得不偿失的场合,是由短小的、单栏的、原生数字的、没有引用结构的文档构成的语料,那里抽取可靠,页码也不承载什么。在这种情况下,对抽取文本做普通的片段标注更简单,而且给出同样的答案。