为了账号安全,请及时绑定邮箱和手机立即绑定

RAG文档解析器的选择与应用指南

如何为您的 RAG 应用程序挑选合适的文档解析器?

选择合适文本解析的指南——斯克anda维克

尽管RAG在最近几个月里变得越来越流行,但文档处理这个关键领域却较少被人重视。归根结底,你可以使用各种专门的检索和生成方法——但返回的结果质量完全取决于文档本身的质量。如果文档出现了信息缺失或格式错误等问题,那么进一步优化检索策略、嵌入模型等方法都无法解决问题。

在这篇文章中,我们将看看三种越来越受欢迎的文档提取方法。在这个教程中,我们将演示从亚马逊2024年第一季度财报中解析一个表格内容。

亚马逊2024年第一季度财务报告的第11页 https://s2.q4cdn.com/299287126/files/doc_financials/2024/q1/AMZN-Q1-2024-Earnings-Release.pdf

文本解析

文本解析工具已经存在了一段时间。这些工具可以读取文档,并从文件中提取文本内容。比如,PyPDF、PyMuPDF和PDFMiner。我们来看看PyMuPDF,并利用PyMuPDF的LlamaIndex功能来解析上面提到的页面。下面是代码:

[代码段保持不变]
from llama_index.core.schema import TextNode  # 文本节点定义
from llama_index.core.node_parser import SentenceSplitter  # 句子分割器定义
import fitz  # 导入fitz库,用于处理PDF文件

file_path = "/content/AMZN-Q1-2024-Earnings-Release.pdf"  # 文件路径
doc = fitz.open(file_path)  # 打开PDF文件
text_parser = SentenceSplitter(  # 初始化句子分割器
    chunk_size=2048,  # 指定分割段落的大小
)
text_chunks = []  # C  # 用于存储分割后的文本块

for doc_idx, page in enumerate(doc):  # 遍历每一页
    page_text = page.get_text("text")  # 获取页面文本
    cur_text_chunks = text_parser.split_text(page_text)  # 分割文本
    text_chunks.extend(cur_text_chunks)  # 将分割后的文本添加到列表中

nodes = []  # D  # 用于存储节点
for idx, text_chunk in enumerate(text_chunks):  # 遍历每个文本块
    node = TextNode(  # 创建文本节点
        text=text_chunk,  # 设置节点文本内容
    )
    nodes.append(node)  # 添加到节点列表

print(nodes[10].text)  # 打印第10个节点的文本内容

PyMUPDF成功提取了所有文本(如下所示)。然而,它的格式并不规范。在生成时,如果LLM无法识别文档结构,这可能成为一个潜在的问题。

AMAZON.COM, INC.  
合并全面收益表  
(单位:百万美元)(未经审计)  

截至2023年3月31日  
2024年3月31日  
净利润  
$3,172 $10,431  
其他综合收益(亏损):  
外币折算差额,扣除所得税(10)和(30)百万美元  
386  
(1,096)  
可供出售债务证券净未实现收益变动:  
净未实现收益(亏损)变化,扣除所得税(29)和(158)百万美元  
95  
536  
减:重新分类调整,计入“其他收入(亏损)净额”,扣除所得税(10)和0  
33  
1  
净变化  
128  
537  
其他,扣除所得税0和(1)百万  
—  
1  
合计其他综合收益  
514  
(558)  
合计全面收益  
$3,686 $9,873

接下来,我们来看看OCR的表现。

文档解析中的OCR
    从 PIL 导入 Image  
    导入 pytesseract  
    导入 sys  
    从 pdf2image 导入 convert_from_path  
    导入 os  
    pages = convert_from_path(file_path)  
    i=10  
    filename = "page"+str(i)+".jpg"  
    pages[i].save(filename, 'JPEG')  
    outfile =  "page"+str(i)+"_text.txt"  
    f = open(outfile, "a")  
    text= str(((pytesseract.image_to_string(Image.open(filename)))))  
    text = text.replace('-\n', '')      
    f.write(text)  
    f.close()  

    打印(text)
    # 从 PDF 文件中提取每一页并保存为 JPEG 格式的图片
    # 使用 pytesseract 将图片转换为文本,并保存到文件中
    # 最后打印文本内容

    from PIL import Image  
    import pytesseract  
    import sys  
    from pdf2image import convert_from_path  
    import os  

    # 将 PDF 文件转换为图片列表
    pages = convert_from_path(file_path)  

    # 设置页码
    i=10  

    # 设置文件名
    filename = "page"+str(i)+".jpg"  

    # 保存页面为 JPEG 文件
    pages[i].save(filename, 'JPEG')  

    # 设置输出文本文件名
    outfile =  "page"+str(i)+"_text.txt"  

    # 打开输出文件并写入内容
    f = open(outfile, "a")  
    text = str(((pytesseract.image_to_string(Image.open(filename)))))  
    text = text.replace('-\n', '')      
    f.write(text)  
    f.close()  

    # 打印文本内容
    print(text)

