RAG 系列之二:PDF 文件的解析

RAG 系列之二:PDF 文件的解析在 RAG(检索增强生成)简介的流程图中,有一个环节是检索向量数据库(下图中红色框标识的部分)。向量数据库存储了外部知识库经过向量化处理的内容。在检索之前,我们首先需要创建向量数据库,而创建的第一步是解析知识库中的文件,提取其中的文本、表格

大家好,欢迎来到IT知识分享网。

在 RAG(检索增强生成)简介的流程图中,有一个环节是检索向量数据库(下图中红色框标识的部分)。向量数据库存储了外部知识库经过向量化处理的内容。在检索之前,我们首先需要创建向量数据库,而创建的第一步是解析知识库中的文件,提取其中的文本、表格等信息。由于 PDF 格式的文件占据了文件的大部分,因此如何从 PDF 文件中精确且高效地提取这些信息,便成为创建向量数据库的关键。本文将介绍如何解析 PDF 文件,帮助实现这一目标。

RAG 系列之二:PDF 文件的解析

PDF,即便携式文档格式(英语:Portable Document Format,缩写 PDF),是一种能够独立于应用程序、硬件和操作系统呈现文档的文件格式。PDF 之所以受欢迎,是因为它能够完全保留原文档的格式,不受设备、软件或系统的影响,这对于传播信息来说意义重大。试想一下,如果你使用的是 Word 文档,一旦更换设备,字体、图片、颜色和格式等可能都会发生变化。但 PDF 不会出现这种情况,它能够原汁原味地保留重要的图文信息,不用担心设备的影响。正是为了实现这种显示的一致性,PDF 牺牲了可编辑性。这里有一点需要注意,不是 PDF 不想做到容易编辑,也不是故意让你无法修改,而是为了极致的显示一致性,必须牺牲可编辑性。PDF 会将文本的位置、字体、间距、缩放比例、页边距等所有属性在文件格式中限定死,让软件没有自由发挥的空间。这就是为什么不同软硬件打开 PDF 效果都能一致的原因。本质上,PDF 的格式限制确保了它在任何设备上的显示效果都一样。比如,一个包含 “Hello World” 字样的 PDF 文件用 PDF 阅读器打开时,效果如下面的左边所示。如果用文本编辑器打开这个 PDF 文件,显示结果如下面的右边所示。

RAG 系列之二:PDF 文件的解析

看到上面的这个文件内容,我们也就明白了 PDF 为什么难于编辑的原因了。但也正是这个文件,会手把手地告诉电脑,怎么一点一点把这个文件的内容在屏幕上打印出来,最大程度地确保了所有人看到这个文件的效果都一样。

上面说的这类 PDF 文件是文本 PDF,也就是机器生成的 PDF。还有一类 PDF 文本 是扫描 PDF,这类文件的每一页都是一张图片,所用到的解析方法和文本 PDF 也是不一样的。下面就分别把解析两类 PDF 文件效果还不错的工具介绍给大家。

文本 PDF 的解析

文本的提取

能够进行文本提取的 Python 库包括:pdfminer.six、PyMuPDF、PyPDF2 和 pdfplumber,效果最好的是 PyMuPDF,PyMuPDF 在进行文本提取时能够最大限度地保留 PDF 的阅读顺序,这对于双栏 PDF 文件的抽取非常有用。下面就以难度比较大的双栏 PDF 为例,来介绍使用 PyMuPDF 库进行文字抽取的效果。

我们以下面的 PDF 为例来看使用 PyMuPDF 进行文字提取的效果。

RAG 系列之二:PDF 文件的解析

进行文本提取的代码如下:

import pymupdf pages = pymupdf.open("bert.pdf") text = pages[0].get_text() print(text) 

打印的结果如下:

BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding Jacob Devlin Ming-Wei Chang Kenton Lee Kristina Toutanova Google AI Language {jacobdevlin,mingweichang,kentonl,kristout}@google.com Abstract We introduce a new language representa- tion ...... (5.1 point absolute improvement). 1 Introduction Language model pre-training has been shown to ...... De Meulder, 2003; Rajpurkar et al., 2016). There are two existing strategies for apply- ing ...... predict the original vocabulary id of the masked arXiv:1810.04805v2 [cs.CL] 24 May 2019 

提取出的文字遵循了原 PDF 文件的阅读顺序,也就是先读左边栏的文字,再读右边栏的文字,(为了节省版面,对部分文字进行了省略),这样提取出的文本也就保持了原 PDF 的语义。

除了上面的这种提取方式之外,我们还可以将文本提取为文本块的列表。代码如下:

import pymupdf pages = pymupdf.open("bert.pdf") text = pages[0].get_text("blocks") print(text) 

打印的结果如下:

