pdf 版面分析与优化策略

1. 简介

版面分析作为RAG的第一步工作,其效果对于下游工作至关重要。
在这里插入图片描述

前常见的 PDF 解析方法包括三种

  • 基于规则:根据 PDF 的组织特征确定每个部分的规则(风格和内容)缺点:不通用(PDF格式不固定)
  • 基于深度学习:目标检查和 OCR 结合的流行解决方案
  • 基于多模态大模型:对复杂的结构进行Pasing或提取PDF中的关键信息

1.1 基于规则的pdf解析

代表框架:

  • pdfplumber
  • PyMuPDF
  • pypdf
1.1.1 pdfplumber

pdfplumber 按照每一页处理 pdf,获得 pdf 的页面文字提取表格,最终将 pdf 文件生成对应的 txt 文件。
缺点:按页进行处理有时候一段上下文连续的文字,分散到两页并不好进行处理。

## 纯文本
file_name = './example_data/焦点科技__2019年__年度报告.pdf'
output_file = './example_data/焦点科技__2019年__年度报告.txt'
with pdfplumber.open(file_name) as pdf, open(output_file, 'wt', encoding='utf-8') as f:for page in pdf.pages: # pdf.pages是⼀个Page对象的列表text = page.extract_text() # 调⽤Page对象的extract_text()⽅法提取⽂本f.write(text)f.write('\n')## 表格
with pdfplumber.open(file_name) as pdf, open(output_file, 'wt', encoding='utf-8') as f:for page in pdf.pages: # pdf.pages是⼀个Page对象的列表text = page.extract_table() # 提取每⻚的表格⽂字信息# page.extract_tables() 提取多个表格print(text)if text:f.write(str(text))f.write('\n')## 表格保存为excel
from openpyxl import Workbook
with pdfplumber.open(file_name) as pdf:for i in pdf.pages:table = i.extract_table()if table:workbook = Workbook() # 创建⼀个⼯作簿sheet = workbook.active # 获取当前活跃的sheet,默认是第⼀个sheetfor row in table:sheet.append(row)workbook.save(output_file) # 保存⼯作簿break## 提取图片保存到本地
with pdfplumber.open(file_name) as pdf:for i in pdf.pages:print('⻚码:', i.page_number)print('⻚宽:', i.width)print('⻚⾼:', i.height)print('⻚⽂本:', i.extract_text())print('⻚表格:', i.extract_table())print('⻚图⽚:', i.images)for img in i.images:# 获取图⽚的⼆进制流img_data = img['stream'].get_data()with open(output_file, 'wb') as f:f.write(img_data)break # 解析第⼀⻚
1.1.2 pymupdf

pymupdf 支持将文字修改写入 pdf 的界面,支持提取所有类型的文档,支持的功能特别多,基本上各种文件都可以处理

