![](/img/trans.png)
[英]What is the difference between xgb.train and xgb.XGBRegressor (or 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.