papermage
设置
conda create -n papermage python=3.11
conda activate papermage
如果您从源代码安装:
pip install -e '.[dev,predictors,visualizers]'
如果您从PyPi安装:
pip install 'papermage.[dev,predictors,visualizers]'
(根据您的命令行shell,可能需要添加或删除引号)。
如果您使用的是MacOSX,还需要运行:
conda install poppler
单元测试
python -m pytest
对于最近失败的测试
python -m pytest --lf --no-cov -n0
对于特定的测试名称或类名
python -m pytest -k 'TestPDFPlumberParser' --no-cov -n0
快速入门
1. 首次从PDF创建文档
from papermage.recipes import CoreRecipe
recipe = CoreRecipe()
doc = recipe.run("tests/fixtures/papermage.pdf")
2. 理解输出:Document
类
什么是Document
?最简单的情况下,它是保存在.symbols
层中的一些文本,就是一个<str>
。例如:
> doc.symbols
"PaperMage: A Unified Toolkit for Processing, Representing, and\nManipulating Visually-..."
但是当您有多种不同的方式来分割.symbols
时,这个库才真正发挥作用。例如,将论文分割成页面,然后将每个页面分割成行:
for page in doc.pages:
print(f'\n=== 页面: {page.id} ===\n\n')
for row in page.rows:
print(row.text)
...
=== 页面: 5 ===
4
案例:为科学论文构建一个属性QA系统
研究人员如何利用papermage进行研究?在这里,
我们将通过一个用户场景来说明,其中一位研究员
(Lucy)正在为科学领域原型设计一个属性QA系统。
系统设计。
借鉴Ko的灵感
...
这展示了这个库的两个优点:
-
Document
为symbols
的不同分割提供了可迭代对象。选项包括pages, tokens, rows, sentences, sections, ...
等。但并非每个解析器都会提供所有分割。 -
这些分割中的每一个(在我们的库中,我们称它们为
Entity
对象)都知道(并可以访问)其他分割类型。例如,您可以调用page.rows
来获取与特定页面相交的所有行。或者您可以调用sent.tokens
来获取与特定句子相交的所有标记。或者您可以调用sent.rows
来获取与特定句子相交的行。这些索引在创建Document
时以及每次添加新的Entity
类型时都会动态构建。极端情况下,只要这些层在Document中可用,您就可以这样写:
for page in doc.pages:
for sent in page.sentences:
for row in sent.rows:
...
您可以通过以下方式检查Document中可用的层:
> doc.layers
['tokens',
'rows',
'pages',
'words',
'sentences',
'blocks',
'vila_entities',
'titles',
'authors',
'abstracts',
'keywords',
'sections',
'lists',
'bibliographies',
'equations',
'algorithms',
'figures',
'tables',
'captions',
'headers',
'footers',
'footnotes',
'symbols',
'images',
'metadata',
'entities',
'relations']
3. 理解实体的交集
注意,Entity
不一定完全嵌套。例如,如果您运行:
for sent in doc.sentences:
for row in sent.rows:
print([token.text for token in row.tokens])
句子外的标记仍然可以被打印出来。这是因为当我们从句子跳到它的行时,我们在寻找与句子有任何重叠的所有行。行可以延伸到句子边界之外,因此可以包含句子外的标记。
使用这个库的一个关键方面是理解这些不同层是如何定义的,并预期它们可能如何相互作用。我们试图做出直观的决定,但我们确实要求用户通过实验来熟悉这些层。
4. Entity
中包含什么?
每个Entity
对象存储有关其内容和位置的信息:
-
.spans: List[Span]
,Span
是指向Document.symbols
的指针(即Span(start=0, end=5)
对应于symbols[0:5]
)。默认情况下,当您迭代Entity
时,您是在迭代它的.spans
。 -
.boxes: List[Box]
,Box
表示页面上的矩形区域。每个span都与一个Box相关联。 -
.metadata: Metadata
,一个自由格式的类字典对象,用于存储该Entity
的额外元数据。这些通常是空的。
5. 我如何手动创建自己的Document
?
Document
是通过将3种类型的工具:Parsers
、Rasterizers
和Predictors
组合在一起创建的。
-
Parsers
以PDF为输入,返回由.symbols
和其他层组成的Document
。我们使用的示例是PDFPlumber的包装器 - MIT许可的工具。 -
Rasterizers
以PDF为输入,返回每页的Image
,添加到Document.images
中。我们使用的示例是PDF2Image - MIT许可。 -
Predictors
接受Document
并应用一些操作来计算新的Entity
对象集,我们可以将其插入到我们的Document
中。这些都是内部构建的,可以是简单的启发式方法,也可以是完整的机器学习模型。
6. 我如何保存我的Document
?
import json
with open('filename.json', 'w') as f_out:
json.dump(doc.to_json(), f_out, indent=4)
将产生类似于:
{
"symbols": "PaperMage: A Unified Toolkit for Processing, Representing, an...",
"entities": {
"rows": [...],
"tokens": [...],
"words": [...],
"blocks": [...],
"sentences": [...]
},
"metadata": {...}
}
7. 我如何加载我的Document
?
这些可以用来重新构建Document
:
with open('filename.json') as f_in:
doc_dict = json.load(f_in)
doc = Document.from_json(doc_dict)
注意:向文档添加层的常见模式是加载先前保存的文档,对其运行一些额外的Predictors
,然后保存结果。
有关在您自己的数据上训练自定义预测器的更多信息,请参见papermage/predictors/README.md
。
有关更多使用模式的演示,请参见papermage/examples/quick_start_demo.ipynb
笔记本。