如何在继承期间避免init中的代码重复?扩展xgb.XGBClassifier以处理要素名称

2024-10-03 19:20:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我对扩展xgb.XGBClassifier类有具体的问题,但它可以被定义为一般的OOP问题

我的实现基于:https://github.com/dmlc/xgboost/blob/master/python-package/xgboost/sklearn.py

基本上,当提供的数据在DataFrame中时,我希望添加特性名称处理

几句话:

  • XGBClassifierN__init__中具有与基类xgb.XGBClassifier相同的参数
  • 还有一个附加属性self.feature_names,由后面的fit方法设置
  • 其余的可以通过混合来完成

它起作用了

困扰我的是__init__中的这堵代码墙。它是通过复制粘贴默认值完成的,每次xgb.Classifier将更改时,它都必须更新

有没有什么方法可以简明扼要地表达这样的想法:子类XGBClassifierN与父类xgb.XGBClassifier具有相同的参数和默认值,然后再执行类似clf = XGBClassifierN(n_jobs=-1)的操作

我试着只使用**kwargs,但没有成功(解释器开始抱怨没有missing参数(没有双关语),为了使它工作,基本上你需要设置更多的参数)

import xgboost as xgb

class XGBClassifierN(xgb.XGBClassifier):
    def __init__(self, base_score=0.5, booster='gbtree', colsample_bylevel=1,
              colsample_bynode=1, colsample_bytree=1, gamma=0,
              learning_rate=0.1, max_delta_step=0, max_depth=3,
              min_child_weight=1, missing=None, n_estimators=100, n_jobs=1,
              nthread=None, objective='binary:logistic', random_state=0,
              reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=None,
              silent=None, subsample=1, verbosity=1, **kwargs): 
        super().__init__(base_score=base_score, booster=booster, colsample_bylevel=colsample_bylevel,
              colsample_bynode=colsample_bynode, colsample_bytree=colsample_bytree, gamma=gamma,
              learning_rate=learning_rate, max_delta_step=max_delta_step, max_depth=max_depth,
              min_child_weight=min_child_weight, missing=missing, n_estimators=n_estimators, n_jobs=n_jobs,
              nthread=nthread, objective=objective, random_state=random_state,
              reg_alpha=reg_alpha, reg_lambda=reg_lambda, scale_pos_weight=scale_pos_weight, seed=seed,
              silent=silent, subsample=subsample, verbosity=verbosity, **kwargs)
        self.feature_names = None

    def fit(self, X, y=None):
        self.feature_names = list(X.columns)
        return super().fit(X, y)

    def get_feature_names(self):
        if not isinstance(self.feature_names, list):
            raise ValueError('Must fit data first!')
        else:
            return self.feature_names

    def get_feature_importances(self):
        return dict(zip(self.get_feature_names(), self.feature_importances_))

Tags: selfnone参数namesinitjobsregmax
1条回答
网友
1楼 · 发布于 2024-10-03 19:20:15

I've tried to use only **kwargs but it doesn't work out.

“不起作用”是对问题最无用的描述。相反,您应该准确地记录发生了什么,以及所有相关的细节

话虽如此,如果您的问题是“如何避免重新键入完整的父方法签名等”,那么实际上您与**kwargs非常接近,只是缺少位置参数部分*args

def __init__(self, *args, **kwargs): 
    super().__init__(*args, **kwargs)
    self.feature_names = None

请注意,这使得签名对检查毫无用处(pydoc、内置函数、IDE自动完成等)

编辑:实际上,可能有一种方法-至少,根据this answerfunctools.wraps()可以保留修饰函数的签名。还有Michele Simionato's "decorator" lib提供了相同的服务,因此您应该能够重用此代码,既能吃蛋糕又能吃蛋糕

相关问题 更多 >