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

粒子物理XGBoost BDT二分类:损失函数修改及标准函数咨询

问题描述

我从事粒子物理领域工作,正在训练BDT用于信号/背景的二分类任务,模型的Python实现代码如下:

import xgboost as xgb
train = xgb.DMatrix(data=train_df[features],label=train_df["label"],
                    missing="inf",feature_names=features,weight=(np.array(train_df['label'].array)*-0.99+1))
test = xgb.DMatrix(data=test_df[features],label=test_df["label"],
                   missing="inf",feature_names=features,weight=(np.array(test_df['label'].array)  *-0.99+1))

param = {}


# Booster parameters
param['eta']              = 0.1 # learning rate
param['max_depth']        = 10  # maximum depth of a tree
param['subsample']        = 0.5 # fraction of events to train tree on
param['colsample_bytree'] = 0.5 # fraction of features to train tree on

# Learning task parameters
param['objective']   = 'binary:logistic' # objective function
param['eval_metric'] = 'error'           # evaluation metric for cross validation
param = list(param.items()) + [('eval_metric', 'logloss')] + [('eval_metric', 'rmse')]


num_trees = 50  # number of trees to make
booster = xgb.train(param,train,num_boost_round=num_trees)

当前模型效果良好,但我希望略微修改损失函数,让假阳性受到比真阳性更严厉的惩罚。我希望得到一个背景事件尽可能少的筛选结果,即便这意味着要牺牲大量信号事件。

我已查阅XGBoost官方文档中关于自定义目标与评估函数的内容,且已成功添加文档中的示例案例。

请问我当前模型中已使用的标准目标函数和评估函数有哪些?由于模型当前表现已不错,我只想在已实现的函数基础上添加额外项。

以下是我使用的软件包版本供参考:

python version: 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0]
XGBoost version: 2.0.2
Pandas version: 2.1.4
Numpy version: 1.26.2
解答

一、当前使用的标准目标与评估函数

目标函数

你当前用的是XGBoost内置的**binary:logistic**目标函数,这是二分类任务通用的逻辑斯蒂回归损失函数,损失表达式为:
$$L = -\sum_{i=1}^n \left[ y_i \log(p_i) + (1-y_i) \log(1-p_i) \right]$$
其中$y_i$是样本真实标签(1为信号,0为背景),$p_i$是模型预测样本为信号的概率。

评估函数

你在参数里指定了三个内置评估函数:

  • error:二分类错误率,统计分类错误的样本占总样本的比例;
  • logloss:逻辑斯蒂损失值,计算逻辑与目标函数一致;
  • rmse:均方根误差,衡量预测概率和真实标签之间的均方偏差。

这些指标会在训练过程中实时输出,用来监控模型训练状态。

二、修改损失函数加重假阳性惩罚

你的核心需求是尽可能减少背景事件(即假阳性:模型将背景样本预测为信号,对应$y_i=0$但$p_i$趋近于1的情况),可以在原binary:logistic损失基础上,给假阳性对应的损失项添加权重系数,实现差异化惩罚。

自定义目标函数实现

我们可以基于原逻辑斯蒂损失,给背景样本($y_i=0$)的损失项乘以一个大于1的权重$\alpha$($\alpha$值越大,对假阳性的惩罚力度越强),修改后的损失表达式为:
$$L = -\sum_{i=1}^n \left[ y_i \log(p_i) + \alpha(1-y_i) \log(1-p_i) \right]$$

对应代码修改如下(保留你原有代码的核心逻辑):

import xgboost as xgb
import numpy as np

# 自定义加权逻辑斯蒂损失函数
def weighted_logistic_obj(preds, dtrain):
    labels = dtrain.get_label()
    # 假阳性惩罚权重,可根据需求调整,示例设为5
    alpha = 5.0
    # 计算逻辑斯蒂损失的一阶导数(梯度)和二阶导数(海森矩阵)
    preds = 1.0 / (1.0 + np.exp(-preds))
    grad = preds - labels
    hess = preds * (1.0 - preds)
    # 对背景样本(label=0)的梯度和海森矩阵乘以惩罚权重
    grad = np.where(labels == 0, grad * alpha, grad)
    hess = np.where(labels == 0, hess * alpha, hess)
    return grad, hess

# 原有数据准备代码保持不变
train = xgb.DMatrix(data=train_df[features],label=train_df["label"],
                    missing="inf",feature_names=features,weight=(np.array(train_df['label'].array)*-0.99+1))
test = xgb.DMatrix(data=test_df[features],label=test_df["label"],
                   missing="inf",feature_names=features,weight=(np.array(test_df['label'].array)  *-0.99+1))

param = {}
# Booster参数保留原有设置
param['eta']              = 0.1
param['max_depth']        = 10
param['subsample']        = 0.5
param['colsample_bytree'] = 0.5
# 移除原objective参数,改用自定义目标;评估函数保留原有三个
param['eval_metric'] = ['error', 'logloss', 'rmse']

num_trees = 50
# 训练时指定自定义目标函数
booster = xgb.train(param, train, num_boost_round=num_trees, obj=weighted_logistic_obj)

调整建议

  1. 权重$\alpha$需要根据实际任务需求调试:如果想要更严格过滤背景,可以逐步增大$\alpha$(比如从2到10);
  2. 训练过程中建议结合PR曲线(精确率-召回率曲线)评估效果,重点关注高背景过滤能力下的信号保留情况;
  3. 你原有代码中已经给背景样本设置了更高的样本权重(label=0时权重为1,label=1时为0.01),自定义损失的权重是在这个基础上进一步加强惩罚,两者可以配合使用,达到更精准的效果。

内容的提问来源于stack exchange,提问作者Rodrigo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 18:26:00