我想实现一个与所有 scikit-learn 兼容的简单包装器/元估计器。很难找到我到底需要什么的完整描述。
目标是让回归器也学习阈值以成为分类器。所以我想出了:
from sklearn.base import BaseEstimator, ClassifierMixin, clone
class Thresholder(BaseEstimator, ClassifierMixin):
def __init__(self, regressor):
self.regressor = regressor
# threshold_ does not get initialized in __init__ ??
def fit(self, X, y, optimal_threshold):
self.regressor = clone(self.regressor) # is this required my sklearn??
self.regressor.fit(X, y)
y_raw = self.regressor.predict()
self.threshold_ = optimal_threshold(y_raw)
def predict(self, X):
y_raw = self.regressor.predict(X)
y = np.digitize(y_raw, [self.threshold_])
return y
这是否实现了我需要的完整 API?
我的主要问题是把
threshold
放在哪里.我希望它只学习一次并且可以在后续 .fit
中重复使用调用新数据而无需重新调整。但是对于当前版本,它必须在每个 .fit
上重新调整。打电话 - 我不想要?另一方面,如果我将其设为固定参数
self.threshold
并将其传递给 __init__
,那么我不应该用数据来改变它?我如何制作
threshold
可以在 .fit
的一次调用中调整的参数并为后续 .fit
修复电话?
最佳答案
I actually wrote a blog post about this the other day .我假设您正在尝试构建类似于 TransformedTargetRegressor
的东西。我建议查看它的源代码来构建类似的东西。
您当前的实现似乎是正确的。就这个问题而言:
How can I make a threshold parameter which can be tuned in one call of
.fit
and be fixed for subsequent.fit
calls?
我建议不要这样做,因为
scikit-learn
的 API 基于 fit
方法重新拟合模型的所有可调方面。这里有两条路线可以走,要么加一个**kwarg
适合明确保护 theshold
从更新或者你可以去什么@rotem-tal suggested .如果您选择后者,它可能如下所示:import numpy as np
from sklearn.base import BaseEstimator, ClassifierMixin
def optimal_threshold(y_raw: np.ndarray) -> np.ndarray:
return np.array([0.1, 0.5, 1]) # some implementation here
class Thresholder(BaseEstimator, ClassifierMixin):
def __init__(self, regressor):
self.regressor = regressor
self.threshold = None
def fit(self, X, y, optimal_threshold):
# you don't need to clone the regressor
self.regressor.fit(X, y)
y_raw = self.regressor.predict()
if self.threshold is None:
self.threshold = optimal_threshold(y_raw)
def predict(self, X):
y_raw = self.regressor.predict(X)
y = np.digitize(y_raw, [self.threshold_])
return y
关于python - 如何使用 scikit-learn API 实现元估计器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58804308/