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

如何在XGBoost每次提升迭代中修改数据集特征?(附论文复现场景)

回答:当然可以用XGBoost Python API实现迭代间的DMatrix特征更新

没问题!你要复现的这个特征迭代增强+基学习器堆叠的逻辑,完全可以通过XGBoost的Python API配合常规的数据处理操作实现——核心思路是每次迭代都基于更新后的特征矩阵重新构建DMatrix,因为DMatrix本身是基于输入数据(numpy数组/pandas DataFrame)创建的,只要你的特征数据更新了,重新生成DMatrix就相当于完成了特征的添加。

下面我结合你的算法步骤,给你一套可落地的代码思路和细节说明:


1. 初始训练与特征重要性提取

首先用初始数据集训练第一个XGBoost基学习器,然后提取特征重要性(你提到的「f-score(分裂次数)」对应XGBoost里的weight类型,即特征被用于分裂的次数):

import xgboost as xgb
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split

# 假设你的初始数据集是df,标签列是'y'
X_train, X_val, y_train, y_val = train_test_split(df.drop('y', axis=1), df['y'], test_size=0.2)

# 初始DMatrix
dtrain = xgb.DMatrix(X_train, label=y_train)
dval = xgb.DMatrix(X_val, label=y_val)

# 训练初始基学习器
params = {'objective': 'binary:logistic', 'eval_metric': 'auc', 'seed': 42}
model = xgb.train(params, dtrain, num_boost_round=100, evals=[(dval, 'val')])

# 提取特征重要性(分裂次数)
feature_importance = model.get_booster().get_score(importance_type='weight')
total_splits = sum(feature_importance.values())

2. 筛选重要特征

根据你设定的阈值(比如占总分裂次数的5%),过滤掉不重要的特征:

# 计算每个特征的分裂占比,筛选占比≥5%的特征
threshold = 0.05
important_features = [
    feat for feat, cnt in feature_importance.items()
    if cnt / total_splits >= threshold
]

# 保留重要特征的数据集
X_important = X_train[important_features]
X_val_important = X_val[important_features]

3. 构建特征采样概率分布

基于剩余特征的分裂次数,归一化得到采样概率:

feat_counts = [feature_importance[feat] for feat in important_features]
sampling_probs = np.array(feat_counts) / sum(feat_counts)

4. 生成新特征

可放回采样两个特征,执行随机数学运算,重复若干次生成新特征:

def generate_new_features(X, features, probs, num_new_feats=10):
    new_features = pd.DataFrame()
    for i in range(num_new_feats):
        # 可放回采样两个特征
        feat1, feat2 = np.random.choice(features, size=2, replace=True, p=probs)
        # 随机选择运算
        op = np.random.choice(['add', 'sub', 'mul', 'div'])
        if op == 'add':
            new_feat = X[feat1] + X[feat2]
        elif op == 'sub':
            new_feat = X[feat1] - X[feat2]
        elif op == 'mul':
            new_feat = X[feat1] * X[feat2]
        elif op == 'div':
            # 避免除以0,加一个极小值
            new_feat = X[feat1] / (X[feat2] + 1e-8)
        new_features[f'{feat1}_{op}_{feat2}_{i}'] = new_feat
    return new_features

# 生成训练集和验证集的新特征
X_new_train = generate_new_features(X_important, important_features, sampling_probs)
X_new_val = generate_new_features(X_val_important, important_features, sampling_probs)

5. 拼接特征并构建新的DMatrix

把保留的重要特征和新生成的特征拼接,然后创建新一轮的DMatrix:

# 拼接特征
X_train_next = pd.concat([X_important, X_new_train], axis=1)
X_val_next = pd.concat([X_val_important, X_new_val], axis=1)

# 构建新的DMatrix
dtrain_next = xgb.DMatrix(X_train_next, label=y_train)
dval_next = xgb.DMatrix(X_val_next, label=y_val)

6. 训练下一个基学习器

用新的DMatrix训练下一个XGBoost模型,然后重复整个迭代流程即可:

# 训练下一个基学习器
model_next = xgb.train(params, dtrain_next, num_boost_round=100, evals=[(dval_next, 'val')])

# 接下来可以重复步骤2-6:提取model_next的特征重要性,筛选,生成新特征...

关键注意点

  • DMatrix本身是不可变对象,不能直接修改已有的DMatrix添加特征,但我们可以通过拼接特征后重新创建DMatrix的方式,实现迭代间的特征更新——这也是最简洁高效的做法。
  • 每次迭代的特征重要性是基于当前基学习器的,所以筛选的重要特征会随着迭代动态变化,符合你论文里的逻辑。
  • 生成新特征时,除法要注意避免除以0的情况,建议加一个极小的epsilon(比如1e-8)来防止报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:53:44