Datasets documentation

数据集特性

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

数据集特性

Features 定义了数据集的内部结构,用于指定底层的序列化格式。但更值得关注的是,Features 包含了从列名和类型到 ClassLabel 的高层信息。你可以将 Features 视为数据集的骨架。

Features 格式很简单:dict[column_name, column_type]。它是一个由列名和列类型组成的字典。列类型提供了丰富的选项,用于描述您拥有的数据类型。

让我们来看看 GLUE 基准测试中 MRPC 数据集的特性:

>>> from datasets import load_dataset
>>> dataset = load_dataset('nyu-mll/glue', 'mrpc', split='train')
>>> dataset.features
{'idx': Value('int32'),
 'label': ClassLabel(names=['not_equivalent', 'equivalent']),
 'sentence1': Value('string'),
 'sentence2': Value('string'),
}

Value 功能会告诉 🤗 Datasets:

  • idx 的数据类型为 int32。
  • sentence1 和 sentence2 的数据类型为 string。

🤗 Datasets 还支持许多其他数据类型,例如 bool、float32 和 binary,仅举几例。

有关支持的数据类型的完整列表,请参阅 Value。

ClassLabel 功能告知 🤗 Datasets,label 列包含两个类别。这两个类别分别标记为 not_equivalent 和 equivalent。标签在数据集中以整数形式存储。当你获取标签时,ClassLabel.int2str() 和 ClassLabel.str2int() 负责执行整数值与标签名称之间的相互转换。

如果您的数据类型包含对象列表,那么您需要使用 List 功能。还记得 SQuAD 数据集吗?

>>> from datasets import load_dataset
>>> dataset = load_dataset('rajpurkar/squad', split='train')
>>> dataset.features
{'id': Value('string'),
 'title': Value('string'),
 'context': Value('string'),
 'question': Value('string'),
 'answers': {'text': List(Value('string')),
  'answer_start': List(Value('int32'))}}

answers 字段使用特征字典构建,因为它包含两个子字段 text 和 answer_start,它们分别是 string 和 int32 类型的列表。

请参阅 flatten 部分,了解如何将嵌套的子字段提取为独立的列。

数组特征类型适用于创建各种大小的数组。您可以使用 Array2D 创建二维数组,甚至可以使用 Array5D 创建五维数组。

>>> features = Features({'a': Array2D(shape=(1, 3), dtype='int32')})

数组类型还允许数组的第一维是动态的。这在处理变长序列(如句子)时非常有用,因为无需将输入填充或截断为统一的形状。

>>> features = Features({'a': Array3D(shape=(None, 5, 2), dtype='int32')})

音频特征

音频数据集包含一个类型为 Audio 的列,其中包含三个重要字段:

  • array:表示为一维数组的解码音频数据。
  • path:下载的音频文件的路径。
  • sampling_rate:音频数据的采样率。

加载音频数据集并调用音频列时,Audio 特征会自动解码并重采样音频文件:

>>> from datasets import load_dataset, Audio

>>> dataset = load_dataset("PolyAI/minds14", "en-US", split="train")
>>> dataset[0]["audio"]
<datasets.features._torchcodec.AudioDecoder object at 0x11642b6a0>

首先使用行索引,然后使用 audio 列来索引音频数据集 - dataset[0]["audio"] - 以避免解码和重采样数据集中的所有音频文件。否则,如果数据集较大,这可能是一个缓慢且耗时的过程。

使用 decode=False 时,Audio 类型仅返回音频文件的路径或字节数据,而不会将其解码为 torchcodec 的 AudioDecoder 对象,

>>> dataset = load_dataset("PolyAI/minds14", "en-US", split="train").cast_column("audio", Audio(decode=False))
>>> dataset[0]
{'audio': {'bytes': None,
  'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~JOINT_ACCOUNT/602ba55abb1e6d0fbce92065.wav'},
 'english_transcription': 'I would like to set up a joint account with my partner',
 'intent_class': 11,
 'lang_id': 4,
 'path': '/root/.cache/huggingface/datasets/downloads/extracted/f14948e0e84be638dd7943ac36518a4cf3324e8b7aa331c5ab11541518e9368c/en-US~JOINT_ACCOUNT/602ba55abb1e6d0fbce92065.wav',
 'transcription': 'I would like to set up a joint account with my partner'}

图像特征

图像数据集包含一个类型为 Image 的列,该列从以字节形式存储的图像中加载 PIL.Image 对象:

加载图像数据集并调用图像列时,Image 特征会自动解码图像文件:

>>> from datasets import load_dataset, Image

>>> dataset = load_dataset("AI-Lab-Makerere/beans", split="train")
>>> dataset[0]["image"]
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=500x500 at 0x125506CF8>

使用行索引先对图像数据集进行索引,然后再访问 image 列 - dataset[0]["image"] - 以避免解码数据集中的所有图像文件。否则,如果数据集较大,这可能是一个缓慢且耗时的过程。

使用 decode=False 时,Image 类型仅返回图像文件的路径或字节数据,而不会将其解码为 PIL.Image,

>>> dataset = load_dataset("AI-Lab-Makerere/beans", split="train").cast_column("image", Image(decode=False))
>>> dataset[0]["image"]
{'bytes': None,
 'path': '/Users/username/.cache/huggingface/datasets/downloads/extracted/772e7c1fba622cff102b85dd74bcce46e8168634df4eaade7bedd3b8d91d3cd7/train/healthy/healthy_train.265.jpg'}

