具体涵盖以下主题:
所有表格数据模型的最佳做法
无论您是要创建适用于 AutoML 模型还是用于表格数据的自定义模型,以下最佳做法都适用。
避免数据泄露
当您的训练数据包含请求预测时无从获得的预测信息时,会发生数据泄露。数据泄露可能会导致模型显示出色的评估指标,但在实际数据上却表现不佳。
例如,假设您想知道您的商店明天将销售多少冰淇淋。您不能在训练数据中包含目标日的温度,因为您不会知道温度(尚未发生)。但是,您可以使用前一天预报的温度,该温度可以包含在预测请求中。
在多个数据分块中使用同一数据时,也可能会出现数据泄露。如果使用时间数据,请确保同一日期中的数据仅用于三个数据分块之一。
避免训练-应用偏差 (training-serving skew)
如果您生成训练数据所用的方式不同于请求预测时生成数据所用的方式,即会发生训练-应用偏差。
例如,如果您要使用平均值,在进行训练时使用 10 天的平均值,但请求预测时却使用上个月的平均值。
一般来讲,您应该检查生成训练数据的方式与生成应用数据(用于生成预测的数据)的方式之间的差异,以避免出现训练-应用偏差。
训练-应用偏差和数据分布
训练、验证和测试数据拆分中的数据分布也可能会导致训练-应用偏差。在生产环境中部署模型时的数据分布与训练模型的数据集的数据分布之间通常存在差异。例如,在生产环境中,模型可能应用于完全不同于训练期间所看到的用户群,或者模型可能用于在记录最终训练数据 30 天后进行预测。
为获得最佳结果,请确保用于创建模型的数据拆分的分布准确反映了训练数据,并且您将在生产环境中进行预测的数据。Vertex AI 可以生成非单调预测,如果生产数据的采样分布与训练数据之间存在非常大的差异,那么非单调预测不是很可靠。
此外,生产数据与训练数据之间的差异必须反映在验证数据拆分与训练数据拆分之间的差异上,以及测试数据拆分与验证数据拆分之间的差异上。
例如,如果您计划预测接下来 30 天的用户生命周期价值 (LTV),请确保验证数据拆分中的数据是训练数据拆分中 30 天后的数据,并且测试数据拆分中的数据是验证数据拆分中 30 天后的数据。
同样,如果您希望调整模型以针对新用户进行一般性预测,请确保来自特定用户的数据仅包含在训练数据的单个拆分中。例如,有关 user1
的所有行位于训练数据拆分中,有关 user2
的所有行位于验证数据拆分中,有关 user3
的所有行位于测试数据拆分中。
提供时间信号
对于分类和回归模型,如果数据中的底层模式有可能随时间变化(不是随时间随机分布),请确保将该信息提供给 Vertex AI。您可以通过多种方式提供时间信号:
如果每行数据都有时间戳,请确保该列被包括在内,转换类型为
Timestamp
,并在训练模型时设置为时间列。该排序用于拆分数据:将最新数据作为测试数据,最早的数据作为训练数据。了解详情。如果您的时间列没有很多不同值,则应使用手动拆分,而不是使用“时间”列来拆分数据。否则,您可能无法在每个数据集中获得足够的行数,从而导致训练失败。
如果时间信息未包含在单个列中,您可以使用手动数据拆分将最新数据用作测试数据,并将最早的数据用作训练数据。
在必要情况下明确信息
对于某些数据原语,您可以通过进行特征工程处理来提高模型质量。
例如,如果您的数据包含经度和纬度,则这些列将被视为数值,而不进行特殊计算。如果位置或距离可为您的问题提供有用信息,则必须提取一个明确提供该信息的特征。
一些可能需要进行特征工程的数据类型有:
- 经度/纬度
- 网址
- IP 地址
- 电子邮件地址
- 电话号码
- 其他地理代码(例如邮政编码)
在一行中包含计算或汇总数据
Vertex AI 仅使用单个行中的输入数据来预测该行的目标值。如果您计算或汇总了来自其他行或来源的数据,而这些数据在确定某个行的预测值时非常有用,请将这些数据包含在来源行中。请注意确保新列不会导致数据泄露或训练-应用偏差。
例如,如果您想要预测下周某种产品的需求,可以通过添加具有以下值的列来提高预测质量:
- 与该产品属于同一类别的库存商品总数。
- 与该产品属于同一类别的库存商品的平均价格。
- 请求预测时距已知节假日的天数。
- 等等…
另一个例子是,如果您想要预测某一特定用户是否会购买产品,则可以通过添加具有以下值的列来提高预测质量:
- 该特定用户的平均历史转化率或点击率。
- 当前该用户的购物车中有多少产品。
避免偏见
确保您的训练数据能够代表您将要预测的潜在数据的整个范围。例如,如果您的客户遍布全球,则不应仅使用来自一个国家/地区的训练数据。
表格 AutoML 模型的最佳做法
以下最佳做法用于为 AutoML 表格模型创建表格训练数据。
适当表示 Null 值
如果从 CSV 导入数据,请使用空字符串表示 Null 值。如果从 BigQuery 导入则使用 Null 值。
如果您的数据使用特殊字符或数字来表示 Null 值(包括零),则这些值会被错误解读,从而降低模型质量。
尽可能避免缺失值
请检查您的数据是否存在缺失值。如果可能,请更正这些值。另外,您也可以将该值留空,并将其视为 null 值。
使用空格分隔文本
Vertex AI 对文本字符串进行分词,并可以从单个字词中获取训练信号。它使用空格来分隔字词;由其他字符分隔的字词被视为单个实体。
例如,如果您提供文本“红/绿/蓝”,该文本不会被标记化为“红”“绿”和“蓝”。如果这些单独的字词对于训练模型可能很重要,则您应该在将文本加入训练数据之前将其转换为“红 绿 蓝”。
确保您的分类特征准确且干净
数据不一致可能导致类别被错误拆分。例如,如果您的数据包含“Brown”和“brown”,您可能将它们视为相同的值,但 Vertex AI 会将这些值用作单独的类别。拼写错误也会造成类似的后果。在创建训练数据之前,请确保从分类数据中消除这种不一致的现象。
特别注意分类模型的不平衡分类
如果您的分类不平衡(包含一个或多个罕见结果的分类问题),请查看以下提示。
为少数类提供充分的训练数据
某个类别的数据行数太少,会降低模型质量。如果可能,您应为每个类提供至少 100 行数据。
考虑使用手动拆分
Vertex AI 会随机(但确定性地)选择测试数据集的行。如果存在分类不平衡的情况,少数类在测试数据集中可能只有极小数量的(甚至完全没有)数据,从而导致训练失败。
如果您的类不平衡,您可能需要进行手动拆分,以确保每个拆分中的少数结果都有足够多的行。
提供足够多的训练数据
如果您没有提供足够多的训练数据,生成的模型可能会性能不佳。用于训练模型的列越多,您需要提供的数据就越多。
您的数据集必须始终包含至少 1000 行。
下表根据您的目标提供了一些启发式信息,以提供多少训练数据。
目标 | 建议的最小训练数据量 |
---|---|
分类 | 行数至少为列数的 10 倍。 |
预测 | 用于训练模型的每一列至少有 10 个时序。 |
回归 | 行数至少为列数的 50 倍。 |
让 Vertex AI 执行所有其他预处理和转换工作
除非另有说明,否则在训练 AutoML 模型时,Vertex AI 会为您执行特征工程。AutoML 有权访问您的底层数据时效果最佳。如需查看 AutoML 按转换类型执行的所有转换的列表,请参阅 Vertex AI 转换。
表格预测模型的最佳做法
用于预测模型的训练数据有一些特殊注意事项。
选择数据粒度时的注意事项
训练预测模型时,您需要指定数据粒度,也就是训练数据行之间的时间间隔。可以是每小时、每天、每周、每月或每年。此外,还可以是每 1 分钟、每 5 分钟、每 10 分钟、每 15 分钟或每 30 分钟。
训练数据和所有批量预测数据中的数据粒度必须保持一致。如果指定了每天粒度,并且两个训练数据行之间间隔 2 天,Vertex AI 会将中间的日期视为缺失数据,这可能会降低模型性能。如果同一时序中有多个行具有相同时间戳(由粒度确定),在训练时会被视为验证错误。
通常,数据收集做法决定了数据粒度。
如何查找适合上下文窗口的值
如果您预计不会有太多过去的预测数据(冷启动),请先将上下文窗口设置为 0。否则,在预测水平大小与预测水平大小的 10 倍之间,都应让上下文时段保持良好的效果。
您可以尝试执行以下步骤来为您的数据找到合适的值:
对于第一次训练迭代,将上下文窗口和预测范围设置为相同的值,并将训练预算至少设置为 6 小时。
使用相同的训练预算再次训练模型,但将上下文时段的大小增加到预测范围的大小的 2 倍。
如果第二个模型的评估指标显示明显改进,则将上下文窗口增加到预测范围大小的 5 倍并再次训练模型。考虑成比例增加训练预算(如果您在第一步中训练了 10 小时,请将训练预算增加到 50 小时)。
继续增加上下文窗口,直至评估指标不再改善或者您已对结果感到满意。还原为生成可接受结果的上下文窗口的最低值。
增加上下文窗口会产生以下影响:
增加训练时间。
具有更大的上下文时段后,该模型会在训练中使用更多数据点,从而增加训练时间。
增加预测数据所需的历史记录量
您的预测数据应提供与上下文窗口值相同的历史数据点。
数据格式的最佳做法
您可以使用宽格式或窄格式创建训练数据。对于回归和分类模型,宽格式被广泛使用,并且更易于汇编和审核。对于预测模型,使用窄格式可帮助您避免在数据和目标之间建立意外连接(数据泄露)。
创建训练数据以训练预测模型时,每一行应代表单个时序上的单个观察结果。您必须有一个表示您的时序标识符的列(用于区分时序),以及一个表示将要预测的值的列(您的目标)。然后,当您为目标请求预测时,用于训练模型的行中的每个其他值都必须存在。
考虑以下(简化和缩写)的示例训练数据:
日期 | Widget_1_Demand | Widget_2_Demand | Widget_3_Demand | 宣传 | 区域 |
---|---|---|---|---|---|
01/01/2019 | 112 | 241 | 0 | 0 | CA |
01/02/2019 | 141 | 219 | 0 | 1 | CA |
01/03/2019 | 149 | 244 | 0 | 0 | CA |
01/01/2019 | 52 | 0 | 43 | 0 | IL |
01/02/2019 | 81 | 0 | 26 | 1 | IL |
01/03/2019 | 89 | 0 | 86 | 0 | IL |
此表使用宽格式按日期显示了业务数据,但无法用于当前形式的预测模型。没有单个目标列,也没有时序 ID 列,对于任何给定日期,您都不知道在预测时对其他微件的需求。
您可以将该表转换为以下格式:
日期 | 产品 | Region_CA_Demand | Region_IL_Demand | 宣传 |
---|---|---|---|---|
01/01/2019 | Widget_1 | 112 | 52 | 0 |
01/02/2019 | Widget_1 | 141 | 81 | 1 |
01/03/2019 | Widget_1 | 149 | 89 | 0 |
01/01/2019 | Widget_2 | 241 | 0 | 0 |
01/02/2019 | Widget_2 | 219 | 0 | 1 |
01/03/2019 | Widget_2 | 244 | 0 | 0 |
01/01/2019 | Widget_3 | 0 | 43 | 0 |
01/02/2019 | Widget_3 | 0 | 26 | 1 |
01/03/2019 | Widget_3 | 0 | 86 | 0 |
现在,我们有一个潜在的时序 ID 列,产品。但是,此格式只能用于预测其中一个区域,并且在预测时需要知道另一个区域的数据。
解决方案是转换为窄格式,使每一行表示一个观察结果。系统会对每一行重复独立于时序的所有数据:
日期 | 需求 | ID | 宣传 |
---|---|---|---|
01/01/2019 | 112 | Widget_1_CA | 0 |
01/02/2019 | 141 | Widget_1_CA | 1 |
01/03/2019 | 149 | Widget_1_CA | 0 |
01/01/2019 | 52 | Widget_1_IL | 0 |
01/02/2019 | 81 | Widget_1_IL | 1 |
01/03/2019 | 89 | Widget_1_IL | 0 |
01/01/2019 | 241 | Widget_2_CA | 0 |
01/02/2019 | 219 | Widget_2_CA | 1 |
01/03/2019 | 244 | Widget_2_CA | 0 |
01/01/2019 | 0 | Widget_2_IL | 0 |
01/02/2019 | 0 | Widget_2_IL | 1 |
01/03/2019 | 0 | Widget_2_IL | 0 |
01/01/2019 | 0 | Widget_3_CA | 0 |
01/02/2019 | 0 | Widget_3_CA | 1 |
01/03/2019 | 0 | Widget_3_CA | 0 |
01/01/2019 | 43 | Widget_3_IL | 0 |
01/02/2019 | 26 | Widget_3_IL | 1 |
01/03/2019 | 86 | Widget_3_IL | 0 |
现在,我们有一个时间序列标识符 (ID)、一个目标列(需求)和一个时间列(日期)。此外,每一行基于一个观察结果,可用于预测目标值。“促销”列用作训练模型的特征。
在实际应用中,您的行数和列数将比示例多得多。但您必须按照此处的准则设计数据结构,以避免数据泄露。