在 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 进行特征工程的更多信息

相关推荐