0
from sklearn.datasets import make_classification 
from sklearn.ensemble import RandomForestClassifier 
from sklearn import clone 
import multiprocessing 
import functools 
import numpy as np 

def train_model(n_estimators, base_model, X, y): 
    model = clone(base_model) 
    model.set_params(n_estimators=n_estimators) 
    model.fit(X,y) 
    return model 


class A(): 
    def __init__(self, random_state, jobs, **kwargs): 
     self.model = RandomForestClassifier(oob_score=True, random_state=random_state, **kwargs) 
     self.jobs = jobs 


    def fit(self, X, y): 
     job_pool = multiprocessing.Pool(self.jobs) 
     n_estimators = [100] 
     for output in job_pool.imap_unordered(functools.partial(train_model, 
                   base_model=self.model, 
                   X=X, 
                   y=y),n_estimators): 
      model = output 
     job_pool.terminate() 
     self.model = model 


if __name__ == '__main__': 

    np.random.seed(42) 
    X, y = make_classification(n_samples=500,n_informative=6,n_redundant=6, flip_y=0.1) 

    print "Class A" 
    for i in range(5): 
     base_model = A(random_state=None, jobs=1) 
     base_model.fit(X,y) 
     print base_model.model.oob_score_ 

    print "Bare RF" 
    base_model = RandomForestClassifier(n_estimators=500, max_features=2, oob_score=True, random_state=None) 
    for i in range(5): 
     model = clone(base_model) 
     model.fit(X,y) 
     print model.oob_score_ 

出力のWindows 7マシン(パイソン2.7.13)上:
(PIPフリーズ:numpyの== 1.11.0、scikit-画像== 0.12 .3、scikit学習== 0.17、scipyのダウンロード== 0.17.0)Sklearnのクローンは、Red Hat上のPythonでマルチプロセッシングと予期しない動作を示し

クラス
0.82
0.826
0.832
0.822

0.816

ベアRFのRed Hat 4.8.3-9 Linuxマシン上
0.818
0.818
0.818

出力
0.814
0.81(Pythonの2.7.5):
(PIPフリーズ:numpyの= = 1.11.0、scikit学習== 0.17、scipyのダウンロード== 0.17.0、sklearn == 0.0)
クラスA
0.818
0.818
0.818
0.818
0.818

ベアRF
0.814
0.81
0.818
0.818
0.818だから、

、合計する:
をLinuxでは、 "クラスA"(マルチプロセッシング使用)同じ正確なモデル、つまり同じスコアを訓練しているようです。一方、私が期待する行動は、スコアが一致しない「裸のRF」セクションの1つになります(ランダムアルゴリズムです)。 Windows(Pycharm)では、問題を再現することはできません。

助けてもらえますか?

BIG EDIT:再現可能なコード例を作成しました。

+0

を見つけました: 'クローン(base_model) 'これを 'base_model = clone(self.model)'に入れてから配布してください。 – mkaran

+1

@mkaranの答えに追加します。問題は、エスティメータの初期化です。あなたのケースでは、それぞれのフィットでモデルを再初期化するわけではありません。つまり、fit()が再び呼び出されたとしても、モデルが以前のフィットで学習したウェイトまたはcoeffはほとんど同じですが、scikit-learnクローンはモデルと重みを再初期化します。 –

+0

@ Vivek Kumarあなたは詳細を教えてください(いくつかのコードは多分?)。ありがとうございました! – user152245

答えて

0

解決策は、並行して実行される「train_model」内部にreseedを追加することです。

def train_model(n_estimators, base_model, X, y): 
    np.random.seed() 
    model = clone(base_model) 
    model.set_params(n_estimators=n_estimators) 
    model.fit(X,y) 
    return model 

推論:

何が起こるかは、Unix上で、すべてのワーカープロセスは親プロセスから乱数生成器の同じ状態を継承していることです。これが同じ疑似ランダムシーケンスを生成する理由です。

これは実際にワーカープロセスを起動するマルチプロセッシングです。そのため、これは関連しています。だからこれはscikit-learnクローンの問題ではありません。

私はあなたが提供した実装に同意すると言うことはできませんにもかかわらず、私は:)あなたがここで何が起こっているかの解決策の一部を提供してきたと思う答えherehere

関連する問題