我正在尝试定义一个名为XGBExtended
的类,该类扩展了 xgboost.XGBClassifier
类,xgboost的scikit-learn api。我遇到了get_params
方法的一些问题。以下是一个iPython会话,说明了这个问题。基本上,get_params
似乎仅返回我在XGBExtended.__init__
中定义的属性,而在父启动方法(xgboost.XGBClassifier.__init__
)期间定义的属性被忽略。我正在使用ipython并运行Python 2.7。完整的系统规格在底部。
In [182]: import xgboost as xgb
...:
...: class XGBExtended(xgb.XGBClassifier):
...: def __init__(self, foo):
...: super(XGBExtended, self).__init__()
...: self.foo = foo
...:
...: clf = XGBExtended(foo = 1)
...:
...: clf.get_params()
...:
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-182-431c4c3f334b> in <module>()
8 clf = XGBExtended(foo = 1)
9
---> 10 clf.get_params()
/Users/andrewhannigan/lib/xgboost/python-package/xgboost/sklearn.pyc in get_params(self, deep)
188 if isinstance(self.kwargs, dict): # if kwargs is a dict, update params accordingly
189 params.update(self.kwargs)
--> 190 if params['missing'] is np.nan:
191 params['missing'] = None # sklearn doesn't handle nan. see #4725
192 if not params.get('eval_metric', True):
KeyError: 'missing'
所以我已经遇到了一个错误,因为"丢失"不是XGBClassifier.get_params
方法中params
dict中的键。我输入调试器以戳戳:
In [183]: %debug
> /Users/andrewhannigan/lib/xgboost/python-package/xgboost/sklearn.py(190)get_params()
188 if isinstance(self.kwargs, dict): # if kwargs is a dict, update params accordingly
189 params.update(self.kwargs)
--> 190 if params['missing'] is np.nan:
191 params['missing'] = None # sklearn doesn't handle nan. see #4725
192 if not params.get('eval_metric', True):
ipdb> params
{'foo': 1}
ipdb> self.__dict__
{'n_jobs': 1, 'seed': None, 'silent': True, 'missing': nan, 'nthread': None, 'min_child_weight': 1, 'random_state': 0, 'kwargs': {}, 'objective': 'binary:logistic', 'foo': 1, 'max_depth': 3, 'reg_alpha': 0, 'colsample_bylevel': 1, 'scale_pos_weight': 1, '_Booster': None, 'learning_rate': 0.1, 'max_delta_step': 0, 'base_score': 0.5, 'n_estimators': 100, 'booster': 'gbtree', 'colsample_bytree': 1, 'subsample': 1, 'reg_lambda': 1, 'gamma': 0}
ipdb>
您可以看到,params
仅包含foo
变量。但是,该对象本身包含xgboost.XGBClassifier.__init__
定义的所有参数。但是由于某种原因,从xgboost.XGBClassifier.get_params
调用的BaseEstimator.get_params
方法仅在XGBExtended.__init__
方法中明确定义了参数。不幸的是,即使我用deep = True
明确调用get_params
,它仍然无法正常工作:
ipdb> super(XGBModel, self).get_params(deep=True)
{'foo': 1}
ipdb>
谁能告诉为什么会发生这种情况?
系统规格:
In [186]: print IPython.sys_info()
{'commit_hash': u'1149d1700',
'commit_source': 'installation',
'default_encoding': 'UTF-8',
'ipython_path': '/Users/andrewhannigan/virtualenvironment/nimble_ai/lib/python2.7/site-packages/IPython',
'ipython_version': '5.4.1',
'os_name': 'posix',
'platform': 'Darwin-14.5.0-x86_64-i386-64bit',
'sys_executable': '/usr/local/Cellar/python/2.7.10/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python',
'sys_platform': 'darwin',
'sys_version': '2.7.10 (default, Jul 3 2015, 12:05:53) n[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)]'}
这里的问题是儿童班级的不正确声明。仅使用foo
声明INIT方法时,您将覆盖原始方法。即使应该为其具有默认值的基类构造函数,它也不会自动初始化。
您应该使用以下内容:
class XGBExtended(xgb.XGBClassifier):
def __init__(self, foo, max_depth=3, learning_rate=0.1,
n_estimators=100, silent=True,
objective="binary:logistic",
nthread=-1, gamma=0, min_child_weight=1,
max_delta_step=0, subsample=1, colsample_bytree=1, colsample_bylevel=1,
reg_alpha=0, reg_lambda=1, scale_pos_weight=1,
base_score=0.5, seed=0, missing=None, **kwargs):
# Pass the required parameters to super class
super(XGBExtended, self).__init__(max_depth, learning_rate,
n_estimators, silent, objective,
nthread, gamma, min_child_weight,
max_delta_step, subsample,
colsample_bytree, colsample_bylevel,
reg_alpha, reg_lambda,
scale_pos_weight, base_score, seed, missing, **kwargs)
# Use other custom parameters
self.foo = foo
之后,您不会遇到任何错误。
clf = XGBExtended(foo = 1)
print(clf.get_params(deep=True))
>>> {'reg_alpha': 0, 'colsample_bytree': 1, 'silent': True,
'colsample_bylevel': 1, 'scale_pos_weight': 1, 'learning_rate': 0.1,
'missing': None, 'max_delta_step': 0, 'nthread': -1, 'base_score': 0.5,
'n_estimators': 100, 'subsample': 1, 'reg_lambda': 1, 'seed': 0,
'min_child_weight': 1, 'objective': 'binary:logistic',
'foo': 1, 'max_depth': 3, 'gamma': 0}