Scikit learn Sklearn';s clone在Red Hat上使用python进行多处理时显示意外行为
Windows 7计算机(Python 2.7.13)上的输出:Scikit learn Sklearn';s clone在Red Hat上使用python进行多处理时显示意外行为,scikit-learn,multiprocessing,clone,python-multiprocessing,Scikit Learn,Multiprocessing,Clone,Python Multiprocessing,Windows 7计算机(Python 2.7.13)上的输出: (pip冻结:numpy==1.11.0,scikit图像==0.12.3,scikit学习==0.17,scipy==0.17.0) A类 0.82 0.826 0.832 0.822 0.816 裸射频 0.814 0.81 0.818 0.818 0.818 在Red Hat 4.8.3-9 Linux机器(Python 2.7.5)上的输出: (pip冻结:numpy==1.11.0,scikit-learn==0.17,
(pip冻结:numpy==1.11.0,scikit图像==0.12.3,scikit学习==0.17,scipy==0.17.0) A类
0.82
0.826
0.832
0.822
0.816 裸射频
0.814
0.81
0.818
0.818
0.818 在Red Hat 4.8.3-9 Linux机器(Python 2.7.5)上的输出:
(pip冻结:numpy==1.11.0,scikit-learn==0.17,scipy==0.17.0,sklearn==0.0)
A类
0.818
0.818
0.818
0.818
0.818 裸射频
0.814
0.81
0.818
0.818
0.818 总之:
在Linux中,“Class A”(使用多处理)似乎在训练相同的精确模型,因此分数相同。然而,我所期望的行为是“裸RF”部分的行为,其中分数不一致(这是一个随机算法)。在Windows(Pycharm)中,无法再现该问题 你能帮忙吗
大编辑:创建了一个可复制的代码示例 解决方案是在并行执行的“train_模型”中添加重新设定的种子
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_
理由是:
在Unix上,每个工作进程都从父进程继承相同的随机数生成器状态。这就是它们生成相同伪随机序列的原因
实际上是多处理启动了辅助进程,这就是为什么这是相关的。所以这不是scikit学习克隆问题
我已经找到了答案,尽管我不能说我同意您提供的实现,但我认为您已经提供了部分解决方案来解决这里发生的问题:):
clone(base\u model)
。在fitbase\u model=clone(self.model)
中使用它,然后将其分发到@mkaran的答案中。问题是估计量的初始化。在您的情况下,您没有在每次拟合中重新初始化模型,这意味着模型在上一次拟合中学习到的权重或系数基本相同(即使再次调用fit()),而scikit learn的克隆将重新初始化模型和权重。@Vivek Kumar您能详细说明一下(可能需要一些代码吗?)。非常感谢。你能提供这样我们可以复制粘贴和分析它吗?你说你尝试了mkaran的base\u model=clone(self.model)
建议。你能告诉我你是怎么用的吗?您需要在functools.partial()方法中使用它。
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