所见即所得,赋能RAG:PDF解析里的段落识别
前几天,有一位用户使用OCR产品识别多栏论文后向我们询问:要怎么解决不合适的断句、分段以及错误阅读顺序的问题?
我们用一个相似案例为大家直观展示这位用户遇到的情况。

如图中的多栏期刊,如果用OCR识别,或直接在一些办公软件对文字进行复制黏贴,我们就会得到右侧的效果——按PDF排版而不是语义进行换行分段,对多栏文字直接从左向右排布,得到完全不通顺的文字段落。显然这样的效果是无法接受的。
于是,我们向用户推荐了文档解析产品,建议在处理多栏文件时使用文档解析来获得更好的识别结果。这是文档解析的同一篇期刊论文输出示例

可以看到,不论是自然段的划分,还是阅读顺序,甚至换页情况下的识别,都遵循了正确的阅读习惯。这正是我们在做文档解析过程中关注的重点之一,也是解析产品和过往纯OCR产品的不同之处:段落识别与阅读顺序还原。
今天,我们也想和大家聊聊,在Markdown Tester中,这个维度的指标是如何设计的。再次指路我们的测评工具https://github.com/intsig/markdown_tester
段落维度的指标包含了段落识别率、召回率,指标的计算方式后文我们会进行展开说明。
直观上来说,段落识别能力指的是系统能够识别和区分PDF文档中的不同段落,理解每个段落的开始和结束。
而阅读顺序的还原能力指的是系统能够根据PDF文档的布局和格式,推断出人类阅读时的顺序,而不仅仅是机械地判定为从左至右排序。
作为自然语言处理的利器,大模型需要的也正是与人类一致的阅读顺序,从预训练、调整到对话应用,正确、优质的语料能为大模型提供良好的工作基础。在实际情况中,文档智能应用场景往往包含着复杂的文档布局(如多栏、嵌套表格、不规则文本框等),正确识别段落和恢复阅读顺序是确保信息准确传达的关键要素之一。
以目前对PDF解析需求量相当高的RAG开发和数据清洗两个应用方向为例:在RAG(Retrieval-Augmented Generation)系统中,正确的阅读顺序还原有助于系统理解文档的逻辑结构和信息流,而正确的段落识别让系统能更准确地定位到文档中的关键信息段落,从而提高检索的准确性和生成内容的相关性。在优秀解析能力的辅助下,RAG分块(Chunking)策略也可以做进一步优化,用按段落分块取代固定长度切分,避免把完整的段落文字“拦腰斩断”、影响语义理解与生成的问题。而在数据清洗和模型训练过程中,解析工具能够保持文档的原始阅读顺序,段落识别则有助于将PDF文档分割成更小的、语义上独立的单元。这使得训练数据更加结构化,对于训练模型理解文档的层次结构和内容组织至关重要,能有效提高模型的训练效果、泛化能力和对复杂文档的理解能力。
来看看我们的Markdown Tester如何评估这两个维度的解析效果。此处涉及4个指标:平均阅读顺序指标=计算预测值和真值中,所有匹配段落的编辑距离(排版用正副标题)编辑距离的概念,我们在上一期文章《聊聊文档解析测评里的表格指标》里介绍过。(+链接)它指的是,对给定的两个字符串,最少要经历多少次插入、删除、替换操作,才能使两个字符串完全一样。在阅读顺序指标中,我们应用同样的概念对匹配段落进行检测,在这一项中得分越高,意味着解析结果中的阅读顺序与实际越匹配、差异越小,也即还原效果越好。段落识别率=段落匹配的个数(段落编辑距离小于0.2) / 预测出的总段落数段落识别率指的是被正确识别的段落数量占所有识别出的段落总数的百分比。它测量的是段落解析够不够“准”。
举一个比较直观的例子来说明段落识别率和段落召回率分别代表的含义。现在我们有一篇需要识别的短文,它有3个段落,分别为:
+----------------+
段1:开头
+----------------+
+----------------+
段2:正文
+----------------+
+----------------+
段3:结尾
+----------------+
在解析过程中,段1、段2被正确识别,而段3被识别为了2个分开的段落。
即解析结果为:
+----------------+
段1:开头
+----------------+
+----------------+
段2:正文
+----------------+
+----------------+
段3:发展
+----------------+
+----------------+
段4:结尾
+----------------+
那么,在这个案例中,段落识别率=2/4=50%。段落识别率反映了产品正确识别段落的能力,即查准率。识别率越高,意味着系统在识别段落时的准确性越高。段落召回率=段落匹配的个数(段落编辑距离小于0.2)/ 总的段落数段落召回率是指被识别到的相关段落数量占实际总段落数的百分比。它测量的是段落解析是不是“全”。
我们继续看前面的短文案例,此处的段落召回率=2/3=66.67%。简单来说,就是原文的3个段落中里,我们正确找到了其中的2个。它衡量了解析产品在识别文档时的查全率。召回率越高,意味着越能够正确找到所有段落。段落F1=2 * (段落识别率 * 段落召回率) / (段落识别率 + 段落召回率)F1值是识别率和召回率的调和平均值,它综合考虑了这两个指标,用于评估文档解析的整体性能。F1值越高,通常意味着文档解析的性能越好。
本期,我们主要介绍了PDF解析中段落与阅读顺序相关的指标及重要性。
关于公式、标题的讨论,我们也将继续深入。
之后,我们还会不断扩充测评的维度、厂商,更好地满足大家的需求。欢迎各位开发者随时给我们提出需求,包括但不限于对这个tester本身的优化建议,或者提供样本找我们对比测试,甚至是指定产品做对比测试~
TextIn文档解析产品目前正在内测计划中,为每位用户提供每周7000页的额度福利,关注公众号《合研社》即可申领。关于测评工具、产品或需求,都可以随时找我们沟通。我们欢迎所有探讨和交流!
所见即所得,赋能RAG:PDF解析里的段落识别的更多相关文章
- PDF解析记录——Pdfbox
此文仅作记录[嫌放电脑里碍事-_-],内容为以前收集的一小段代码. 下面为pdf获取文本的简要代码片段: private string GetPDFText(string filename) { ...
- pdf解析与结构化提取
#PDF解析与结构化提取##PDF解析对于PDF文档,我们选择用PDFMiner对其进行解析,得到文本.###PDFMinerPDFMiner使用了一种称作lazy parsing的策略,只在需要的时 ...
- 【PDF】手写字与识别字重叠
[PDF]手写字与识别字重叠 前言 同学平时上课用iPad记笔记,考试之前导出为PDF发给我后,我用PDF打开,发现可以直接Ctrl+F搜索一些词语.一直不知道是怎么做到的,毕竟里面的字都是手写的,不 ...
- 温故知新,.Net Core利用UserAgent+rDNS双解析方案,正确识别并反爬虫/反垃圾邮件
背景 一般有价值的并保有数据的网站或接口很容易被爬虫,爬虫会占用大量的流量资源,接下来我们参考历史经验,探索如何在.Net Core中利用UserAgent+rDNS双解析方案来正确识别并且反爬虫. ...
- 当页面是本地页面时,通过ajax访问tomcat里的action,传递的参数在action里并不能识别
当页面是本地页面时,通过ajax访问tomcat里的action,传递的参数在action里并不能识别,这个问题困扰了我不少时间. 在测试时发现此问题
- PDF解析
解析如下图PDF文件 using System; using System.Collections.Generic; using System.Linq; using System.Text; usi ...
- 如何将一个PDF文件里的图片批量导出
假设我有下面这个PDF文件,里面有很多图片,我想把这些图片批量导出,而不是在Adobe Acrobat Reader里一张张手动拷贝: 本文介绍一种快捷做法. 用PDF-XChange Editor打 ...
- PDF解析帮助类
public class ComPDFHepler { /// <summary> /// 正则获取字符串中两个字符串间的内容 /// </summary> /// <p ...
- PDF解析。。。
解析出PDF中的文字.用项目名称作Key取对应的值.. 正则匹配 .....:..\n
- 如何添加、删除、合并PDF文件里的页面?
使用Adobe Acrobat. Adobe中文官网http://www.adobe.com/cn/products/acrobat.html 能够自己下载破解版. watermark/2/text/ ...
随机推荐
- Docker自定义网段实现容器间的互访【开发环境中】
我们都知道docker容器之间是互相隔离的,不能互相访问,但如果有些依赖关系的服务要怎么办呢,所以自定义网段实现容器间的互访. Docker 安装好之后默认会创建三个虚拟网卡,可以使用 docker ...
- 如何去除字符串中的 "\n" ?80% 的同学错了!
大家好,我是鱼皮,今天分享一个小知识. 我最近负责的工作是设计一个 SQL 解析引擎.简单来说,就是将一个 SQL 表达式字符串,解析为一颗对象树,从而执行查询等一系列操作. 在最开始,我就遇到了一个 ...
- 怎么用git命令将其他分支的提交记录提取到当前分支上
您可以使用 Git 命令 "cherry-pick" 将其他分支的提交记录提取到当前分支上.以下是使用 cherry-pick 命令的步骤:1. 切换到当前分支: `git che ...
- oeasy教您玩转vim - 67 - # 批量替换
批量替换 回忆上次 我们可以用vimdiff快速的比较文件 这很实用!!! 实用的一些跳转方式 遍历所有的修改change ]c 下一条修改 [c 上一条修改 遍历所有的函数method ]m 下 ...
- 工作单元(UnitOfWork) 模式 (1)
在开始UnitOfWork模式之前有必要回顾下我们耳熟能详的Data Access Object(DAO)模式,即数据访问对象.DAO是一种简单的模式,我们构建应用的时候经常会使用到它,它的功能就是将 ...
- Linux安全启动及Machine Owner Key(UEFI BIOS MBR GPT GRUB)
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 环境说明 无 前言 只要装过各种系统的人都或多或少会接触 ...
- Python 利用argparse模块实现脚本命令行参数解析
利用argparse模块实现脚本命令行参数解析 By:授客 QQ:1033553122 #代码实践1 study.py内容如下 #!/usr/bin/env python # -*- coding:u ...
- Gymnasium 环境搭建
[默认在链接公网环境]!!!! 一. Conda虚拟环境搭建[安装则忽略] 1.1 检查本地适配python版本 >python -V 1.2根据版本下载并安装aconda[这里默认使 ...
- 【Java】Collection子接口:其二 Set 组接口
Collection子接口:其二 Set 组接口 - Set接口是Collection的子接口,Set没有提供额外的方法 - Set集合中不允许包含重复的元素,如果重复添加,只保留最新添加的那一个 - ...
- 【IDEA】DEBUG调试问题
不要将断点打在方法的声明上: 会有一个菱形标志,在标记之后运行DEBUG模式会跑不起来 查看所有的断点标记: 在这里直接找到所有标记位置,弄掉就会跑起来了