使用MaxCompute进行XGboost模型训练和预测

本文介绍如何使用MaxCompute进行XGboost模型训练并使用训练好的模型进行数据预测。

先导概念

XGBoost(Extreme Gradient Boosting)是一种基于梯度提升框架的集成学习算法,通过迭代构建决策树模型,利用二阶导数优化目标函数并逐步修正预测误差,专注于提升结构化数据分类和回归任务的精度,其核心思想是通过加法模型(Additive Model)结合多棵决策树的预测结果,以迭代方式最小化损失函数,最终实现对复杂非线性关系的高效建模。

适用范围

本场景示例包含MaxFrame引擎升级特性,目前正在邀测阶段,本文中示例代码仅为参考示意。如需实际体验,可提交工单。

方案优势

在真实生产业务中,经常存在跨团队协同的情况。算法团队在训练模型时通常希望使用更熟悉的python编程语言,而业务分析团队则更倾向于使用SQL语言进行数据分析。MaxCompute支持MaxFrame引擎和SQL引擎使用同一个模型对象,有助于降低用户在跨语言和技术栈协作场景的对接成本,方便用户更灵活的使用MaxComputeAI能力为业务分析服务。

数据集介绍

本案例使用经典波士顿房价样例数据集,反映了1970年代波士顿地区住房情况。训练数据包含500条样本,包含12个特征和1个目标变量;待预测数据有6条,包含与训练集完全一致的12个特征。

数据集字段详细说明如下:

NO.

字段名

类型

含义

描述

1

CRIM

Float

城镇人均犯罪率

该字段表示每个城镇的人均犯罪率,通常认为犯罪率较高的地区房价相对较低。

2

ZN

Float

占地面积>2.5万平方英尺的住宅用地比例

这个字段表示在城镇中,占地面积大于2.5万平方英尺的住宅用地所占的比例。

3

INDUS

Float

城镇非零售业务用地比例

该字段代表城镇中用于非零售业务的土地比例,如工厂、仓库等。

4

CHAS

Integer

是否临河(1=是,0=否)

这是一个二元字段,用于指示该区域是否紧邻查尔斯河。

5

NOX

Float

一氧化氮浓度(ppm)

该字段表示空气中的一氧化氮浓度,通常以百万分之一(ppm)为单位。

6

RM

Float

住宅平均房间数

这个字段代表住宅中的平均房间数量,通常认为房间数较多的住宅价格更高。

7

AGE

Float

1940年前建成自住单位比例

该字段表示在1940年之前建成的自住房屋所占的比例。

8

DIS

Float

距离五大就业中心的加权距离

这个字段表示到五个波士顿主要就业中心的加权距离,通常距离较近的区域房价较高。

9

RAD

Integer

高速路通达指数

该字段表示高速公路的可达性指数,指数越高表示通达性越好。

10

TAX

Float

每万美元房产税率

这个字段表示每万美元房产需要缴纳的税额,税率较高的地区可能会对房价产生负面影响。

11

PTRATIO

Float

城镇师生比例

该字段表示城镇中的公立学校学生与教师比例,比例较高的地区可能意味着教育资源相对紧张。

12

LSTAT

Float

低收入人群比例

该字段表示低收入人群在总人口中所占的比例,低收入人群比例较高的地区房价通常较低。

13

MEDV

Float

业主自住房中位数价格(单位:千美元)

目标变量:表示该区域业主自住房的中位数价格,单位是千美元。这是模型需要预测的值。

环境准备

