python - 继承过程中如何避免init中的代码重复?扩展 xgb.XGBClassifier 以处理特征名称
问题描述
我对扩展类有具体的问题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 部分*args
:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.feature_names = None
请注意,这会使签名对检查无用(pydoc、内置help()
函数、IDE 自动完成等)。
编辑:实际上,可能有一种方法 - 至少,根据这个答案,可以functools.wraps()
保留装饰函数的签名。还有提供相同服务的Michele Simionato 的“装饰器”库,因此您应该能够重用此代码来获得您的蛋糕并吃掉它!-)
推荐阅读
- javascript - 使用jQuery选择具有特定类的元素的正确方法是什么
- swift - tvOS UIImageView 焦点阴影被剪裁
- php - 如何在 wordpress 的 metaslider 中添加联系表格 7,我想在图像为幻灯片时显示不同的表格
- asp.net-mvc - LINQ:具有最大值的列表
- node.js - 使用 Mongoose 将项目推送到对象中的数组
- java - 如何将 RadioGroup 和 EditText 添加到 AlertDialog?
- macos - 使用 Scapy 从 Mac OSX 上的数据包中获取信号强度
- c# - 无法通过 ASP.NET Web 应用程序将数据插入 MySQL 表
- python-3.x - Matplotlib 打开但没有响应
- python - 存储为 DataFrame 时 python cx_oracle 挂起?