本文介绍如何使用MaxCompute进行XGboost模型训练并使用训练好的模型进行数据预测。
先导概念
XGBoost(Extreme Gradient Boosting)是一种基于梯度提升框架的集成学习算法,通过迭代构建决策树模型,利用二阶导数优化目标函数并逐步修正预测误差,专注于提升结构化数据分类和回归任务的精度,其核心思想是通过加法模型(Additive Model)结合多棵决策树的预测结果,以迭代方式最小化损失函数,最终实现对复杂非线性关系的高效建模。
适用范围
本场景示例包含MaxFrame引擎升级特性,目前正在邀测阶段,本文中示例代码仅为参考示意。如需实际体验,可提交工单。
方案优势
在真实生产业务中,经常存在跨团队协同的情况。算法团队在训练模型时通常希望使用更熟悉的python编程语言,而业务分析团队则更倾向于使用SQL语言进行数据分析。MaxCompute支持MaxFrame引擎和SQL引擎使用同一个模型对象,有助于降低用户在跨语言和技术栈协作场景的对接成本,方便用户更灵活的使用MaxCompute的AI能力为业务分析服务。
数据集介绍
本案例使用经典波士顿房价样例数据集,反映了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 | 业主自住房中位数价格(单位:千美元) | 目标变量:表示该区域业主自住房的中位数价格,单位是千美元。这是模型需要预测的值。 |
环境准备
开通MaxCompute服务并创建MaxCompute项目,且项目已开启Schema语法开关;如已完成可跳过此步骤。
确保本地Python开发环境中已安装MaxFrame最新版本、scikit-learn和xgboost包。详情请参见在本地环境中使用MaxFrame。
数据准备
创建所需的表并写入数据:
-- 创建训练数据表 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 '业主自住房中位数价格,单位千美元' ); -- 创建SQL和MaxFrame所需的预测数据表 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 '业主自住房预测结果' );通过Tunnel API上传数据:
TUNNEL UPLOAD xgboost_train_data.csv demo_xgboost_train; TUNNEL UPLOAD xgboost_predict.csv demo_xgboost_predict;
模型训练与保存
使用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()查看训练产生的模型。
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进行数据预测
在训练模型的代码基础上,继续在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()查看预测结果表:
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引擎中进行推理,可以得到一致的预测结果。