簡體   English   中英

繼承過程中如何避免init中的代碼重復? 擴展 xgb.XGBClassifier 來處理特征名稱

[英]How to avoid code duplication in init during inheritance? Extending xgb.XGBClassifier to handle feature names

我有擴展xgb.XGBClassifier類的具體問題,但它可以被定義為一般的 OOP 問題。

我的實現基於: https : //github.com/dmlc/xgboost/blob/master/python-package/xgboost/sklearn.py

基本上,當提供的數據在 Pandas 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_))

我試過只使用 **kwargs 但它不起作用。

“不起作用”是對問題最無用的可能描述。 相反,您應該准確記錄所有相關細節發生的情況。

話雖如此,如果您的問題是“我如何避免重新輸入完​​整的父方法簽名等”,那么您實際上與**kwargs非常接近,只是缺少位置參數部分*args

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

請注意,這會使簽名無法用於檢查(pydoc、內置help()函數、IDE 自動完成等)。

編輯:實際上,可能有一種方法 - 至少,根據這個答案functools.wraps()保留裝飾函數的簽名。 還有提供相同服務的Michele Simionato 的“裝飾器”庫,因此您應該能夠重用此代碼來獲得蛋糕並吃掉它!-)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM