Subclassing XGBoostRegressor for scikit-learn estimators receives "TypeError: super() takes no keyword arguments."
Subclassing XGBoostRegressor for scikit-learn estimators receives "TypeError: super() takes no keyword arguments."
我尝试子class XGBRegressor 创建一个嵌入了 GridSearchCV 的自定义 scikit-learn 兼容估计器。我一直收到 TypeError 消息说“super() 没有关键字参数。”
在下面的上下文中,第一个代码是第二个代码的过程版本。第二个代码是我打算做的但失败了:我想用 GridSearchCV 作为交叉验证器为 XGBoost 回归器创建一个新的 class。
from xgboost.sklearn import XGBRegressor
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import make_regression
import matplotlib.pyplot as plt
# procedural version
X, y = make_regression(n_samples=20, n_features=3, random_state=42)
parameters = {'n_estimators': [10, 20], 'max_depth': [3, 4]}
tunned_regr = GridSearchCV(XGBRegressor(), parameters)
tunned_regr.fit(X, y)
pred_y = tunned_regr.predict(X)
fig, ax = plt.subplots(figsize=(10,6))
plt.scatter(range(len(X)), pred_y, label="predicted")
plt.scatter(range(len(X)), y, label="true")
plt.legend()
# the new xgboost regressor with gridsearchCV embedded
class XGBR(XGBRegressor):
def __init__(self, objective='reg:linear'):
super(XGBR, self).__init__(objective=objective)
def fit(self, X, y):
parameters = {'n_estimators': [10, 20], 'max_depth': [3, 4]}
self.regr = GridSearchCV(super(XGBR, self), parameters)
self.regr.fit(X, y)
return self
def predict(self, X):
return self.regr.predict(X)
运行以下命令xgbr=XGBR(); xgbr.fit(X, y)
,你应该会看到错误信息:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/test.py in <module>
13 return self.regr.predict(X)
14 xgbr = XGBR()
---> 15 xgbr.fit(X, y)
/test.py in fit(self, X, y)
7 parameters = {'n_estimators': [10, 20], 'max_depth': [3, 4]}
8 self.regr = GridSearchCV(super(XGBR, self), parameters)
----> 9 self.regr.fit(X, y)
10 return self
11
~/.local/lib/python3.9/site-packages/sklearn/model_selection/_search.py in fit(self, X, y, groups, **fit_params)
803 n_splits = cv_orig.get_n_splits(X, y, groups)
804
--> 805 base_estimator = clone(self.estimator)
806
807 parallel = Parallel(n_jobs=self.n_jobs, pre_dispatch=self.pre_dispatch)
~/.local/lib/python3.9/site-packages/sklearn/base.py in clone(estimator, safe)
80 for name, param in new_object_params.items():
81 new_object_params[name] = clone(param, safe=False)
---> 82 new_object = klass(**new_object_params)
83 params_set = new_object.get_params(deep=False)
84
TypeError: super() takes no keyword arguments
我觉得这一行很可疑:
self.regr = GridSearchCV(super(XGBR, self), parameters)
我怀疑您想改写以下内容:
self.regr = GridSearchCV(self, parameters)
在你的代码的过程版本中,你写
tunned_regr = GridSearchCV(XGBRegressor(), parameters)
所以你传递了一个 XGBRegressor
class 的实例作为 GridSearchCV
构造函数的第一个参数。在您的代码中,XGRB
是 XGBRegressor
的子 class,因此 self
将是 XGRB
的实例,因此也是 XGBRegressor
的实例。
但是,在花了更多时间查看您的代码和您的问题之后,我不确定继承是否适合这里。
'prefer composition over inheritance'软件开发有一个通用的格言。在某些情况下继承很有用,但它往往用在它不是最佳方法的地方,我认为这就是其中一种情况。
XGBR 也是 XGBRegressor 吗?您可以在任何可以使用 XGBRegressor
的地方使用 XGBR
class 的实例吗?如果这两个问题中的任何一个的答案是否定的,那么就不要使用继承。
您的 class 的以下版本改为使用组合:它在 fit()
方法中创建一个 XGBRegressor
。您以与以前完全相同的方式创建和使用它:
class XGBR:
def __init__(self, objective='reg:linear'):
self.objective = objective
def fit(self, X, y):
parameters = {'n_estimators': [10, 20], 'max_depth': [3, 4]}
self.regr = GridSearchCV(XGBRegressor(objective=self.objective), parameters)
self.regr.fit(X, y)
return self
def predict(self, X):
return self.regr.predict(X)
暂时我选择在对 fit()
的调用中初始化 XGBRegressor。如果 XGBRegressor
的创建速度很慢,您可能希望改为在 __init__
中创建它。但是,如果这样做,您还需要确保可以使用相同的 XGBRegressor
来分析多个数据集,并且任何数据集的分析都不会受到 XGBRegressor
具有的任何先前数据集的影响见过。这可能是问题,也可能不是问题,我不知道。
最后,我添加一个免责声明,我不是数据科学家,我也没有测试过这段代码。
我尝试子class XGBRegressor 创建一个嵌入了 GridSearchCV 的自定义 scikit-learn 兼容估计器。我一直收到 TypeError 消息说“super() 没有关键字参数。”
在下面的上下文中,第一个代码是第二个代码的过程版本。第二个代码是我打算做的但失败了:我想用 GridSearchCV 作为交叉验证器为 XGBoost 回归器创建一个新的 class。
from xgboost.sklearn import XGBRegressor
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import make_regression
import matplotlib.pyplot as plt
# procedural version
X, y = make_regression(n_samples=20, n_features=3, random_state=42)
parameters = {'n_estimators': [10, 20], 'max_depth': [3, 4]}
tunned_regr = GridSearchCV(XGBRegressor(), parameters)
tunned_regr.fit(X, y)
pred_y = tunned_regr.predict(X)
fig, ax = plt.subplots(figsize=(10,6))
plt.scatter(range(len(X)), pred_y, label="predicted")
plt.scatter(range(len(X)), y, label="true")
plt.legend()
# the new xgboost regressor with gridsearchCV embedded
class XGBR(XGBRegressor):
def __init__(self, objective='reg:linear'):
super(XGBR, self).__init__(objective=objective)
def fit(self, X, y):
parameters = {'n_estimators': [10, 20], 'max_depth': [3, 4]}
self.regr = GridSearchCV(super(XGBR, self), parameters)
self.regr.fit(X, y)
return self
def predict(self, X):
return self.regr.predict(X)
运行以下命令xgbr=XGBR(); xgbr.fit(X, y)
,你应该会看到错误信息:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/test.py in <module>
13 return self.regr.predict(X)
14 xgbr = XGBR()
---> 15 xgbr.fit(X, y)
/test.py in fit(self, X, y)
7 parameters = {'n_estimators': [10, 20], 'max_depth': [3, 4]}
8 self.regr = GridSearchCV(super(XGBR, self), parameters)
----> 9 self.regr.fit(X, y)
10 return self
11
~/.local/lib/python3.9/site-packages/sklearn/model_selection/_search.py in fit(self, X, y, groups, **fit_params)
803 n_splits = cv_orig.get_n_splits(X, y, groups)
804
--> 805 base_estimator = clone(self.estimator)
806
807 parallel = Parallel(n_jobs=self.n_jobs, pre_dispatch=self.pre_dispatch)
~/.local/lib/python3.9/site-packages/sklearn/base.py in clone(estimator, safe)
80 for name, param in new_object_params.items():
81 new_object_params[name] = clone(param, safe=False)
---> 82 new_object = klass(**new_object_params)
83 params_set = new_object.get_params(deep=False)
84
TypeError: super() takes no keyword arguments
我觉得这一行很可疑:
self.regr = GridSearchCV(super(XGBR, self), parameters)
我怀疑您想改写以下内容:
self.regr = GridSearchCV(self, parameters)
在你的代码的过程版本中,你写
tunned_regr = GridSearchCV(XGBRegressor(), parameters)
所以你传递了一个 XGBRegressor
class 的实例作为 GridSearchCV
构造函数的第一个参数。在您的代码中,XGRB
是 XGBRegressor
的子 class,因此 self
将是 XGRB
的实例,因此也是 XGBRegressor
的实例。
但是,在花了更多时间查看您的代码和您的问题之后,我不确定继承是否适合这里。
'prefer composition over inheritance'软件开发有一个通用的格言。在某些情况下继承很有用,但它往往用在它不是最佳方法的地方,我认为这就是其中一种情况。
XGBR 也是 XGBRegressor 吗?您可以在任何可以使用 XGBRegressor
的地方使用 XGBR
class 的实例吗?如果这两个问题中的任何一个的答案是否定的,那么就不要使用继承。
您的 class 的以下版本改为使用组合:它在 fit()
方法中创建一个 XGBRegressor
。您以与以前完全相同的方式创建和使用它:
class XGBR:
def __init__(self, objective='reg:linear'):
self.objective = objective
def fit(self, X, y):
parameters = {'n_estimators': [10, 20], 'max_depth': [3, 4]}
self.regr = GridSearchCV(XGBRegressor(objective=self.objective), parameters)
self.regr.fit(X, y)
return self
def predict(self, X):
return self.regr.predict(X)
暂时我选择在对 fit()
的调用中初始化 XGBRegressor。如果 XGBRegressor
的创建速度很慢,您可能希望改为在 __init__
中创建它。但是,如果这样做,您还需要确保可以使用相同的 XGBRegressor
来分析多个数据集,并且任何数据集的分析都不会受到 XGBRegressor
具有的任何先前数据集的影响见过。这可能是问题,也可能不是问题,我不知道。
最后,我添加一个免责声明,我不是数据科学家,我也没有测试过这段代码。