如下所示的OCR技术更好地识别了文档的文字和结构。

    AMAZON.COM, INC.  
    合并收益表  
    (单位:百万)  

    (未经审计)  
    截至  
    2023年3月31日 2024年3月31日  
    净收入 $ 3,172 §$ 10,431  
    其他综合收益(损失):  
    外币翻译调整,扣除所得税 $(10) 和 $30 386 (1,096)  
    可供出售的债务证券:  
    净未实现收益(损失)变动,扣除所得税 $(29) 和 $(158) 95 536  
    减:重新分类调整损失(收益),计入“其他收入(费用)净额”,扣除所得税 $(10) 和 $0 33 1  
    净变化 128 231  
    其他,扣除所得税 $0 和 $(1) _— 1  
    总其他综合收益(损失) 514 (558)  

    综合收益总额 $ 3,686 $ 9,873

最后,让我们来了解一下智能文档解析技术吧。

智能文档分析(IDP)

智能文档解析是一项相对较新的技术,旨在解决从所有文档中提取结构化格式的信息的问题。有许多智能文档解析(IDP)工具,例如LlamaParse、DocSumo、Unstructured.io、Azure文档智能服务等。

底层结合了 OCR、文本提取、多模态大语言模型和 Markdown 转换等功能来提取文本内容。让我们来瞧瞧 LlamaIndex 发布的 LlamaParse 吧。为此,您首先需要注册一个 LlamaParse API 密钥,以通过 API 解析文档。

    import getpass  
    import os  
    from copy import deepcopy  

    os.environ["LLAMA_CLOUD_API_KEY"] = getpass.getpass()  
    from llama_parse import LlamaParse  
    import nest_asyncio  
    nest_asyncio.apply()  
    documents = LlamaParse(result_type="markdown").load_data(file_path)  
    def get_page_nodes(docs, separator="\n---\n"):  
        """按分隔符将每个文档拆分为页面节点。"""  
        nodes = []  
        for doc in docs:  
            doc_chunks = doc.text.split(separator)  
            for doc_chunk in doc_chunks:  
                node = TextNode(  
                    text=doc_chunk,  
                    metadata=deepcopy(doc.metadata),  
                )  
                nodes.append(node)  

        return nodes  

    nodes_lp = get_page_nodes(documents)  
    print(nodes_lp[10].text)

以下格式如下采用Markdown格式,似乎是目前最佳的结构表示方式。

    # Amazon公司

    # 合并收益表

    | |截至2023年3月31日的三个月期间|截至2024年3月31日的三个月期间|
    |---|---|---|
    |净利润|$3,172元|$10,431元|
    |其他综合收益(损失):| | |
    |外币折算调整,扣除税后 $(10) 和 $(30)|386元|(1,096)元|
    |可供出售的债务证券:| | |
    |未实现损益变化,扣除税后 $(29) 和 $(158)|95元|536元|
    |扣除税后 $(10) 和 $0,再分类调整计入‘其他收入(费用)净额’|33元|1元|
    |净变化|128元|537元|
    |其他,扣除税后 $0 和 $(1)|—|1元|
    |总其他综合收益(损失)|514元|(558)元|
    |综合收益总额|$3,686元|$9,873元|

不过,上述内容缺少了一些重要的上下文信息。需要注意的是,解析后的文档中不再提及“数百万”——这使得大模型生成器LLM更可能凭空编造内容。

收获

为了让你的RAG应用得到优化,你必须精心选择合适的文档解析器。如你所见,每种解析策略都有其独特的优缺点。

  1. 文本解析器: 当你使用像 PyPDF 或 PyMUPDF 这样的工具时,你会高效地提取文本。然而,你可能会丢失文档的结构,这可能会在生成时混淆你的大型语言模型(LLM)。
  2. OCR: 如果你选择使用像 Pytesseract 这样的 OCR 工具,你将更有效地捕获文本和结构。这种方法比基本的文本解析器更好地保留了原始格式和上下文。不过请注意,OCR 通常伴随着较高的延迟,其有效性可能高度依赖于你的具体用例。你需要评估提高的准确性是否值得为你的应用增加处理时间。
  3. 智能文档解析(IDP): 通过选择像 LlamaParse 这样的高级 IDP 方法,你将结合 OCR、文本提取以及多模态大语言模型。这种方法使你能够将文档转换为结构良好的 Markdown 格式。然而,请注意你可能会偶尔丢失关键的上下文,比如度量单位。另外,请记住 IDP 是一项较不成熟的科技,目前面临可扩展性和高延迟问题。在实施 IDP 时,你需要仔细考虑这些限制并为系统中潜在的瓶颈做好准备。

最终,你的选择取决于具体的应用场景。最确切的方法是用不同的解析器评估你的应用程序,选择能满足所有需求的那个。你甚至可能会发现,将不同的方法组合起来最适合你的具体需求。继续实验并不断优化你的方法,以达到你RAG应用的最佳效果。

参阅 GitHub 指南以获取详细说明:

GitHub - skandavivek/RAG-Doc-Parsers: 该仓库展示了不同的文档解析策略用于检索增强生成(RAG)的应用中。github.com

要是你喜欢这篇帖子,就关注EMAlpha——我们在这里探讨和挖掘人工智能、金融和数据的交汇点。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消