数据准备

  1. 创建所需的表并写入数据:

    -- 创建训练数据表
    CREATE TABLE IF NOT EXISTS demo_xgboost_train
    (
     CRIM         FLOAT comment '城镇人均犯罪率',
     ZN           FLOAT comment '占地面积大于2.5万平方英尺的住宅用地比例',
     INDUS        FLOAT comment '城镇非零售业务用地比例',
     CHAS         INT   comment '是否临河1=是0=否',
     NOX          FLOAT comment '一氧化氮浓度ppm',
     RM           FLOAT comment '住宅平均房间数',
     AGE          FLOAT comment '1940年前建成自住单位比例',
     DIS          FLOAT comment '距离五大就业中心的加权距离',
     RAD          FLOAT comment '高速路通达指数',
     TAX          FLOAT comment '每万美元房产税率',
     PTRATIO      FLOAT comment '城镇师生比例',
     LSTAT        FLOAT comment '低收入人群比例',
     MEDV         FLOAT comment '业主自住房中位数价格,单位千美元'
    );
    
    -- 创建SQLMaxFrame所需的预测数据表
    CREATE TABLE IF NOT EXISTS demo_xgboost_predict
    (
     CRIM         FLOAT comment '城镇人均犯罪率',
     ZN           FLOAT comment '占地面积大于2.5万平方英尺的住宅用地比例',
     INDUS        FLOAT comment '城镇非零售业务用地比例',
     CHAS         INT   comment '是否临河1=是0=否',
     NOX          FLOAT comment '一氧化氮浓度ppm',
     RM           FLOAT comment '住宅平均房间数',
     AGE          FLOAT comment '1940年前建成自住单位比例',
     DIS          FLOAT comment '距离五大就业中心的加权距离',
     RAD          FLOAT comment '高速路通达指数',
     TAX          FLOAT comment '每万美元房产税率',
     PTRATIO      FLOAT comment '城镇师生比例',
     LSTAT        FLOAT comment '低收入人群比例'
    );
    
    
    
    -- 创建MaxFrame预测数据表。
    CREATE TABLE IF NOT EXISTS demo_xgboost_predict_result
    (
     CRIM         DOUBLE comment '城镇人均犯罪率',
     ZN           DOUBLE comment '占地面积大于2.5万平方英尺的住宅用地比例',
     INDUS        DOUBLE comment '城镇非零售业务用地比例',
     CHAS         BIGINT comment '是否临河1=是0=否',
     NOX          DOUBLE comment '一氧化氮浓度ppm',
     RM           DOUBLE comment '住宅平均房间数',
     AGE          DOUBLE comment '1940年前建成自住单位比例',
     DIS          DOUBLE comment '距离五大就业中心的加权距离',
     RAD          DOUBLE comment '高速路通达指数',
     TAX          DOUBLE comment '每万美元房产税率',
     PTRATIO      DOUBLE comment '城镇师生比例',
     LSTAT        DOUBLE comment '低收入人群比例',
     RESULT       DOUBLE comment '业主自住房预测结果'
    );
  2. 通过Tunnel API上传数据:

    xgboost_train_data.csv

    xgboost_predict.csv

    TUNNEL UPLOAD xgboost_train_data.csv demo_xgboost_train;
    TUNNEL UPLOAD xgboost_predict.csv demo_xgboost_predict;

模型训练与保存

  1. 使用MaxFrame训练Xgboost回归模型。

    ## 会话初始化
    from odps import ODPS
    import maxframe
    from maxframe import options
    
    o = ODPS('LT******************',
             'Cz************************',
             'project_name',
             'endpoint',
            )
    
    ## 参数配置
    from maxframe.config import options
    options.sql.enable_mcqa = False
    # 使用 DPE 引擎 "DPE", 
    options.dag.settings = {
        "engine_order" : ["DPE", "MCSQL", "SPE"]
    }
    options.dpe.settings = {
        "odps.catalog_api_endpoint": "catalog_api_endpoint",
    }
    options.sql.settings = {
        "odps.session.image": "common",
    }
    options.service_role_arn =  "acs:ram::13933481********:role/aliyunodpsdefaultrole"
    options.object_cache_url = "oss://oss-cn-beijing-internal.aliyuncs.com/models-*******/mfdemo"
    
    sess = maxframe.new_session(o)  
    print(sess.get_logview_address())
    
    ## 模型训练和生成
    import numpy as np
    from sklearn.datasets import make_classification
    import maxframe.dataframe as md, maxframe.tensor as mt
    from maxframe.learn.contrib.xgboost import XGBRegressor
    
    # 定义表名和字段
    table_name = "demo_xgboost_train"
    # 特征列和标签列
    features = ['crim', 'zn', 'indus', 'chas', 'nox', 'rm', 'age', 'dis', 'rad', 'tax', 'ptratio', 'lstat']
    label = 'medv'
    # 读取训练数据
    df = md.read_odps_table(
        table_name,
        unknown_as_string=True  # 防止非结构化数据报错
    )
    # 特征和标签处理
    X_train = df[features].fillna(-1)  # 填充缺失值
    y_train = df[label]
    # 初始化并训练XGBoost回归模型
    model = XGBRegressor(
        n_estimators=300,
        learning_rate=0.1,
        colsample_bytree=0.8,
        n_jobs=-1,
        tree_method="hist",
        enable_categorical=True,
        objective='reg:squarederror'
    )
    # 保存生成的XGBoost回归模型
    model.fit(X_train, y_train).to_odps_model(
        model_name="demo_model_xgboost_regressor",
        model_version="v01",
    ).execute()
  2. 查看训练产生的模型。

    DESC model demo_model_xgboost_regressor;
    
    +------------------------------------------------------------------------------------+
    |                  Model Information                                                 |
    +------------------------------------------------------------------------------------+
    | Owner:                    ALIYUN$***********************                           |
    | Project:                  pd_test_model                                            |
    | Schema:                   default                                                  |
    | Model Name:               demo_model_xgboost_regressor                                   |
    | Model Type:               BOOSTED_TREE_REGRESSOR                                   |
    | Source Type:              INTERNAL_TRAIN                                           |
    | Default Version:          v01                                                      |
    | CreateTime:               2025-09-12 13:15:16                                      |
    | LastModifiedTime:         2025-09-12 13:15:16                                      |
    | Model ID:                 389c90e355264079923b89**********                         |
    +------------------------------------------------------------------------------------+
    |                Version Information                                                 |
    +------------------------------------------------------------------------------------+
    | Owner:                    ALIYUN$***********************                           |
    | Project:                  pd_test_model                                            |
    | Schema:                   default                                                  |
    | Model Name:               demo_model_xgboost_regressor                                    |
    | Model Type:               BOOSTED_TREE_REGRESSOR                                   |
    | Source Type:              INTERNAL_TRAIN                                           |
    | Version Name:             v01                                                      |
    | Version ID:               99acd6cb93f845c8a4a9977*********                         |
    | Path:                                                                              |
    | CreateTime:               2025-09-12 13:15:16                                      |
    | LastModifiedTime:         2025-09-12 13:15:16                                      |
    +------------------------------------------------------------------------------------+
    | Input           | Type       | Comment                                             |
    +------------------------------------------------------------------------------------+
    | crim            | float      |                                                     |
    | zn              | float      |                                                     |
    | indus           | float      |                                                     |
    | chas            | int        |                                                     |
    | nox             | float      |                                                     |
    | rm              | float      |                                                     |
    | age             | float      |                                                     |
    | dis             | float      |                                                     |
    | rad             | float      |                                                     |
    | tax             | float      |                                                     |
    | ptratio         | float      |                                                     |
    | lstat           | float      |                                                     |
    +------------------------------------------------------------------------------------+

