You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XGBoost自定义目标函数:如何动态调整样本权重?

解决XGBoost自定义目标中动态更新Top样本权重的问题

你的核心问题是当前自定义目标里的权重仅在单次梯度计算中生效,无法传递到下一棵树的训练中。XGBoost的自定义目标函数本身不支持直接获取或更新训练过程中的样本权重,但可以通过**回调函数(Callback)**实现动态权重更新,每轮迭代后根据当前预测结果重新调整Top样本的权重。

核心思路

  1. 用类属性存储样本权重,让自定义目标函数可以访问它;
  2. 定义回调函数,在每棵树训练完成后,用当前模型的预测结果重新筛选Top3000样本,更新权重;
  3. 训练时将回调函数传入,确保每轮迭代都使用最新的权重计算梯度。

实现代码(类封装版,避免全局变量)

import numpy as np
import xgboost as xgb

class TopSampleWeightUpdater:
    def __init__(self, top_x=3000):
        self.top_x = top_x
        self.sample_weights = None

    def custom_objective(self, y_true, y_pred):
        # 转换为概率
        pred_probs = 1.0 / (1.0 + np.exp(-y_pred))
        
        # 你的逻辑回归梯度与海森矩阵计算
        grad = (pred_probs - y_true) / (pred_probs * (1 - pred_probs))
        hess = (2 * pred_probs**2 - 3 * pred_probs + 1 + y_true - 2 * y_true * pred_probs) / (pred_probs * (1 - pred_probs))**2
        
        # 用动态更新的权重缩放梯度和海森矩阵
        return grad * self.sample_weights, hess * self.sample_weights

    def update_weights(self, model):
        # 获取当前模型对训练集的logit预测值
        y_pred_logit = model.predict(model.dtrain)
        pred_probs = 1.0 / (1.0 + np.exp(-y_pred_logit))
        
        # 筛选Top X样本的索引
        top_x_indices = np.argsort(pred_probs)[-self.top_x:]
        
        # 更新权重:重置为1,Top样本设为10
        self.sample_weights = np.ones_like(pred_probs)
        self.sample_weights[top_x_indices] = 10

# ---------------------- 使用示例 ----------------------
# 假设你已经有训练数据X_train和y_train
weight_updater = TopSampleWeightUpdater(top_x=3000)
weight_updater.sample_weights = np.ones(len(y_train))

# 构建DMatrix,传入初始权重
dtrain = xgb.DMatrix(X_train, label=y_train, weight=weight_updater.sample_weights)

# XGBoost参数设置
params = {
    'objective': weight_updater.custom_objective,  # 指定自定义目标函数
    'eval_metric': 'logloss',
    'tree_method': 'hist',
    'learning_rate': 0.1,
    'seed': 42
}

# 训练模型,传入回调函数
model = xgb.train(
    params,
    dtrain,
    num_boost_round=100,
    callbacks=[weight_updater.update_weights]
)

关键说明

  • 回调函数update_weights会在每棵树训练完成后执行,基于当前模型的预测结果重新确定Top3000样本,更新权重数组;
  • 自定义目标函数直接使用更新后的权重计算梯度,确保每棵树的训练都聚焦于最新的Top样本;
  • 用类封装权重和回调函数可以避免全局变量的副作用,代码更易维护。

注意事项

  • 动态加权可能增加过拟合风险,建议加入验证集监控eval_metric的变化,必要时提前停止训练;
  • 如果你的初始样本已经有自定义权重,可以修改update_weights方法,将Top样本的权重设为原权重×10而非直接设为10。

内容的提问来源于stack exchange,提问作者Gábor B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 06:14:52