在scikit-learn GridSearchCV中只计算一次中间结果



我有一个这样的估计器:

    from sklearn.base import BaseEstimator, TransformerMixin
    import numpy as np
    class customEstimator(BaseEstimator, TransformerMixin):
        def __init__(self, estimator_var):
            self.estimator_var = estimator_var
        def transform(self, X):
            self.tmpVar = np.random.randn(estimator_var, estimator_var)
            return np.hstack((self.tmpVar, X)) # this is just an example
        def fit(self, X, y=None):
            return self
        def get_params(self, deep=False):
            return {'estimator_var': self.estimator_var, 'tmpVar': tmpVar}

然后,我创建一个包含估算器(和其他)的管道,并将其输入 GridSearchCV 以进行 k 折叠交叉验证。 K-fold交叉验证是这样的:

for all possible params combination:
   for every fold split
     compute score(mini_train, mini_test)
   compute average score
pick best combination 

问题是,对于给定的参数组合,我只想计算一次self.tmpVar(计算起来可能很慢),并将其用于共享相同参数组合的所有折叠拆分。

这在scikit-learn中是否可能,或者有解决方法吗?

只需将此变量存储为类的静态属性,或任何其他全局名称范围。

from sklearn.base import BaseEstimator, TransformerMixin
import numpy as np
class customEstimator(BaseEstimator, TransformerMixin):
    tmpVar = None
    def __init__(self, estimator_var):
        self.estimator_var = estimator_var
    def transform(self, X):
        if customEstimator.tmpVar is None:
            customEstimator.tmpVar = np.random.randn(estimator_var, estimator_var)
        return np.hstack((customEstimator.tmpVar, X)) # this is just an example
    def fit(self, X, y=None):
        return self
    def get_params(self, deep=False):
        return {'estimator_var': self.estimator_var}

当然,这里的问题是,如果您多次重复使用估算器,使用不同的数据,有时您确实想要重置。然后,您可以简单地为每个估算器指定一个名称,并将这些 tmpVar 存储在映射(字典)中,并将这些名称作为键。您甚至可以通过以下行自动生成名称:

from sklearn.base import BaseEstimator, TransformerMixin
import numpy as np
class customEstimator(BaseEstimator, TransformerMixin):
    tmpVars = {}
    estimators = 0
    def __init__(self, estimator_var, name=None):
        if name is None:
            customEstimator.estimators = customEstimator.estimators + 1
            name = 'Estimator %d' % customEstimator.estimators
        self.name = name
        self.estimator_var = estimator_var
    def transform(self, X):
        if self.name not in customEstimator.tmpVar:
            customEstimator.tmpVar[self.name] = np.random.randn(estimator_var, estimator_var)
        return np.hstack((customEstimator.tmpVar[self.name], X)) # this is just an example
    def fit(self, X, y=None):
        return self
    def get_params(self, deep=False):
        return {'estimator_var': self.estimator_var, 'name': self.name}

这样,如果你创建一个 customEstimator 的新实例,它将获得一个新名称,但如果它被 scikit-learn 克隆,它们将共享相同的名称(因此 - 数据)。

相关内容

  • 没有找到相关文章

最新更新