使用MaxFrame进行数据预测

  1. 在训练模型的代码基础上,继续在MaxFrame中执行以下程序,即可使用训练的模型进行数据预测:

    #定义预测数据和结果表。
    predict_table = "demo_xgboost_predict_mf"
    predict_result_table = "demo_xgboost_predict_result"
    
    #读取预测数据。
    predict_data = md.read_odps_table(
        predict_table,
        unknown_as_string=True
    )
    X_predict = predict_data[features].fillna(-1)
    y_predict = model.predict(X_predict)
    
    # 构建预测结果 DataFrame。
    df_predict = predict_data[features].copy()  
    df_predict['predicted_medv'] = y_predict.astype(np.float64)  # 添加预测值
    
    # 输出预测结果到ODPS表。
    df_predict.to_odps_table(
        predict_result_table,
        overwrite=True,
        index=False,
        unknown_as_string=True
    ).execute()
  2. 查看预测结果表:

    SELECT * FROM demo_xgboost_predict_result limit 10;
    
    +------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+
    | crim       | zn         | indus      | chas       | nox        | rm         | age        | dis        | rad        | tax        | ptratio    | lstat      | result     | 
    +------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+
    | 0.22438    | 0.0        | 9.69       | 0          | 0.585      | 6.027      | 79.7       | 2.4982     | 6.0        | 391.0      | 19.2       | 14.33      | 20.03961181640625 | 
    | 0.06263    | 0.0        | 11.93      | 0          | 0.573      | 6.593      | 69.1       | 2.4786     | 1.0        | 273.0      | 21.0       | 9.67       | 24.491479873657227 | 
    | 0.04527    | 0.0        | 11.93      | 0          | 0.573      | 6.12       | 76.7       | 2.2875     | 1.0        | 273.0      | 21.0       | 9.08       | 24.683202743530273 | 
    | 0.06076    | 0.0        | 11.93      | 0          | 0.573      | 6.976      | 91.0       | 2.1675     | 1.0        | 273.0      | 21.0       | 5.64       | 32.33962631225586 | 
    | 0.10959    | 0.0        | 11.93      | 0          | 0.573      | 6.794      | 89.3       | 2.3889     | 1.0        | 273.0      | 21.0       | 6.48       | 28.45917510986328 | 
    | 0.04741    | 0.0        | 11.93      | 0          | 0.573      | 6.03       | 80.8       | 2.505      | 1.0        | 273.0      | 21.0       | 7.88       | 24.43267822265625 | 
    +------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+------------+

使用SQL AI Function进行预测

使用构建的模型和SQL ML_PREDICT函数进行房价预测。

SET odps.sql.type.system.odps2=true;
SET odps.task.major.version=sqlml_master;
SET odps.sql.machine.learning.enable=true;

SELECT ML_PREDICT(demo_model_xgboost_regressor,v01,crim,zn,indus,chas,nox,rm,age,dis,rad,tax,ptratio,lstat)
FROM demo_xgboost_predict;

-- 执行结果如下:
+------------+
| _c0        | 
+------------+
| 20.039612  | 
| 24.49148   | 
| 24.683203  | 
| 32.339626  | 
| 28.459175  | 
| 24.432678  | 
+------------+

当使用相同的模型和预测数据时,无论在MaxFrame引擎还是SQL引擎中进行推理,可以得到一致的预测结果。