[(116.281, 67.594, 481.025, 102.61, 'BERT: Pre-training of Deep Bidirectional Transformers for\nLanguage Understanding\n', 0, 0), (107.562, 128.5, 492.69, 179.25, 'Jacob Devlin\nMing-Wei Chang\nKenton Lee\nKristina Toutanova\nGoogle AI Language\n{jacobdevlin,mingweichang,kentonl,kristout}@google.com\n', 1, 0), (158.938, 222.025, 203.312, 237.625, 'Abstract\n', 2, 0), ...... , (10.7617, 256.25, 37.4766, 609.75, 'arXiv:1810.04805v2 [cs.CL] 24 May 2019\n', 8, 0)] 

由上面的结果可以看出,每个文本块包含了文本块的坐标、文本块的内容以及文本块的序号(为了节省版面,对部分文本块进行了省略)。有了每个文本块的上述信息,我们便可以知道文本块的阅读顺序;如果需要的话,还可以使用每个文本块的坐标信息对版面进行恢复。

表格的提取

表格提取效果比较好的库有 camelot 和 tabula ,表格又可以分为有线表和少线表。下面就分别以有线表和少线表为例来介绍 camelot 和 tabula 的使用。

有线表

我们以下面的 PDF 为例来看使用 camelot 和 tabula 进行有线表格提取的效果。

RAG 系列之二:PDF 文件的解析

  1. 使用 camelot 进行表格提取的代码如下:
import camelot tables = camelot.read_pdf('data.pdf') print(tables[0].df) 

输出结果如下:

RAG 系列之二:PDF 文件的解析

  1. 使用 tabula 进行表格提取的代码如下:
import tabula dfs = tabula.read_pdf("data.pdf") print(dfs[0]) 

输出结果如下:

RAG 系列之二:PDF 文件的解析

从结果可以看出,在提取有线表时,不管是 camelot 还是 tabula 都能很好地进行提取,而且不需要过多的参数设置。

少线表

我们以下面的 PDF 为例来看使用 camelot 和 tabula 进行少线表格提取的效果。

RAG 系列之二:PDF 文件的解析

  1. 使用 camelot 进行少线表格提取的代码如下:
import camelot tables = camelot.read_pdf('bert-6.pdf', flavor='stream') tables[0].df 

在使用 camelot 进行少线表格的提取时,需要将参数 flavor 设置成 stream ,输出结果如下:

RAG 系列之二:PDF 文件的解析

  1. 使用 tabula 进行少线表格提取的代码如下:
import tabula dfs = tabula.read_pdf("bert-6.pdf", stream=True) dfs[0] 

在使用 tabula 进行少线表格的提取时,需要将参数 stream 设置成 True ,输出结果如下:

RAG 系列之二:PDF 文件的解析

在使用 camelot 和 tabula 进行少线表格的提取时,需要设置相应的参数。

扫描 PDF 的解析

文本的提取

在从扫描的 PDF 文件中提取文本时,使用开源的 PaddleOCR,并且用 PPStructure 做版面的分析。我们还是以下面的 PDF 文件为例,不过这是的 PDF 文件是扫描 PDF。

RAG 系列之二:PDF 文件的解析

提取文本的代码如下:

import os import cv2 from paddleocr import PPStructure, draw_structure_result, save_structure_res from PIL import Image img_path = "./bert-1.png" table_engine = PPStructure(show_log=True) save_folder = './output' img = cv2.imread(img_path) result = table_engine(img) save_structure_res(result, save_folder, os.path.basename(img_path).split('.')[0]) font_path = './fonts/simfang.ttf' image = Image.open(img_path).convert('RGB') im_show = draw_structure_result(image, result, font_path=font_path) im_show = Image.fromarray(im_show) im_show.save('result.jpg') 

得到的结果如下:

RAG 系列之二:PDF 文件的解析

图中的左边是根据给出的版面分析结果画出来的,可以看出对双栏 PDF 做了正确的解析。右边是根据识别出来的文本以及文本的坐标画出来的,可以看出基本上和左边的版面以及内容是一致的。

表格的提取

我们还是以下面的 PDF 文件为例,不过这是的 PDF 文件是扫描 PDF。

RAG 系列之二:PDF 文件的解析

代码如下:

import os import cv2 from paddleocr import PPStructure,draw_structure_result,save_structure_res from PIL import Image table_engine = PPStructure(show_log=True) save_folder = './output' img_path = './bert-6.png' img = cv2.imread(img_path) result = table_engine(img) save_structure_res(result, save_folder,os.path.basename(img_path).split('.')[0]) for line in result: line.pop('img') print(line) 

在上面的输出结果中,有一行类型为 table 的输出,我们将这一行中 html 标签下的内容拷贝出来,放到一个 html 文件中,得到如下的表格:

RAG 系列之二:PDF 文件的解析

可以看出在表头这一块还是有一些差异,但是其他的信息基本都是正确的,应该说效果还是不错的。

总结

本文重要介绍了文本 PDF 和 扫描 PDF 的解析,了解到了 PDF 文件解析的复杂性。要想 RAG(检索增强生成)后面的环节取得比较好的效果,文件解析的准确性至关重要。如果在文件解析这一环节质量不高的话,后面的环节不论怎么优化,也不会达到很好的效果。所以花大力气在文件的解析上,后面会收到事半功倍的效果。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/89703.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信