import fitz
pdf_path = '/example_data/安靠智电__2019年__年度报告.pdf'
doc = fitz.open(pdf_path)# 基本的pdf信息
title = doc.metadata['title'] # 标题
author = doc.metadata['author'] # 作者
create_time = doc.metadata['creationDate'] # 创建时间
num_pages = doc.page_count # ⻚数
page = doc.load_page(0) # 加载第⼀⻚
page_width = page.rect.width # ⻚宽
page_height = page.rect.height # ⻚⾼
page_text = page.get_text() # ⻚⽂本
page_images = page.get_images(full=True) # ⻚图⽚
print('标题:', title)
print('作者:', author)
print('创建时间:', create_time)
print('⻚数:', num_pages)
print('⻚码:', 1)
print('⻚宽:', page_width)
print('⻚⾼:', page_height)
print('⻚⽂本:', page_text)
print('⻚图⽚:', page_images)num_pages = doc.page_count # ⻚数
for page_index in range(num_pages):page = doc.load_page(page_id=page_index)page_text = page.get_text() # ⻚⽂本print(page_text)breakfor page_index in range(num_pages):page = doc.load_page(page_id=page_index)image_list = page.get_images() # 图⽚print(image_list)# 两种⽅式# 1for img in image_list:xref = img[0]base_image = doc.extract_image(xref)image_bytes = base_image["image"] # 图⽚⼆进制数据image_ext = base_image["ext"] # 图⽚格式# image_path = f'./example_data/__焦点科技__2019年__年度报告__page_{page_index}__image_{xref}.{image_ext}'# with open(image_path, 'wb') as f:# f.write(image_bytes)# 2pix = fitz.Pixmap(doc, xref)pix.save(f'./example_data/焦点科技__2019年__年度报告__page_{page_index}__image_{xref}.png')break## 获取表格
for page_index in range(num_pages):page = doc.load_page(page_id=page_index)tables = page.find_tables() # 表格print(tables)# 提取表格数据并存储为csv⽂件for table in tables:df = table.to_pandas()print(df.head())df.to_csv(f'./example_data/焦点科技__2019年__年度报告_page_{page_index}__table_{table}.csv',index=False)break## PDF文档分割
output_dir = './example_data/{0}.pdf'
for page_index in range(num_pages):print(page_index)# 创建⼀个新的Document对象,包含当前⻚⾯new_pdf = fitz.open()new_pdf.insert_pdf(doc, from_page=page_index, to_page=page_index)# 保存为单独的pdf⽂件new_pdf.save(output_dir.format(page_index))new_pdf.close()break
doc.close()
1.1.3 pypdf

pypdf 就是一种基于规侧广泛使用的解析器,也是 LangChain 和 Llamalndex 中解析 PDF文件的标准方法。

pip install PyPDF2

在这里插入图片描述

import PyPDF2
filename = "./example_data/焦点科技_2019年__年度报告.pdf"
pdf_file = open(filename, 'rb')
reader = PyPDF2.PdfReader(pdf_file)
page_num = 0
page = reader.pages[page_num]
text = page.extract_text()
print('--------------------------------------------------')
print(text)
pdf_file.close()
'''
焦点科技股份有限公司 2019年年度报告全⽂ 
1 
焦点科技股份有限公司 
Focus Technology Co., Ltd. 
(南京江北新区星⽕路软件⼤厦 A 座12F)
⼆〇⼀九年年度报告 
⼆〇⼆〇年⼆⽉
'''

1.2 基于深度学习的pdf解析

基于深度学习模型的方法能够准确地识别整个文档的布局,包括表格和段落。它甚至可以理解表中的结构。这意味着它可以将文档划分为定义明确、完整的信息单元。同时保留预期的含义和结构。
代表性的开源框架:

  • Unstructured: 已经集成到langchain中。使用hi_res策略设置infer_table_structure=True 可以很好的识别表格信息。然而 fast策略因为不使用目标检测模型,在识别图像和表格方面表现比较差。
  • Layout-parser:如果需要识别复杂的结构化PDF ,建议使用最大的模型以获得更高的精度,但是会比较慢。此外,Layout解析器的模型在过去几年中似乎没有更新。
  • PP-StructureV2: 可以组合各种模型用于文档分析,性能高于平均水平。
Unstructured
from unstructured.partition.pdf import partition_pdf
filename = "../paper/bert.pdf"
# infer_table_structure=True automatically selects hi_res strategy
elements = partition_pdf(filename=filename, infer_table_structure=True)
tables = [el for el in elements if el.category == "Table"]
print(tables[0].text)
print('--------------------------------------------------')
print(tables[0].metadata.text_as_html)

1.3 基于多模态的pdf解析(复杂结构)

LlamaIndex例子:检索相关图像(PDF页面)并将其发送到GPT4-V 以响应查询。

  1. 将每个PDF页面视为一个图像,让GPT4-V 对每个页面进行图像推理,为图像推理构建文本矢量存储索引,根据图像矢量存储查询答案。
  2. 使用Table Transformer从检索到的图像中裁剪表信息,然后将这些裁剪的图像发送到GPT4-V 进行查询相应。
  3. 对裁剪的表图像应用OCR,并将数据发送到GPT4 以回答查询。

