数据预处理
概述¶
Ludwig 数据预处理对输入数据集执行以下几种不同的操作:
- 计算元数据,例如词汇表、词汇大小和序列长度。这使得 Ludwig 能够创建像
idx2str
或str2idx
这样的字典,用于将原始数据值映射到张量值。 - 处理缺失值:任何具有缺失特征值的行/示例都会被填充为常量或其他基于示例的值(参见类型全局预处理配置)。
- (可选)分割数据集为训练集、验证集和测试集,基于分割比例,或使用显式指定的分割方式。
- (可选)平衡数据,这对于类别严重不足或过多的数据集非常有用。
数据预处理将原始数据映射到两个文件: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 文件中,并附带一个字典,其中包含:
- 整数到字符串的映射(
idx2str
) - 字符串到 ID 的映射(
str2idx
) - 字符串到频率的映射(
str2freq
) - 所有标记集合的大小(
vocab_size
) - 附加的预处理信息(默认为如何填充缺失值以及用于填充缺失值的标记)
集合特征¶
Set
特征转换为大小为 n x l
的二元(实际是 int8)值矩阵(其中 n
是数据集的大小,l
是最大集合大小和 max_size
参数中的较小值),并添加到已处理的数据集中,键为该特征在数据集中的列名。
集合到整数的映射方式如下:首先使用分词器将字符串映射到集合项序列(默认通过空格分隔)。然后收集数据集中该列中所有不同的集合项字符串的字典,然后按频率对其进行排序,并从最频繁到最稀有的项分配递增的整数 ID(其中 0 分配给用于填充的 <PAD>
,1 分配给 <UNK>
项)。列名被添加到 JSON 文件中,并附带一个字典,其中包含:
- 整数到字符串的映射(
idx2str
) - 字符串到 ID 的映射(
str2idx
) - 字符串到频率的映射(
str2freq
) - 所有集合的最大大小(
max_set_size
) - 附加的预处理信息(默认为如何填充缺失值以及用于填充缺失值的标记)
词袋特征¶
Bag
特征的处理方式与集合特征相同,唯一的区别是矩阵的值为浮点数(频率)。
序列特征¶
序列特征默认由 space
分词器处理。它使用空格将特征值的内容分割成字符串列表。
分词前 | 分词后 |
---|---|
"token3 token4 token2" | [token3, token4, token2] |
"token3 token1" | [token3, token1] |
计算元数据:创建了一个列表 idx2str
和两个字典 str2idx
和 str2freq
,包含通过分割列的所有行获得的所有列表中的所有标记,并为每个标记分配一个整数 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
编码器,则会使用该编码器的特殊符号索引。
计算的元数据包括:
- 整数到字符串的映射(
idx2str
) - 字符串到 ID 的映射(
str2idx
) - 字符串到频率的映射(
str2freq
) - 所有序列的最大长度(
max_sequence_length
) - 附加的预处理信息(默认为如何填充缺失值以及用于填充缺失值的标记)
文本特征¶
Text
特征的处理方式与序列特征相同,但有几点不同。会进行两次不同的分词:一次按每个字符分割,一次使用自定义分词器。已处理的数据集文件中会添加两个不同的键,一个用于字符矩阵,一个用于符号矩阵。
JSON 文件中也发生同样的情况,其中有两组字典:一组用于将字符映射到整数(及其逆映射),另一组用于将符号映射到整数(及其逆映射)。
如果指定了 huggingface
编码器,则会使用该编码器的分词器进行基于符号的分词。
在配置中,用户可以指定使用哪个级别的表示:字符级别或符号级别。
时间序列特征¶
Timeseries
特征的处理方式与序列特征相同,唯一的区别是已处理数据集文件中的矩阵值不是整数,而是浮点数。JSON 文件没有附加的映射信息。
图像特征¶
Image
特征转换为大小为 n x h x w x c
的 int8 值张量(其中 n
是数据集的大小,h x w
是图像的可设置的特定重采样大小,c
是颜色通道数),并添加到已处理的数据集中,键为该特征在数据集中的列名。
列名被添加到 JSON 文件中,并附带一个字典,其中包含有关重采样大小的预处理信息。