自动化机器学习中的数据特征化
本文介绍如何为自动化机器学习 (AutoML) 试验自定义 Azure 机器学习中的数据特征化设置。
特征工程和特征化
训练数据由行和列构成。 每一行都是一条观测或记录,而每行的列则是用于描述每条记录的特征。 通常,会选择对数据中模式的特点描述效果最佳的特征来创建预测模型。
虽然许多原始数据字段都可以直接用于训练模型,但通常还是需要创建其他(工程化)特征来提供信息,以更好地区分数据中的模式。 此过程被称为特征工程,它会利用数据领域知识来创建特征,这些特征反过来又会帮助机器学习算法更好地学习。
在 Azure 机器学习中,应用了数据缩放和规范化技术来简化特征工程。 这些技术和此特征工程在自动化机器学习 (ML) 试验中统称为特征化。
先决条件
本文假设你已知道如何配置自动化 ML 试验。
重要
本文中的 Python 命令需要最新的 azureml-train-automl
包版本。
- 将最新的
azureml-train-automl
包安装到本地环境。 - 有关最新
azureml-train-automl
包的详细信息,请参阅azureml-train-automl
。
有关配置的信息,请参阅以下文章:
- 对于代码优先体验:使用 Python 设置 AutoML 训练
- 对于无代码体验:使用工作室 UI 为表格数据设置无代码 AutoML 训练
配置特征化
在每一个自动化机器学习试验中,默认情况下都会将自动缩放和规范化技术应用于数据。 这些技术是特征化的类型,用于帮助对不同规模数据的特征敏感的某些算法。 可以启用更多特征化,例如缺失值插补、编码和转换 。
注意
自动化机器学习特征化步骤(例如特征规范化、处理缺失数据,或将文本转换为数字)成为了基础模型的一部分。 使用模型进行预测时,将自动向输入数据应用在训练期间应用的相同特征化步骤。
对于使用 Python SDK 配置的试验,你可以启用或禁用特征化设置,并进一步指定要用于试验的特征化步骤。 如果使用的是 Azure 机器学习工作室,请参阅启用特征化的步骤。
下表列出了 AutoMLConfig 类中 featurization
的已接受设置:
特征化配置 | 说明 |
---|---|
"featurization": 'auto' |
指定在预处理过程中自动执行数据护栏和特征化步骤。 此设置为默认设置。 |
"featurization": 'off' |
指定不自动执行特征化步骤。 |
"featurization": 'FeaturizationConfig' |
指定将使用自定义特征化步骤。 了解如何自定义特征化。 |
自动特征化
下表汇总了自动应用于你的数据的技术。 这些方法适用于使用 SDK 或工作室 UI 配置的试验。 若要禁用此行为,请在 AutoMLConfig
对象中设置 "featurization": 'off'
。
注意
如果计划将 AutoML 创建的模型导出到 ONNX 模型,则 ONNX 格式中仅支持使用星号(“*”)指示的特征化选项。 详细了解如何将模型转换为 ONNX。
特征化步骤 | 说明 |
---|---|
删除高基数或者无差异的特征* | 从训练集和验证集中删除这些特征。 适用于所有值都缺失的特征、所有行使用同一值的特征,或者包含高基数(例如哈希、ID 或 GUID)的特征。 |
插补缺少的值* | 对于数字特征,将在列中插补平均值。 对于分类特征,将插补最常用值。 |
生成更多特征* | 对于日期时间特征:年、月、日、星期、年日期、季、年周、小时、分钟、秒。 对于预测任务,将创建以下附加的日期/时间特征:ISO 年份、半年、字符串形式的日历月份、周、字符串形式的周几、一季中的日期、一年中的日期、AM/PM(如果是中午 (12 pm) 之前的时间,则此项为 0,否则为 1)、字符串形式的 AM/PM、一天中的小时(12 小时制) 对于文本特征:基于单元语法、双元语法和三元语法的字词频率。 详细了解如何通过 BERT 执行此操作。 |
转换和编码* | 将唯一值较少的数字特征转换为分类特征。 将为低基数分类特征使用 One-hot 编码。 将为高基数分类特征使用 One-hot-hash 编码。 |
单词嵌入 | 文本特征化器使用预先训练的模型将文本标记的矢量转换为句子矢量。 每个单词在文档中的嵌入矢量与其余矢量聚合在一起,以生成文档特征矢量。 |
群集距离 | 基于所有数字列训练 k 平均聚类模型。 生成 k 个新特征(每个聚类一个新数字特征),这些特征包含每个样本与每个聚类质心之间的距离。 |
在每个自动化机器学习试验中,数据将自动缩放或规范化,以帮助确保算法的良好性能。 在模型训练过程中,将对每个模型应用以下缩放或规范化技术之一。
缩放和处理 | 说明 |
---|---|
StandardScaleWrapper | 通过移除平均值并缩放到单位差异对特征进行标准化处理。 |
MinMaxScalar | 通过按该列的最小值和最大值缩放每个特征来转换特征。 |
MaxAbsScaler | 按特征的最大绝对值缩放每个特征。 |
RobustScalar | 按特征的分位数范围缩放特征。 |
PCA | 使用数据的奇异值分解进行线性降维,以将其投影到低维空间。 |
TruncatedSVD | 此转换器通过截断的奇异值分解 (SVD) 执行线性降维。 与 PCA 相反,此估算器在计算奇异值分解之前不会将数据居中,这意味着它可以有效地处理 scipy.sparse 矩阵。 |
SparseNormalizer | 至少包含一个非零成分的每个样本(即,数据矩阵的每个行)会重新缩放,而无论其他样本如何,从而使其范数(l1 或 l2)等于 1。 |
数据护栏
“数据护栏”有助于识别数据的潜在问题(例如缺少值或类不平衡)。 它们还可帮助你采取纠正措施来改进结果。
数据护栏适用于:
- 对于 SDK 试验:在
AutoMLConfig
对象中指定了参数"featurization": 'auto'
或validation=auto
时 - 对于工作室试验:当启用了自动特征化时
可通过以下方式查看试验的数据护栏:
- 使用 SDK 提交试验时设置
show_output=True
。 - 访问工作室中自动化机器学习运行的“数据护栏”选项卡。
数据护栏状态
数据护栏显示以下三种状态之一:
状态 | 说明 |
---|---|
已通过 | 未检测到任何数据问题,你无需执行任何操作。 |
已完成 | 已对数据应用更改。 我们建议你查看 AutoML 采取的纠正措施,以确保所做的更改与预期的结果一致。 |
出现警告 | 检测到数据问题,但无法修正。 我们建议你进行修正并解决此问题。 |
支持的数据护栏
下表描述了当前支持的数据护栏,以及你在提交试验时可能会看到的相关状态:
护栏 | 状态 | 触发器的条件 |
---|---|---|
插补缺少的特征值 | 传递 完成 |
在训练数据中未检测到缺失特征值。 详细了解缺失值插补。 在训练数据中检测到缺失特征值并进行了插补。 |
高基数特征检测 | 传递 完成 |
已分析输入,但未检测到任何高基数特征。 在输入中检测到了高基数特征,并进行了处理。 |
验证拆分处理 | 完成 | 已将验证配置设置为 'auto' ,并且训练数据包含的行少于 20,000 行。 已使用交叉验证来验证经过训练的模型的每个迭代。 详细了解验证数据。 已将验证配置设置为 'auto' ,并且训练数据包含的行多于 20,000 行。 输入数据已被拆分成训练数据集和验证数据集,以用于验证模型。 |
类均衡检测 | 传递 收到警报 完成 |
输入已经过分析,训练数据中的所有类都是均衡的。 如果某个数据集中每个类都有良好的表示形式(按样本的数量和比率进行度量),则将该数据集视为均衡的数据集。 在输入中检测到了不均衡类。 若要修复模型偏差,请解决均衡问题。 详细了解不均衡数据。 在输入中检测到不均衡类,并且扫描逻辑已确定要应用均衡。 |
内存问题检测 | 传递 完成 |
已分析了选定的值(范围、滞后、滚动窗口),但未检测到潜在的内存不足问题。 详细了解时序预测配置。 已分析了选定的值(范围、滞后、滚动窗口),可能会导致你的试验遇到内存不足问题。 滞后或滚动窗口配置已禁用。 |
频率检测 | 传递 完成 |
已分析了时序,所有数据点都与检测到的频率保持一致。 已分析时序,检测到了与已检测到的频率不一致的数据点。 这些数据点已从数据集中删除。 |
交叉验证 | 完成 | 为了准确评估 AutoML 训练的模型,我们使用未对模型进行训练的数据集。 因此,如果用户未提供明确的验证数据集,则会使用一部分训练数据集来实现此目的。 对于较小的数据集(少于 20,000 个样本),将使用交叉验证,否则单个保留集将从训练数据拆分以充当验证数据集。 因此,对于输入数据,如果训练样本的数量少于 1000 个,我们将使用 10 倍交叉验证,并在所有其他情况下使用 3 倍交叉验证。 |
训练-测试数据拆分 | 完成 | 为了准确评估 AutoML 训练的模型,我们使用未对模型进行训练的数据集。 因此,如果用户未提供明确的验证数据集,则会使用一部分训练数据集来实现此目的。 对于较小的数据集(少于 20,000 个样本),将使用交叉验证,否则单个保留集将从训练数据拆分以充当验证数据集。 因此,输入数据将拆分为训练数据集和保留验证数据集。 |
时序 ID 检测 | 传递 固定 |
已分析数据集,未检测到重复的时间索引。 在数据集中找到多个时序,并自动为数据集创建了时序标识符。 |
时序聚合 | 传递 固定 |
数据集频率与用户指定的频率一致。 未执行聚合。 数据已聚合,以便与用户提供的频率保持一致。 |
短时序处理 | 传递 固定 |
自动化 ML 检测到,输入数据中的每个时序都有足够的数据点,可以继续进行训练。 自动化 ML 检测到一些系列包含的数据点不足,无法训练模型。 为了继续训练,这些较短的系列已被丢弃或填充。 |
自定义特征化
你可以自定义特征化设置,以确保用于训练机器学习模型的数据和特征能够产生相关的预测。
若要自定义特征化,请在 AutoMLConfig
对象中指定 "featurization": FeaturizationConfig
。 如果使用 Azure 机器学习工作室进行试验,请参阅操作方法文章。 若要为预测任务类型自定义特征化,请参阅预测操作指南。
支持的自定义项包括:
自定义 | 定义 |
---|---|
列用途更新 | 重写指定列的自动检测到的特征类型。 |
转换器参数更新 | 更新指定转换器的参数。 当前支持 Imputer(平均值、最频繁使用的值和中值)和 HashOneHotEncoder。 |
删除列 | 指定要从特征化中删除的列。 |
阻止转换器 | 指定要在特征化过程中使用的块转换器。 |
注意
从 SDK 版本1.19 开始,“删除列”功能已弃用。 在自动化 ML 试验中使用数据集之前,请将数据集中的列删除,这是数据清理过程的一部分。
使用 API 调用创建 FeaturizationConfig
对象:
featurization_config = FeaturizationConfig()
featurization_config.blocked_transformers = ['LabelEncoder']
featurization_config.drop_columns = ['aspiration', 'stroke']
featurization_config.add_column_purpose('engine-size', 'Numeric')
featurization_config.add_column_purpose('body-style', 'CategoricalHash')
#default strategy mean, add transformer param for 3 columns
featurization_config.add_transformer_params('Imputer', ['engine-size'], {"strategy": "median"})
featurization_config.add_transformer_params('Imputer', ['city-mpg'], {"strategy": "median"})
featurization_config.add_transformer_params('Imputer', ['bore'], {"strategy": "most_frequent"})
featurization_config.add_transformer_params('HashOneHotEncoder', [], {"number_of_bits": 3})
特征化透明度
每个 AutoML 模型均已自动应用特征化。 特征化包括自动特征工程(执行 "featurization": 'auto'
时)和缩放和归一化,这会影响所选算法及其超参数值。 AutoML 支持不同的方法,以确保你直观了解对模型应用了哪些内容。
请考虑此预测示例:
- 有四个输入功能:A(数值)、B(数值)、C(数值)、D(日期/时间)。
- 数值特征 C 被删除,因为它是一个 ID 列,包含所有唯一值。
- 数值特征 A 和 B 包含缺失值,因此由平均值进行插补。
- 日期/时间特征 D 已特征化为 11 个不同的工程特征。
若要获取此信息,请使用来自自动化 ML 试验运行的 fitted_model
输出。
automl_config = AutoMLConfig(…)
automl_run = experiment.submit(automl_config …)
best_run, fitted_model = automl_run.get_output()
自动化特征工程
get_engineered_feature_names()
返回工程特征名称的列表。
注意
请将“timeseriestransformer”用于任务为“预测”的情况,否则请将“datatransformer”用于“回归”或“分类”任务。
fitted_model.named_steps['timeseriestransformer']. get_engineered_feature_names ()
此列表包括所有工程特征的名称。
['A', 'B', 'A_WASNULL', 'B_WASNULL', 'year', 'half', 'quarter', 'month', 'day', 'hour', 'am_pm', 'hour12', 'wday', 'qday', 'week']
get_featurization_summary()
获取所有输入特征的特征化摘要。
fitted_model.named_steps['timeseriestransformer'].get_featurization_summary()
输出
[{'RawFeatureName': 'A',
'TypeDetected': 'Numeric',
'Dropped': 'No',
'EngineeredFeatureCount': 2,
'Tranformations': ['MeanImputer', 'ImputationMarker']},
{'RawFeatureName': 'B',
'TypeDetected': 'Numeric',
'Dropped': 'No',
'EngineeredFeatureCount': 2,
'Tranformations': ['MeanImputer', 'ImputationMarker']},
{'RawFeatureName': 'C',
'TypeDetected': 'Numeric',
'Dropped': 'Yes',
'EngineeredFeatureCount': 0,
'Tranformations': []},
{'RawFeatureName': 'D',
'TypeDetected': 'DateTime',
'Dropped': 'No',
'EngineeredFeatureCount': 11,
'Tranformations': ['DateTime','DateTime','DateTime','DateTime','DateTime','DateTime','DateTime','DateTime',ateTime','DateTime','DateTime']}]
输出 | 定义 |
---|---|
RawFeatureName | 从提供的数据集中输入特征/列名称。 |
TypeDetected | 检测到的输入特征的数据类型。 |
Dropped | 指示是否已删除或使用输入特征。 |
EngineeringFeatureCount | 通过自动化特征工程转换生成的特征数。 |
转换 | 应用于输入特征以生成工程特征的转换列表。 |
缩放和归一化
若要了解缩放/归一化和所选算法及其超参数值,请使用 fitted_model.steps
。
下面的示例输出是针对所选运行而运行 fitted_model.steps
的结果:
[('RobustScaler',
RobustScaler(copy=True,
quantile_range=[10, 90],
with_centering=True,
with_scaling=True)),
('LogisticRegression',
LogisticRegression(C=0.18420699693267145, class_weight='balanced',
dual=False,
fit_intercept=True,
intercept_scaling=1,
max_iter=100,
multi_class='multinomial',
n_jobs=1, penalty='l2',
random_state=None,
solver='newton-cg',
tol=0.0001,
verbose=0,
warm_start=False))]
若要获取更多详细信息,请使用此帮助程序函数:
from pprint import pprint
def print_model(model, prefix=""):
for step in model.steps:
print(prefix + step[0])
if hasattr(step[1], 'estimators') and hasattr(step[1], 'weights'):
pprint({'estimators': list(e[0] for e in step[1].estimators), 'weights': step[1].weights})
print()
for estimator in step[1].estimators:
print_model(estimator[1], estimator[0]+ ' - ')
elif hasattr(step[1], '_base_learners') and hasattr(step[1], '_meta_learner'):
print("\nMeta Learner")
pprint(step[1]._meta_learner)
print()
for estimator in step[1]._base_learners:
print_model(estimator[1], estimator[0]+ ' - ')
else:
pprint(step[1].get_params())
print()
此帮助程序函数使用 LogisticRegression with RobustScalar
作为特定算法返回特定运行的以下输出。
RobustScaler
{'copy': True,
'quantile_range': [10, 90],
'with_centering': True,
'with_scaling': True}
LogisticRegression
{'C': 0.18420699693267145,
'class_weight': 'balanced',
'dual': False,
'fit_intercept': True,
'intercept_scaling': 1,
'max_iter': 100,
'multi_class': 'multinomial',
'n_jobs': 1,
'penalty': 'l2',
'random_state': None,
'solver': 'newton-cg',
'tol': 0.0001,
'verbose': 0,
'warm_start': False}
预测类概率
使用自动化 ML 生成的模型都具有包装器对象,这些对象对其开源来源类中的功能进行镜像。 自动化 ML 返回的大多数分类模型包装器对象都实现了 predict_proba()
函数,该函数接受特征(X 值)的数组式或稀疏矩阵数据样本,并返回每个样本的 n 维数组及其各自的类概率。
假设你已使用相同调用检索了最佳运行和拟合模型,则可以直接从拟合模型调用 predict_proba()
,从而根据模型类型提供相应格式的 X_test
样本。
best_run, fitted_model = automl_run.get_output()
class_prob = fitted_model.predict_proba(X_test)
如果基础模型不支持 predict_proba()
函数或者格式不正确,则会引发特定于模型类的异常。 有关如何针对不同的模型类型实现此函数的示例,请参阅 RandomForestClassifier 和 XGBoost 参考文档。
自动化 ML 中的 BERT 集成
BERT 在自动化 ML 的特征化层中使用。 在此层中,如果列包含自由文本或其他类型的数据(例如时间戳或简单编号),则会相应地应用特征化。
对于 BERT,已利用用户提供的标签对该模型进行了微调和训练。 在这里,文档嵌入会作为特征随其他特征(例如基于时间戳的特征、一周中的某一天)一起输出。
了解如何设置 AutoML 以使用 Python 训练自然语言处理模型。
调用 BERT 的步骤
若要调用 BERT,请在 automl_settings 中设置 enable_dnn: True
,并使用 GPU 计算(vm_size = "STANDARD_NC6"
或性能更高的 GPU)。 如果使用 CPU 计算,则 AutoML 会启用 BiLSTM DNN 特征化器,而非启用 BERT。
自动化 ML 会为 BERT 执行以下步骤。
所有文本列的预处理和标记化。 例如,可以在最终模型的特征化摘要中找到
StringCast
转换器。 此笔记本中提供了一个有关如何生成模型的特征化摘要的示例。将所有文本列连接到单个文本列中,因此在最终模型中会调用
StringConcatTransformer
。我们实现的 BERT 将训练示例的总文本长度限制为 128 个标记。 这意味着,当已连接时,所有文本列在理想情况下的长度最多应为 128 个标记。 如果存在多个列,则应修剪每个列,使此条件得到满足。 否则,对于长度大于 128 个标记的已连接列,BERT 的 tokenizer 层会将此输入截断为 128 个标记。
在特征扫描过程中,AutoML 在数据样本上将 BERT 与基线(词袋特征)进行比较。 这一比较确定了 BERT 是否可以提高准确性。 如果 BERT 的性能优于基线,AutoML 会使用 BERT 对整个数据进行文本特征化。 在这种情况下,你将在最终模型中看到
PretrainedTextDNNTransformer
。
BERT 的运行时间通常比其他的特征化器更长。 为了提高性能,我们建议使用 STANDARD_NC24r 或 STANDARD_NC24rs_V3 以使用其 RDMA 功能。
如有多个节点可用(最多可以使用 8 个节点),则 AutoML 会在多个节点之间分配 BERT 训练。 可以通过将 max_concurrent_iterations
参数设置为大于 1,在 AutoMLConfig
对象中完成此操作。
AutoML 中 BERT 支持的语言
AutoML 目前支持大约 100 种语言,它根据数据集的语言选择合适的 BERT 模型。 对于德语数据,我们使用德语 BERT 模型。 对于英语,我们使用英语 BERT 模型。 对于所有其他语言,我们使用多语言 BERT 模型。
在下面的代码中,将触发德语 BERT 模型,因为数据集语言被指定为 deu
,而根据 ISO 分类,这一 3 个字母的代码表示德语:
from azureml.automl.core.featurization import FeaturizationConfig
featurization_config = FeaturizationConfig(dataset_language='deu')
automl_settings = {
"experiment_timeout_minutes": 120,
"primary_metric": 'accuracy',
# All other settings you want to use
"featurization": featurization_config,
"enable_dnn": True, # This enables BERT DNN featurizer
"enable_voting_ensemble": False,
"enable_stack_ensemble": False
}