经测试确定第三种方法最有效。
此外可以试用多模态模型从图像中提取或者总结关键信息(PDF文件可以很容易转换为图像)

1.3.1 解析pdf文档存在哪些挑战

挑战在于准确提取整个页面的布局,并将表格、标题、段落和图片在内的内容翻译成文档的文本表示。这个过程涉及到处理文本提取、图像识别中的不确定之处,以及表中行-列关系的混乱。

1.3.1.1 挑战一:如何从表格和图像中提取数据问题?

使用unstructured框架作为示例,检测到的表格数据可以直接导出为HTML:
在这里插入图片描述
复制HTML标记并将其另存为HTML文件,使用Chrome打开如下:
在这里插入图片描述

1.3.1.2 挑战二:如何重新排列检测到的块?特别对于双列PDF?

在这里插入图片描述
在确定布局后,unstructured框架会将每个页面划分成几个矩形块:

在这里插入图片描述
每个矩形块的详细信息可以通过以下格式获取:
在这里插入图片描述
其中(x1, y1)是左上顶点的坐标,(x2, y2)是右下顶点的坐标
在这里插入图片描述
此时,可以选择重新调整页面的阅读顺序。unstructured 有一个内置排序算法。但是实际排序结果不是很满意。
因此有必要设计一种排序算法。最简单的方法就是先按左上角顶点的水平座标排序,如果水平座标相同,则按垂直坐标排序。伪代码如下:

layout.sort(key=lambda z:(z.bbox.x1, z.bbox.y1, z.bbox.x2, z.bbox.y2))

然而还发现,即使同一列中的块,其水平坐标也可能发生变化。如下图,提取到的紫色线条块的水平坐标bbox.x1 实际更靠左。排序时他将位于路线块之前,显然违反了阅读顺序。

在这里插入图片描述
在这种情况下使用一种可能的算法:

  • 首先,对左上角所有x坐标x1 进行排序,可以得到X1_min
  • 然后,对所有右下角x坐标x2进行排序,可以得到x2_max
  • 接下来,将页面中心线的x坐标确定x1_min = min([el.bbox.x1 for el in layout]) ; x2_max = max([el.bbox.x2 for el in layout]); mid_line_x_cooedinate = (x2_max + x1_min)/2
  • 接下来,如果bbox.x1< mid_line_x_cordinate ,则块被分类为左列的一部分。否则被视为右边的一部分。
  • 分类完成后,根据列中的y坐标对每个块进行排序。
  • 最后,将右侧列连接到左侧列的右侧
left_column, right_column = [], []
for el in layout:if el.bbox.x1 < mid_line_x_cooedinate:left_column.append(el)else:right_column.append(el)left_column.sort(key = lambda z: z.bbox.y1)
right_column.sort(key = lambda z: z.bbox.y1)
sorted_layout = left_column + right_column

值得一提的是这种改进也与单列pdf兼容.

1.3.1.3 挑战三:如何提取多级标题?

提取多级标题的目的是提高LLM答案的准确性。
该算法依然依赖与上面提到的布局快。我们可以设置type=‘Section-hearder’的块,并计算高度差(bbox.y2-bbox.y1)。高度差最大的块对应第一级标题,其次是第二级标题…

补充:PPT类文档解析问题

  • 难点:如何对PPT 中的大量的流程图,架构图进行提取,因为这些图多以形状元素在PPT中呈现,如果只提取文字,大量潜藏的信息会大量丢失。
  • 解决办法:将PPT转为pdf形式,然后用户上述处理PDF 的形式进行解析。

参考:
版面分析–优化策略篇
【知识库构建——知识文本分块】
【知识库构建——文档切分优化策略篇】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/836685.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GPT搜索引擎原型曝光!

