Datasets documentation

Caractéristiques du jeu de données

Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Caractéristiques du jeu de données

Features définit la structure interne d’un jeu de données. Il est utilisé pour spécifier le format de sérialisation sous-jacent. Ce qui vous intéressera davantage, c’est que Features contient des informations de haut niveau, allant des noms et types de colonnes au ClassLabel. Vous pouvez considérer Features comme l’ossature d’un jeu de données.

Le format Features est simple : dict[column_name, column_type]. Il s’agit d’un dictionnaire de paires nom de colonne et type de colonne. Le type de colonne offre un large éventail d’options pour décrire le type de données dont vous disposez.

Examinons les caractéristiques du jeu de données MRPC issu du benchmark GLUE :

>>> 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'),
}

La fonctionnalité Value indique à 🤗 Datasets :

  • Le type de données idx est int32.
  • Les types de données sentence1 et sentence2 sont string.

🤗 Datasets prend en charge de nombreux autres types de données, tels que bool, float32 et binary, pour n’en citer que quelques-uns.

Reportez-vous à Value pour la liste complète des types de données pris en charge.

La fonctionnalité ClassLabel indique à 🤗 Datasets que la colonne label contient deux classes. Les classes sont étiquetées not_equivalent et equivalent. Les étiquettes sont stockées sous forme d’entiers dans le jeu de données. Lors de la récupération des étiquettes, ClassLabel.int2str() et ClassLabel.str2int() effectuent la conversion de la valeur entière vers le nom de l’étiquette, et inversement.

Si votre type de données contient une liste d'objets, vous devez utiliser la fonctionnalité List. Vous vous souvenez du jeu de données 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'))}}

Le champ answers est construit à l'aide du dictionnaire de caractéristiques car il contient deux sous-champs, text et answer_start, qui sont respectivement des listes de string et de int32.

Consultez la section flatten pour découvrir comment extraire les sous-champs imbriqués en tant que colonnes indépendantes.

Le type de fonctionnalité tableau est utile pour créer des tableaux de différentes tailles. Vous pouvez créer des tableaux à deux dimensions à l'aide de Array2D, et même des tableaux à cinq dimensions à l'aide de Array5D.

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

Le type de tableau permet également de rendre la première dimension du tableau dynamique. Cela est utile pour traiter des séquences de longueurs variables, telles que des phrases, sans avoir à compléter ou tronquer l'entrée pour obtenir une forme uniforme.

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

Caractéristique audio

Les jeux de données audio possèdent une colonne de type Audio, qui contient trois champs importants :

  • array : les données audio décodées, représentées sous forme de tableau unidimensionnel.
  • path : le chemin vers le fichier audio téléchargé.
  • sampling_rate : le taux d'échantillonnage des données audio.

Lorsque vous chargez un jeu de données audio et que vous appelez la colonne audio, la fonctionnalité Audio décode et rééchantillonne automatiquement le fichier 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>

Accédez à un jeu de données audio en utilisant d'abord l'index de la ligne, puis la colonne audio - dataset[0]["audio"] - afin d'éviter de décoder et de rééchantillonner tous les fichiers audio du jeu de données. Sinon, cela peut être un processus lent et chronophage si vous disposez d'un jeu de données volumineux.

Avec decode=False, le type Audio vous fournit simplement le chemin ou les octets du fichier audio, sans le décoder en un objet 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'}

Fonctionnalité d'image

Les jeux de données d'images possèdent une colonne de type Image, qui charge des objets PIL.Image à partir d'images stockées sous forme d'octets :

Lorsque vous chargez un jeu de données d'images et appelez la colonne d'images, la fonctionnalité Image décode automatiquement le fichier 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>

Accédez à un jeu de données d’images en utilisant d’abord l’index de la ligne, puis la colonne image - dataset[0]["image"] - afin d’éviter de décoder tous les fichiers d’images du jeu de données. Sinon, cela peut être un processus lent et chronophage si vous disposez d’un jeu de données volumineux.

Avec decode=False, le type Image vous fournit simplement le chemin ou les octets du fichier image, sans le décoder en 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'}

Selon le jeu de données, vous obtiendrez soit le chemin de l'image téléchargée localement, soit le contenu de l'image sous forme d'octets si le jeu de données n'est pas constitué de fichiers individuels.

Vous pouvez également définir un jeu de données d'images à partir de tableaux numpy :

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

Et dans ce cas, les tableaux numpy sont encodés en PNG (ou en TIFF si la précision des valeurs des pixels est importante).

Pour les tableaux multi-canaux comme RGB ou RGBA, seul uint8 est pris en charge. Si vous utilisez une précision plus élevée, un avertissement est affiché et le tableau est converti en uint8. Pour les images en niveaux de gris, vous pouvez utiliser la précision entière ou flottante de votre choix, à condition qu'elle soit compatible avec Pillow. Un avertissement est affiché si la précision entière ou flottante de votre image est trop élevée, et dans ce cas le tableau est converti vers une précision inférieure : un tableau int64 est converti en int32, et un tableau float64 est converti en float32.

Fonctionnalité Mesh

Les jeux de données maillés possèdent une colonne de type Mesh, qui charge les fichiers de maillage 3D en tant qu'objets trimesh.

Lorsque vous chargez un jeu de données de maillage et appelez la colonne de maillage, la fonctionnalité Mesh décode automatiquement le fichier de maillage :

>>> from datasets import load_dataset, Mesh

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

Selon le contenu du fichier, trimesh peut retourner un objet trimesh.Trimesh ou un objet trimesh.Scene.

Accédez à un jeu de données de maillage en utilisant d'abord l'index de ligne, puis la colonne mesh - dataset[0]["mesh"] - afin d'éviter de décoder tous les fichiers de maillage du jeu de données. Sinon, cela peut être un processus lent et chronophage si vous disposez d'un jeu de données volumineux.

Avec decode=False, le type Mesh vous fournit le chemin ou les octets du fichier de maillage sans le décoder avec 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'}

La fonctionnalité Mesh prend en charge les fichiers .glb, .gltf, .ply et .stl. Pour les octets intégrés, le path stocké est utilisé pour déduire le type de fichier de maillage.

Fonctionnalité Json

Les jeux de données sont basés sur Arrow, un format en colonnes, et s'attendent donc à ce que chaque exemple ait le même type et les mêmes sous-types, et que les dictionnaires aient les mêmes clés et les mêmes types de valeurs. Le chargement d'un jeu de données génère une erreur lorsque les types des champs ne correspondent pas, et remplit les champs manquants dans les dictionnaires avec None afin que tous les dictionnaires aient les mêmes clés et les mêmes types de valeurs.

Pour éviter cela et autoriser les types mixtes sans erreur, vous pouvez utiliser on_mixed_types="use_json" ou spécifier features= avec un type 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"}]

Ceci est également utile pour les listes de dictionnaires avec des clés et des valeurs arbitraires, afin d'éviter de remplir les champs manquants avec 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

Un autre exemple avec des données d’appel d’outils et l’argument on_mixed_types="use_json" (utile pour ne pas avoir à spécifier features= manuellement) :

>>> 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