2017-01-25 8 views
0

に私はこのような推定を有する:計算の中間結果は、一度だけscikit学習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} 

を私はそれ(及びその他)で推定器とパイプラインを作成し、K倍ためGridSearchCVにそれを供給クロスバリデーション。 K-交差検定は次のようなものだ:

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で可能か、回避策はありますか?

答えて

1

この変数は、クラスの静的属性のという静的属性または他のグローバル名スコープに格納してください。もちろん

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} 

ここでの問題は、あなたがあなたの推定を何度も再利用する場合は、別のデータで、時にはあなたがリセットするをしたいですです。次に、各エスティメータの名前をつけて、これらの名前をキーとしてマップ(辞書)に格納します。あなたがcustomEstimatorの新しいインスタンスを作成する場合、それは新しい名前を取得しますが、それはscikit-によりクローン化されている場合

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} 

この方法を:あなたものラインの中で何かによって、名前が自動的に生成されるようにすることができます彼らは同じ名前(と結果として - データ)を共有することを学びます。

+0

ありがとうございます! 1つの質問:毎回__init__メソッドが呼び出されるので、私はそれらが異なる物理的オブジェクトであると考えます。しかし、私は、ScickitがGridSearchCVの同じパラメータセットで作業するときに、同じ名前の変数を__init__を呼び出すときに使用することを知っています。それは正しいでしょうか? – Bob

+0

customEstimatorの各インスタンスは異なるオブジェクトですが、私の例では "tmpVars"は** static **です。つまり、すべてのインスタンスで共有されています。これはscikit-learnの機能ではなく、静的属性がどのプログラミング言語でも一般的にどのように機能するかです。もちろん、scikit-learnのクローニングを使用すると、同じ名前が取得され、同じ部分のメモリを取得できるようになります。 – lejlot