OpenAI发布会前一天&#xff0c;员工集体发疯中……上演大型套娃行为艺术。 A&#xff1a;我为B的兴奋感到兴奋&#xff1b;B&#xff1a;我为C的兴奋感到兴奋……Z&#xff1a;我为这些升级感到兴奋 与此同时还有小动作不断&#xff0c;比如现在GPT-4的文字描述已不再是“最先…

618购物节适合入手的数码好物有哪些?实用闭眼冲的数码好物清单

随着618购物节的临近&#xff0c;数码爱好者们纷纷翘首以盼&#xff0c;期待着在这个年度大促中寻觅到心仪的数码好物&#xff0c;无论是提升工作效率的办公利器&#xff0c;还是丰富业余生活的娱乐设备&#xff0c;数码产品在我们的日常生活中扮演着越来越重要的角色&#xff…

电路板维修【三】

自恢复保险丝&#xff1a; 自恢复保险丝属于慢断类型保险丝&#xff0c;自恢复保险丝的材料因为通电后发热&#xff0c;当电流过大发热到一定程度的时候&#xff0c;材料就不导电了&#xff0c;这个和普通的保险丝是一个道理&#xff0c;只不过普通的保险丝是一次型熔断而已。…

【5月13日】YesPMP平台目前最新项目

YesPMP平台目前最新项目&#xff0c;有感兴趣的用户查看项目接单&#xff0c;与项目方沟通&#xff0c;双方直接对接。 1.查看项目&#xff1a;blender动画师 2查看项目&#xff1a;找宠友信息源码 3.查看项目&#xff1a;儿童…

ComfyUI 完全入门:必备插件

大家好&#xff0c;我是每天分享AI应用的萤火君&#xff01; ComfyUI 是一个基于 Stable Diffusion 的AI绘画创作工具&#xff0c;最近发展势头特别迅猛&#xff0c;但是 ComfyUI 的上手门槛有点高&#xff0c;用户需要对 Stable Diffusion 以及各种数字技术的原理有一定的了解…

【Web】CTFSHOW 月饼杯 题解(全)

目录 web1_此夜圆 web2_故人心 web3_莫负婵娟 web1_此夜圆 拿到源码&#xff0c;一眼字符串逃逸 本地测一测&#xff0c;成功弹出计算器 <?phpclass a {public $uname;public $password;public function __wakeup(){system(calc);} }function filter($string){retur…

全新Transformer模型:全球与局部双重突破!

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享&#xff0c;与你一起了解前沿深度学习信息&#xff01; 引言&#xff1a;探索视觉变换器在对象重识别中的全局与局部特征 在对象重识别&#xff08;Re-ID&#xff09;的研究领域中&#xff0c;如何有效地从不同时间…

奇舞周刊第527期:​Virtual DOM(虚拟DOM) 的地位再一次被挑战 !!!

奇舞推荐 ■ ■ ■ Virtual DOM&#xff08;虚拟DOM&#xff09; 的地位再一次被挑战 &#xff01;&#xff01;&#xff01; 最近在前端圈有一个 Github Repo 算是蛮受关注的 - proposal-signals&#xff0c;这是一个由 Daniel Ehrenberg 为主导&#xff0c;向 TC39 提案的项目…

26版SPSS操作教程(高级教程第二十章)

目录 前言 粉丝及官方意见说明 第二十章一些学习笔记 第二十章一些操作方法 神经网络与支持向量机 人工神经网络&#xff08;artificial neural network&#xff0c;ANN&#xff09; 假设数据 具体操作 结果解释 对案例的进一步分析 结果解释 ​编辑 尝试将模型复…

自动驾驶技术与传感器数据处理

目录 自动驾驶总体架构 感知系统 决策系统 定位系统 ​计算平台​ 仿真平台​ 自动驾驶公开数据集 激光点云 点云表征方式 1) 原始点云 2) 三维点云体素化 3)深度图 4)鸟瞰图 点云检测障碍物的步骤 PCL点云库 车载毫米波雷达 车载相机 设备标定 自动驾驶…

Matlab如何导出高质量论文插图?科研效率UpUp第8期

