使用多处理时无法重现scikit-learn和numpy依赖代码



下面的代码在cross_validaten_jobs=1函数时是完全可重现的,但在n_jobs=-12时则不然。

import numpy as np
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_validate,RepeatedStratifiedKFold
class DecisionTree(DecisionTreeClassifier):
def fit(self,X,Y):
weight = np.random.uniform(size=Y.shape)
return super().fit(X,Y,sample_weight=weight)
def main():
X,Y = load_iris(return_X_y=True)
rks = RepeatedStratifiedKFold(n_repeats=2,n_splits=5,random_state=42)
clf = DecisionTree(random_state=42)
res = cross_validate(clf,X,Y,cv=rks,n_jobs=2)['test_score']*100
return res.mean(),res.std()
if __name__=='__main__':
np.random.seed(42)
print(main())

请注意np.random.uniform调用fit功能。该代码也是完全可重现的,无需此类 numpy 调用。这里提到numpy.random.seed不是线程安全的。但是我在 sklearn 的常见问题解答中没有看到这一点,根据该常见问题解答,在任何地方提供random_state就足够了。

无论如何,在保持完全可重复性的同时,是否可以在 sklearn 中使用 numpy 随机调用和多处理?

编辑:我认为如果我们n_jobs>1放在接受它的估计器中,例如实例化RandomForestClassifier,它可以很好地重现。

看起来您的DecisionTree类应该使用传入的random_state。 当我这样做时,我会得到一致的结果:

from sklearn.utils import check_random_state
class DecisionTree(DecisionTreeClassifier):
def fit(self, X, Y):
rng = check_random_state(self.random_state)
weight = rng.uniform(size=Y.shape)
return super().fit(X, Y, sample_weight=weight)

但除此之外,请照你做的那样。 请注意,通过此更改,您还可以删除对np.random.seed(42)的调用,因为 RNG 状态在需要的任何位置都显式设置

相关内容

  • 没有找到相关文章

最新更新