本文介紹如何使用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引擎中進行推理,可以得到一致的預測結果。