5个不稳定发布版
0.8.4 | 2024年7月15日 |
---|---|
0.8.1 | 2024年5月26日 |
0.8.0 | 2024年5月26日 |
0.6.0 | 2024年3月15日 |
0.5.0 | 2024年2月22日 |
520 在 文本处理 中
183 每月下载量
240KB
5.5K SLoC
STAM Python绑定
STAM 是一个用于 stand-off 文本注释的数据模型,详细信息请参阅 此处。这是一个Python库(更具体地说,是一个用Rust编写的Python绑定),用于与该模型交互。
您可以用这个库做什么?
- 保留、构建和操作高效的内存中文本和文本注释存储
- 在注释、数据和文本中进行搜索
- 通过数据、文本内容、文本片段之间的关系(重叠、嵌入、相邻等)搜索注释
- 在文本中搜索(包括通过正则表达式)并找到针对找到的文本选择的注释
- 在数据(集合、键、值)中搜索并找到使用该数据的注释
- 进行有关文本偏移的基本文本操作(在分隔符上拆分文本、删除文本等)
- 在不同类型的偏移之间进行转换(绝对偏移、相对于其他结构的相对偏移、UTF-8字节与Unicode代码点等)
- 从STAM JSON、STAM CSV或优化的二进制(CBOR)表示形式读取和写入资源及注释
- 底层 STAM 模型 致力于清晰和简单。它灵活,不对任何词汇表或除 stand-off 注释之外的注释范例做出承诺。
此STAM库旨在作为构建进一步应用程序的基础,这些应用程序处理文本上的 stand-off 注释。我们实现了所有处理这些的低级逻辑,这样您就不再需要这样做,可以专注于您的实际应用程序。
安装
$pip install stam
或者,如果您喜欢冒险并且已经安装了必要的构建时依赖项(Rust),您可以从GitHub尝试最新的开发版本
$pip install git+https://github.com/annotation/stam-python
文档
- STAM规范 - STAM规范本身
- API参考
- STAM教程:面向Python程序员的离线文本标注 - 一份全面的教程,展示了如何使用这个Python库,以Jupyter Notebook的形式。 推荐!
用法
导入库
import stam
加载包含标注存储的STAM JSON(或CSV)文件
store = stam.AnnotationStore(file="example.stam.json")
标注存储是你的工作空间,它包含所有资源、标注集(即键和标注数据)以及当然实际的标注。它是一个基于内存的存储,你可以放入尽可能多的内容(只要它适合内存)。
在加载存储时,你可以选择性地传递配置参数,如下所示
store = stam.AnnotationStore(file="example.stam.json", config={"debug": True})
加载后,你可以通过公共ID检索任何内容
annotation = store.annotation("my-annotation")
resource = store.resource("my-resource")
dataset = store.dataset("my-annotationset")
key = dataset.key("my-key")
data = dataset.annotationdata("my-data")
你还可以遍历存储中的所有标注,并以简单的制表符分隔格式输出
for annotation in store.annotations():
# get the text to which this annotation refers (if any)
try:
text = str(annotation)
except stam.StamError:
text = "n/a"
for data in annotation:
print("\t".join(( annotation.id(), data.key().id(), str(data.value()), text)))
添加资源
resource = store.add_resource(filename="my-text.txt")
从头创建存储和标注
from stam import AnnotationStore, Selector, AnnotationDataBuilder
store = AnnotationStore(id="test")
resource = store.add_resource(id="testres", text="Hello world")
store.annotate(id="A1",
target=Selector.textselector(resource, Offset.simple(6,11)),
data={ "id": "D1", "key": "pos", "value": "noun", "set": "testdataset"})
在上面的例子中,AnnotationDataSet
,DataKey
和AnnotationData
都是即时创建的。你也可以在集合中显式地先创建它们,如下面的代码片段所示,从而得到完全相同的存储
store = AnnotationStore(id="test")
resource = store.add_resource(id="testres", text="Hello world")
dataset = store.add_dataset(id="testdataset")
dataset.add_key("pos")
data = dataset.add_data("pos","noun","D1")
store.annotate(id="A1",
target=Selector.textselector(resource, Offset.simple(6,11)),
data=data)
提供完整的数据字典,如早期示例所示,也会正常工作,得到相同的结果,但性能可能不如直接传递AnnotationData
实例。实现将始终确保尽可能重用任何已存在的AnnotationData
,因为不重复数据是STAM模型的核心特性之一。
你可以将整个标注存储(包括所有集合和标注)序列化为STAM JSON文件
store.set_filename("example.stam.json")
store.save()
有关更多信息,请参阅:STAM教程:面向Python程序员的离线文本标注。
Rust库和Python库之间的差异以及性能考虑
虽然这个Python绑定建立在Rust库的基础上,但它在某些方面公开的API与Rust库有所不同,使其更具Python风格,更容易使用。这导致了一个更高层次的API,它隐藏了一些在Rust库中存在的底层细节。这种方法的代价是造成一些额外的运行时开销。
Rust方法通常会在可能的情况下返回迭代器、引用或句柄,而且会安全地这样做。Python API通常被迫制作本地副本。对于我们通常决定让整个底层的Rust迭代器运行到底,然后将结果作为一个整体作为一个元组返回,而不是返回Python生成器。在这里,你通过牺牲一些内存来获得一些速度。
可能无需多言,但直接使用Rust始终比使用此Python绑定更高效。然而,使用此Python绑定应该仍然比完全用原生Python实现整个系统要高效得多。诀窍在于尽可能让绑定为你工作,在可能的情况下使用高级方法,而不是在Python中实现你的逻辑。
致谢
这项工作是在KNAW人文集群的数字基础设施部门进行的,并由CLARIAH项目(CLARIAH-PLUS,NWO资助项目184.034.023)作为FAIR标注轨道的一部分资助。
依赖关系
~15–26MB
~402K SLoC