当你用Matlab绘制了一张论文插图&#xff1a; 想要所见即所得&#xff0c;原封不动地将其保存下来&#xff0c;该怎么操作呢&#xff1f; 虽说以前总结过7种方法&#xff08;Matlab导出论文插图的7种方法&#xff09;&#xff0c;但要说哪一种可以满足上面的要求&#xff0c;想…

UV胶固化时使用的UV灯要如何选择才适合!

近日&#xff0c;在使用UV灯固化 UV胶的过程中&#xff0c;遇到了不同的问题&#xff0c;最基本的就是很多人对于固化UV胶时&#xff0c;使用什么样的UV灯不清楚&#xff0c;从而导致了UV胶在实际使用过程中没有固化&#xff0c;或者没有完全固化&#xff0c;胶水仍处是液体流动…

2024年AIGC发展趋势报告

来源&#xff1a;靠谱二次元 AIGC&#xff0c;即人工智能生成内容&#xff0c;是近年来在人工智能领域兴起的一项重要技术。 它通过使用机器学习和深度学习等技术&#xff0c;使得计算机能够自动生成各种形式的数字内容&#xff0c;如文本、图像、音频和视频等。 AIGC的发展可…

批量处理文件,高效分发数据:一键操作解决繁琐工作的技巧

在数字化时代&#xff0c;文件处理和数据分发已经成为许多行业日常工作中不可或缺的一部分。然而&#xff0c;面对大量的文件和数据&#xff0c;传统的手动处理方式往往显得繁琐且效率低下。幸运的是&#xff0c;现代技术为我们提供了办公提效工具批量处理文件&#xff0c;高效…

【谷粒商城】01-环境准备

1.下载和安装VirtualBox 地址&#xff1a;https://www.virtualbox.org/wiki/Downloads 傻瓜式安装VirtualBox 2.下载和安装Vagrant官方镜像 地址&#xff1a;https://app.vagrantup.com/boxes/search 傻瓜式安装 验证是否安装成功 打开CMD,输入vagrant命令&#xff0c;是否…

Transformer模型详解04-Encoder 结构

文章目录 简介基础知识归一化作用常用归一化 残差连接 Add & NormFeed Forward代码实现 简介 Transformer 模型中的 Encoder 层主要负责将输入序列进行编码&#xff0c;将输入序列中的每个词或标记转换为其对应的向量表示&#xff0c;并且捕获输入序列中的语义和关系。 具…

Linux基础之进程-fork()函数的详解

目录 一、前言 二、fork()函数 2.1 fork()函数的基本概念 2.2 问题一的解答 2.3 问题二的解答 2.4 问题三的解答 2.5 问题四的解答 2.6 问题五的解答 一、前言 在上节内容中我们已经学会了使用我们的getpid()和我们的getppid()去查看我们进程的pid&#xff0c;并且学习到…

FastAPI:Python打造高效API的终极武器

在Python的世界里&#xff0c;如果你想要一个既快速又现代的方式来构建API&#xff0c;那么FastAPI可能是你的首选。这个库基于Starlette&#xff08;用于Web编程&#xff09;和Pydantic&#xff08;用于数据验证&#xff09;&#xff0c;专门为速度和易用性设计。 什么是FastA…

【系统架构师】-案例篇(三)NoSQL与分布式对象调用

1、NoSQL 一个基于Web 2.0的大型社交网络系统。就该系统的数据架构而言&#xff0c;李工决定采用公司熟悉的数据架构&#xff0c;使用通用的商用关系型数据库&#xff0c;系统内部数据采用中央集中方式存储。该系统投入使用后&#xff0c;初期用户数量少&#xff0c;系统运行平…

【LeetCode】每日一题 2024_5_13 腐烂的橘子(经典多源 BFS)

文章目录 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01;题目&#xff1a;找出不同元素数目差数组题目描述代码与解题思路 每天进步一点点 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01; 好久没写每日一题题解了&#xff0c;今天重新起航 干…