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

Pipeline中XGBoostClassifier多分类任务class_weight的正确使用方法

如何在Pipeline中为XGBoost多分类任务配置类别权重

报错原因

你看到的警告是两个错误用法共同导致的:

  • XGBoost官方原生的XGBClassifier没有内置class_weight参数,该参数是Scikit-learn部分模型的专属入参,直接传入XGBoost构造函数会被识别为无效参数。
  • sample_weight是模型fit()方法的入参,不属于模型初始化阶段的配置参数,写在构造函数中无法被XGBoost核心逻辑识别。

正确实现方案

方案1:通过Pipeline的fit_params传参(最简便)

Pipeline的fit方法支持传入步骤名__参数名格式的参数,给指定步骤的fit方法传值,你只需要提前算好样本权重,在调用fit时传入即可:

import numpy as np
from sklearn.utils import class_weight
from sklearn.pipeline import Pipeline
from xgboost import XGBClassifier

# 1. 计算训练集每个样本对应的权重
classes_weights = class_weight.compute_class_weight(
    'balanced',
    classes=np.unique(y_train),
    y=y_train
)
sample_weights = np.array([classes_weights[y] for y in y_train])

# 2. 构造Pipeline,XGB构造函数不需要传class_weight、sample_weight参数
pipe = Pipeline([
    # 此处补充你的预处理步骤,例如标准化、特征选择等
    ('clf', XGBClassifier(n_jobs=-1, objective='multi:softprob'))
])

# 3. 调用fit时通过双下划线格式传入样本权重
pipe.fit(X_train, y_train, clf__sample_weight=sample_weights)

如果配合GridSearchCV等交叉验证工具使用,同样可以把该参数传入搜索类的fit方法:

from sklearn.model_selection import GridSearchCV

params = {'clf__max_depth': [3,5,7]}
grid = GridSearchCV(pipe, params, cv=5)
grid.fit(X_train, y_train, clf__sample_weight=sample_weights)

方案2:自定义封装支持class_weight的XGB类(高复用性)

如果你希望和Scikit-learn其他模型一样,直接传入class_weight='balanced'即可自动处理权重,可以自定义一个继承XGBClassifier的扩展类:

from xgboost import XGBClassifier
from sklearn.utils.class_weight import compute_class_weight
import numpy as np

class XGBClassifierWeighted(XGBClassifier):
    def __init__(self, class_weight=None, **kwargs):
        self.class_weight = class_weight
        super().__init__(**kwargs)
    
    def fit(self, X, y, sample_weight=None, **kwargs):
        if self.class_weight == 'balanced' and sample_weight is None:
            # 自动基于当前传入的训练集标签计算权重
            classes = np.unique(y)
            classes_weights = compute_class_weight('balanced', classes=classes, y=y)
            sample_weight = np.array([classes_weights[np.where(classes == label)[0][0]] for label in y])
        return super().fit(X, y, sample_weight=sample_weight, **kwargs)

使用时直接在Pipeline中初始化该自定义类即可,不需要手动计算权重:

pipe = Pipeline([
    # 预处理步骤
    ('clf', XGBClassifierWeighted(class_weight='balanced', n_jobs=-1, objective='multi:softprob'))
])
pipe.fit(X_train, y_train)

注意事项

如果使用K折交叉验证,不要基于全量数据集的标签计算样本权重,应该基于每个训练折的标签单独计算,避免数据泄露,这种场景更推荐使用自定义封装类,会自动在每个fit阶段基于当前传入的y计算权重。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 19:06:09