根据数据集的不同,您可能会获取到本地下载图像的路径,或者如果数据集不是由单个文件组成的,则获取图像内容的字节数据。

您也可以从 numpy 数组定义一个图像数据集:

>>> ds = Dataset.from_dict({"i": [np.zeros(shape=(16, 16, 3), dtype=np.uint8)]}, features=Features({"i": Image()}))

在这种情况下,numpy 数组会被编码为 PNG(如果像素值的精度很重要,则编码为 TIFF)。

对于 RGB 或 RGBA 等多通道数组,仅支持 uint8。如果使用更高的精度,系统会发出警告,并将数组向下转换为 uint8。 对于灰度图像,只要精度与 Pillow 兼容,您可以使用所需的整数或浮点精度。如果图像的整数或浮点精度过高,系统会显示警告,此时数组会被向下转换:int64 数组会被向下转换为 int32,float64 数组会被向下转换为 float32。

Mesh 功能

Mesh 数据集包含一个类型为 Mesh 的列,该列将 3D 网格文件加载为 trimesh 对象。

加载网格数据集并调用网格列时,Mesh 特征会自动解码网格文件:

>>> from datasets import load_dataset, Mesh

>>> dataset = load_dataset("VINAY-UMRETHE/My-Mesh-Dataset", split="train")
>>> dataset[0]["mesh"]
<trimesh.Scene(len(geometry)=33)>

根据文件内容,trimesh 可能返回一个 trimesh.Trimesh 对象或一个 trimesh.Scene 对象。

使用行索引先索引到网格数据集,然后索引到 mesh 列 - dataset[0]["mesh"] - 以避免解码数据集中的所有网格文件。否则,如果数据集较大,这可能是一个缓慢且耗时的过程。

使用 decode=False 时,Mesh 类型会返回网格文件的路径或字节内容,而不会使用 trimesh 对其进行解码:

>>> dataset = load_dataset("VINAY-UMRETHE/My-Mesh-Dataset", split="train").cast_column("mesh", Mesh(decode=False))
>>> dataset[0]["mesh"]
{'bytes': b'...',
 'path': '00001.glb'}

Mesh 功能支持 .glb、.gltf、.ply 和 .stl 文件。对于嵌入的字节,将使用存储的 path 来推断网格文件类型。

Json 功能

数据集基于 Arrow 构建,这是一种列式格式,因此要求每个示例具有相同的类型和子类型,并且字典具有相同的键和值类型。 加载数据集时,如果字段类型不匹配,则会抛出错误;对于字典中缺失的字段,会用 None 填充,以确保所有字典具有相同的键和值类型。

为避免此问题并允许混合类型而不报错,您可以使用 on_mixed_types="use_json" 或指定 features= 并使用 Json 类型:

>>> ds = Dataset.from_dict({"a": [0, "foo", {"subfield": "bar"}]})
Traceback (most recent call last):
  ...
  File "pyarrow/error.pxi", line 92, in pyarrow.lib.check_status
pyarrow.lib.ArrowInvalid: Could not convert 'foo' with type str: tried to convert to int64

>>> features = Features({"a": Json()})
>>> ds = Dataset.from_dict({"a": [0, "foo", {"subfield": "bar"}]}, features=features)
>>> ds.features
{'a': Json()}
>>> list(ds["a"])
[0, "foo", {"subfield": "bar"}]

对于具有任意键和值的字典列表,这也很有用,可以避免用 None 填充缺失的字段:

>>> ds = Dataset.from_dict({"a": [[{"b": 0}, {"c": 0}]]})
>>> ds.features
{'a': List({'b': Value('int64'), 'c': Value('int64')})}
>>> list(ds["a"])
[[{'b': 0, 'c': None}, {'b': None, 'c': 0}]]  # missing fields are filled with None

>>> features = Features({"a": List(Json())})
>>> ds = Dataset.from_dict({"a": [[{"b": 0}, {"c": 0}]]}, features=features)
>>> ds.features
{'a': List(Json())}
>>> list(ds["a"])
[[{'b': 0}, {'c': 0}]]  # OK

另一个使用工具调用数据以及 on_mixed_types="use_json" 参数的示例(无需手动指定 features=,非常有用):

>>> messages = [
...     {"role": "user", "content": "Turn on the living room lights and play my electronic music playlist."},
...     {"role": "assistant", "tool_calls": [
...         {"type": "function", "function": {
...             "name": "control_light",
...             "arguments": {"room": "living room", "state": "on"}
...         }},
...         {"type": "function", "function": {
...             "name": "play_music",
...             "arguments": {"playlist": "electronic"}  # mixed-type here since keys ["playlist"] and ["room", "state"] are different
...         }}]
...     },
...     {"role": "tool", "name": "control_light", "content": "The lights in the living room are now on."},
...     {"role": "tool", "name": "play_music", "content": "The music is now playing."},
...     {"role": "assistant", "content": "Done!"}
... ]
>>> ds = Dataset.from_dict({"messages": [messages]}, on_mixed_types="use_json")
>>> ds.features
{'messages': List({'role': Value('string'), 'content': Value('string'), 'tool_calls': List(Json()), 'name': Value('string')})}
>>> ds[0][1]["tool_calls"][0]["function"]["arguments"]
{"room": "living room", "state": "on"}
Update on GitHub