在 ML 中,将原始数据转换为有意义的特征(称为特征工程的预处理步骤)是一个关键步骤。BigQuery ML 在这一领域取得了重大进展,为数据科学家和 ML 工程师提供了一组用于特征工程的多特征预处理函数。这些转换甚至可以无缝嵌入到模型中,确保其可以移植到 BigQuery 之外,以服务于 Vertex AI 等环境。现在,我们在 BigQuery ML 中更进一步,引入了一种独特的特征工程方法:模块化。这样就可以在 BigQuery 中轻松复用特征管道,同时还可以直接移植到 Vertex AI。
本内容提供了配套教程 - 立即尝试这一新功能吧!
使用 TRANSFORM 子句进行特征预处理
在 BigQuery ML 中创建模型时,CREATE MODEL 语句可以选择包含TRANSFORM 语句。这允许使用预处理函数将 SELECT 语句中的列转换为模型特征的自定义规范。这是一个很大的优势,因为用于转换的统计数据基于模型创建时使用的数据。这提供了与其他框架类似的预处理一致性——例如 TFX 框架的 Transform 组件,有助于消除训练/服务偏差。即使没有 TRANSFORM 语句,也会根据模型类型和数据类型应用自动转换。
以下面的示例(来自配套教程的一部分)为例,在输入之前应用了预处理步骤以估算缺失值。TRANSFORM 语句中还嵌入了用于缩放列的预处理。这种缩放会与模型一起嵌入,并应用于输入数据,该数据在此处输入之前已经进行了估算。嵌入式缩放函数的优点是模型会记住缩放中使用的计算参数,以便稍后在使用模型进行推理时应用。
CREATE OR REPLACE MODEL `statmike-mlops-349915.bqml.embedded_preprocessing` TRANSFORM( species, sex, island, split, ML.ROBUST_SCALER(body_mass_g) OVER() AS body_mass_g, ML.STANDARD_SCALER(culmen_length_mm) OVER() AS culmen_length_mm, ML.STANDARD_SCALER(culmen_depth_mm) OVER() AS culmen_depth_mm, ML.STANDARD_SCALER(flipper_length_mm) OVER() AS flipper_length_mm ) OPTIONS( model_type = 'BOOSTED_TREE_CLASSIFIER', input_label_cols = ['species'], data_split_method = 'CUSTOM', data_split_col = 'split', model_registry = 'VERTEX_AI', VERTEX_AI_MODEL_ID = 'bqml_embedded_preprocessing' ) AS SELECT species, island, CASE WHEN split = 'TRAIN' THEN FALSE ELSE TRUE END AS split, ML.IMPUTER(sex, 'most_frequent') OVER() AS sex, ML.IMPUTER(body_mass_g, 'median') OVER() AS body_mass_g, ML.IMPUTER(culmen_length_mm, 'mean') OVER() AS culmen_length_mm, ML.IMPUTER(culmen_depth_mm, 'mean') OVER() AS culmen_depth_mm, ML.IMPUTER(flipper_length_mm, 'mean') OVER() AS flipper_length_mm, FROM `statmike-mlops-349915.bqml.feature-engineering-source` |
使用 ML.TRANSFORM 函数进行可复用的预处理
通过新的 ML.TRANSFORM 表函数,可以直接调用模型的特征工程部分。这可以实现一些有用的工作流程,包括:
处理表格以查看预处理的特征
使用一个模型的转换来转换另一模型的输入
在下面的示例(摘自教程)中,ML.TRANSFORM 函数直接应用于输入数据,而无需使用原始训练数据重新计算缩放参数。这样可以把数据转换有效的复用到未来的模型、进一步的数据审查以及检测偏差和漂移的模型监控计算。
SELECT * FROM ML.TRANSFORM( MODEL `statmike-mlops-349915.bqml.embedded_preprocessing`, (SELECT * FROM `statmike-mlops-349915.bqml.feature-engineering-source` ) ) |
使用 TRANSFORM_ONLY 模型进行模块化预处理
通过创建仅转换模型,将可复用性提升到完全模块化的状态。这与其他模型一样,通过使用带有 TRANSFORM 语句的 CREATE MODEL,并使用值 model_type = TRANSFORM_ONLY 来实现。换句话说,它仅创建管道的特征工程部分的模型对象。这意味着转换模型也可以复用于转换任何 CREATE MODEL 语句的输入,甚至可以将模型注册到 Vertex AI 模型注册表,以便在 BigQuery 之外的 ML 管道中使用。您甚至可以将模型导出到 GCS 以实现完全的可移植性。
来自教程中的以下摘录显示了用于将 TRANSFORM 语句编译为模型的常规 CREATE MODEL 语句。在这种情况下,所有插补步骤都存储在单个模型对象中,该模型对象将记住训练数据中的平均值/中值,并能够将它们应用于未来记录的插补 —— 即使在推理时也是如此。
CREATE OR REPLACE MODEL `statmike-mlops-349915.bqml.modular_preprocessing_impute` TRANSFORM( ML.IMPUTER(sex, 'most_frequent') OVER() AS sex, ML.IMPUTER(body_mass_g, 'median') OVER() AS body_mass_g, ML.IMPUTER(culmen_length_mm, 'mean') OVER() AS culmen_length_mm, ML.IMPUTER(culmen_depth_mm, 'mean') OVER() AS culmen_depth_mm, ML.IMPUTER(flipper_length_mm, 'mean') OVER() AS flipper_length_mm ) OPTIONS( model_type = 'TRANSFORM_ONLY', model_registry = 'VERTEX_AI', VERTEX_AI_MODEL_ID = 'bqml_modular_preprocessing_impute' ) AS SELECT * FROM `statmike-mlops-349915.bqml.feature-engineering-source` WHERE split = 'TRAIN' |
仅转换模型 (TRANSFORM_ONLY model) 可以像我们之前介绍过的任何其他模型一样,使用相同的 ML.TRANSFORM 函数。
SELECT * FROM ML.TRANSFORM( MODEL `statmike-mlops-349915.bqml.modular_preprocessing_scale`, (SELECT * FROM `statmike-mlops-349915.bqml.feature-engineering-source`') ) |
特征管道
通过 TRANSFORM_ONLY 模型的模块化,可以在一个特征管道中使用多个模型。BigQuery SQL 查询语法 WITH 子句 (CTE) 使特征管道具有高度可读性。这个概念使得特征转换模型变得像特征存储一样,可以轻松地通过模块化使用。
首先作为这个想法的一个例子,为每个单独的特征创建一个 TRANSFORM_ONLY 模型:body_mass_g、culmen_length_mm、culmen_depth_mm、flipper_length_mm。在这里,它们用于将列缩放为特征 —— 就像我们在开始时创建的完整模型一样。
对于 body_mass_g:
CREATE OR REPLACE MODEL `statmike-mlops-349915.bqml.modular_preprocessing_scale_body_mass_g` TRANSFORM( * EXCEPT(body_mass_g), ML.ROBUST_SCALER(body_mass_g) OVER() AS body_mass_g, model_registry = 'VERTEX_AI', VERTEX_AI_MODEL_ID = 'bqml_modular_preprocessing_scale_body_mass_g' ) OPTIONS(model_type = 'TRANSFORM_ONLY') AS SELECT * FROM `statmike-mlops-349915.bqml.feature-engineering-source` WHERE split = 'TRAIN' |
对于 culmen_length_mm:
CREATE OR REPLACE MODEL `statmike-mlops-349915.bqml.modular_preprocessing_scale_culmen_length_mm` TRANSFORM( * EXCEPT(culmen_length_mm), ML.STANDARD_SCALER(culmen_length_mm) OVER() AS culmen_length_mm, model_registry = 'VERTEX_AI', VERTEX_AI_MODEL_ID = 'bqml_modular_preprocessing_scale_culmen_length_mm' ) OPTIONS(model_type = 'TRANSFORM_ONLY') AS SELECT * FROM `statmike-mlops-349915.bqml.feature-engineering-source` WHERE split = 'TRAIN' |
对于 culmen_depth_mm:
CREATE OR REPLACE MODEL `statmike-mlops-349915.bqml.modular_preprocessing_scale_culmen_depth_mm` TRANSFORM( * EXCEPT(culmen_depth_mm), ML.STANDARD_SCALER(culmen_depth_mm) OVER() AS culmen_depth_mm, model_registry = 'VERTEX_AI', VERTEX_AI_MODEL_ID = 'bqml_modular_preprocessing_scale_culmen_depth_mm' ) OPTIONS(model_type = 'TRANSFORM_ONLY') AS SELECT * FROM `statmike-mlops-349915.bqml.feature-engineering-source` WHERE split = 'TRAIN' For flipper_length_mm: CREATE OR REPLACE MODEL `statmike-mlops-349915.bqml.modular_preprocessing_scale_flipper_length_mm` TRANSFORM( * EXCEPT(flipper_length_mm), ML.STANDARD_SCALER(flipper_length_mm) OVER() AS flipper_length_mm, model_registry = 'VERTEX_AI', VERTEX_AI_MODEL_ID = 'bqml_modular_preprocessing_scale_flipper_length_mm' ) OPTIONS(model_type = 'TRANSFORM_ONLY') AS SELECT * FROM `statmike-mlops-349915.bqml.feature-engineering-source` WHERE split = 'TRAIN' |
现在,借助 CTE,特征管道可以像下面所示的一样简单,甚至可以打包为视图:
CREATE OR REPLACE VIEW `statmike-mlops-349915.bqml.feature-engineering-preprocessing` AS WITH raw AS ( SELECT * FROM `statmike-mlops-349915.bqml.feature-engineering-source` ), impute AS ( SELECT * FROM ML.TRANSFORM( MODEL `statmike-mlops-349915.bqml.modular_preprocessing_impute`, (SELECT * FROM raw) ) ), feature_1 AS ( SELECT * FROM ML.TRANSFORM( MODEL `statmike-mlops-349915.bqml.modular_preprocessing_scale_body_mass_g`, (SELECT * FROM impute) ) ), feature_2 AS ( SELECT * FROM ML.TRANSFORM( MODEL `statmike-mlops-349915.bqml.modular_preprocessing_scale_culmen_length_mm`, (SELECT * FROM feature_1) ) ), feature_3 AS ( SELECT * FROM ML.TRANSFORM( MODEL `statmike-mlops-349915.bqml.modular_preprocessing_scale_culmen_depth_mm`, (SELECT * FROM feature_2) ) ), feature_4 AS ( SELECT * FROM ML.TRANSFORM( MODEL `statmike-mlops-349915.bqml.modular_preprocessing_scale_flipper_length_mm`, (SELECT * FROM feature_3) ) ) SELECT * FROM feature_4 |
使用此模块化特征管道从上面创建原始模型将如下所示,直接从作为上面的视图创建的特征预处理管道中进行选择:
CREATE OR REPLACE MODEL `statmike-mlops-349915.bqml.modular_preprocessing` OPTIONS( model_type = 'BOOSTED_TREE_CLASSIFIER', input_label_cols = ['species'], data_split_method = 'CUSTOM', data_split_col = 'split', model_registry = 'VERTEX_AI', VERTEX_AI_MODEL_ID = 'bqml_modular_preprocessing' ) AS SELECT * EXCEPT(split), CASE WHEN split = 'TRAIN' THEN FALSE ELSE TRUE END AS split FROM `statmike-mlops-349915.bqml.feature-engineering-preprocessing |
这种级别的模块化和可复用性将 MLOps 的活动带入熟悉的 SQL 语法和流程中。
但有时需要在数据仓库之外使用模型,例如在线预测或边缘应用程序。请注意上面的模型是如何使用 VERTEX_AI_MODEL_ID 参数创建的。这意味着它们已自动在 Vertex AI Model Registry 中注册,距离部署到 Vertex AI 预测端点仅有一步之遥。此外,与其他 BigQuery ML 模型一样,可以使用 EXPORT MODEL 语句将这些模型导出到 Cloud Storage,以实现完全的可移植性。
总结
BigQuery ML 的新可复用和模块化功能工程是强大的工具,可以让您更轻松地构建和维护 ML 管道并增强 MLOps。通过模块化预处理,您可以创建仅转换模型,这些模型也可以在其他模型中复用,甚至可以导出到 Vertex AI。这种模块化也可以直接在 SQL 中启用特征管道。通过这种方式不仅可以节省您的时间、提高准确性、防止训练/服务偏差,同时也能够简化维护。要详细了解如何使用 BigQuery 进行特征工程,请尝试教程并阅读有关如何使用 BigQuery ML 进行特征工程的更多信息。
文章信息
相关推荐
