跳至内容

数据预处理

概述

Ludwig 数据预处理对输入数据集执行以下几种不同的操作:

  1. 计算元数据,例如词汇表、词汇大小和序列长度。这使得 Ludwig 能够创建像 idx2strstr2idx 这样的字典,用于将原始数据值映射到张量值。
  2. 处理缺失值:任何具有缺失特征值的行/示例都会被填充为常量或其他基于示例的值(参见类型全局预处理配置)。
  3. (可选)分割数据集为训练集、验证集和测试集,基于分割比例,或使用显式指定的分割方式。
  4. (可选)平衡数据,这对于类别严重不足或过多的数据集非常有用。

数据预处理将原始数据映射到两个文件:1)包含张量的已处理数据集文件(在本地运行时为 HDF5,在 Ray 上运行时为 Parquet)和 2)元数据 JSON 文件。已处理的数据集和元数据文件保存在缓存目录中(默认为输入数据集所在的同一目录),除非使用了 --skip_save_processed_input 选项。这两个文件将用作缓存,以避免在后续实验中再次执行相同的预处理,因为这可能会非常耗时。

可以通过 Ludwig 配置的类型全局预处理部分高度定制预处理过程。基本假设始终是所有数据都采用 UTF-8 编码,并且每行代表一个示例,每列代表一个特征。

为每个特征分配类型是很有帮助的。某些类型假定特定的格式,不同类型会将原始数据映射到张量的方式也不同。从 v0.5 版本开始,用户还可以选择依靠 Ludwig AutoML 自动分配类型。

不同数据类型的预处理

每种数据类型都以不同的方式进行预处理,使用不同的参数和不同的分词器。有关如何为每种特征类型和每个特定特征设置这些参数的详细信息,请参阅配置 - 默认设置 - 类型全局预处理部分。

二元特征

Binary 特征直接转换为长度为 n 的二元值向量(其中 n 是数据集的大小),并添加到已处理的数据集中,键为该特征在数据集中的列名。JSON 元数据文件中没有关于它们的附加信息。

数值特征

Number 特征直接转换为长度为 n 的浮点值向量(其中 n 是数据集的大小),并添加到已处理的数据集中,键为该特征在数据集中的列名。JSON 元数据文件中没有关于它们的附加信息。

类别特征

Category 特征转换为大小为 n 的整数值向量(其中 n 是数据集的大小),并添加到已处理的数据集中,键为该特征在数据集中的列名。

类别到整数的映射方式如下:首先收集数据集中该列中所有唯一的类别字符串的字典,然后按频率对其进行排序,然后从最频繁到最稀有的类别分配递增的整数 ID(其中 0 分配给 <UNK> 标记)。列名被添加到 JSON 文件中,并附带一个字典,其中包含:

  1. 整数到字符串的映射(idx2str
  2. 字符串到 ID 的映射(str2idx
  3. 字符串到频率的映射(str2freq
  4. 所有标记集合的大小(vocab_size
  5. 附加的预处理信息(默认为如何填充缺失值以及用于填充缺失值的标记)

集合特征

Set 特征转换为大小为 n x l 的二元(实际是 int8)值矩阵(其中 n 是数据集的大小,l 是最大集合大小和 max_size 参数中的较小值),并添加到已处理的数据集中,键为该特征在数据集中的列名。

集合到整数的映射方式如下:首先使用分词器将字符串映射到集合项序列(默认通过空格分隔)。然后收集数据集中该列中所有不同的集合项字符串的字典,然后按频率对其进行排序,并从最频繁到最稀有的项分配递增的整数 ID(其中 0 分配给用于填充的 <PAD>,1 分配给 <UNK> 项)。列名被添加到 JSON 文件中,并附带一个字典,其中包含:

  1. 整数到字符串的映射(idx2str
  2. 字符串到 ID 的映射(str2idx
  3. 字符串到频率的映射(str2freq
  4. 所有集合的最大大小(max_set_size
  5. 附加的预处理信息(默认为如何填充缺失值以及用于填充缺失值的标记)

词袋特征

Bag 特征的处理方式与集合特征相同,唯一的区别是矩阵的值为浮点数(频率)。

序列特征

序列特征默认由 space 分词器处理。它使用空格将特征值的内容分割成字符串列表。

分词前 分词后
"token3 token4 token2" [token3, token4, token2]
"token3 token1" [token3, token1]

计算元数据:创建了一个列表 idx2str 和两个字典 str2idxstr2freq,包含通过分割列的所有行获得的所有列表中的所有标记,并为每个标记分配一个整数 ID(按频率排序)。

{
    "column_name": {
        "idx2str": [
            "<PAD>",
            "<UNK>",
            "token3",
            "token2",
            "token4",
            "token1"
        ],
        "str2idx": {
            "<PAD>": 0,
            "<UNK>": 1,
            "token3": 2,
            "token2": 3,
            "token4": 4,
            "token1": 5
        },
        "str2freq": {
            "<PAD>":  0,
            "<UNK>":  0,
            "token3": 2,
            "token2": 1,
            "token4": 1,
            "token1": 1
        }
    }
}

最后,创建了一个大小为 n x l 的 numpy 矩阵,其中 n 是列中的行数,l 是最长分词列表的大小和可设置的 max_length 参数中的较小值。所有短于 l 的序列都在右侧进行填充到 max_length(尽管此行为也可以通过参数修改)。

分词后 numpy 矩阵
[token3, token4, token2] 2 4 3
[token3, token1] 2 5 0

最终结果矩阵以原始列名作为键保存在已处理的数据集中,而标记到整数 ID 的映射(及其逆映射)保存在 JSON 文件中。

创建了一个按频率排序的词汇表字典,将标记映射到整数 ID。特殊符号如 <PAD>, <START>, <STOP><UNK> 具有特定的索引。默认情况下,我们使用 [0, 1, 2, 3],但这些可以手动覆盖。

如果指定了 huggingface 编码器,则会使用该编码器的特殊符号索引。

计算的元数据包括:

  1. 整数到字符串的映射(idx2str
  2. 字符串到 ID 的映射(str2idx
  3. 字符串到频率的映射(str2freq
  4. 所有序列的最大长度(max_sequence_length
  5. 附加的预处理信息(默认为如何填充缺失值以及用于填充缺失值的标记)

文本特征

Text 特征的处理方式与序列特征相同,但有几点不同。会进行两次不同的分词:一次按每个字符分割,一次使用自定义分词器。已处理的数据集文件中会添加两个不同的键,一个用于字符矩阵,一个用于符号矩阵。

JSON 文件中也发生同样的情况,其中有两组字典:一组用于将字符映射到整数(及其逆映射),另一组用于将符号映射到整数(及其逆映射)。

如果指定了 huggingface 编码器,则会使用该编码器的分词器进行基于符号的分词。

在配置中,用户可以指定使用哪个级别的表示:字符级别或符号级别。

时间序列特征

Timeseries 特征的处理方式与序列特征相同,唯一的区别是已处理数据集文件中的矩阵值不是整数,而是浮点数。JSON 文件没有附加的映射信息。

图像特征

Image 特征转换为大小为 n x h x w x c 的 int8 值张量(其中 n 是数据集的大小,h x w 是图像的可设置的特定重采样大小,c 是颜色通道数),并添加到已处理的数据集中,键为该特征在数据集中的列名。

列名被添加到 JSON 文件中,并附带一个字典,其中包含有关重采样大小的预处理信息。