Datasets documentation
数据集特性
数据集特性
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"}