2 回答

TA贡献1821条经验 获得超6个赞
参数候选是在使用ParameterSampler 对象传递给多线程功能之前生成的。因此random_state
,对于 RandomizedSearchCV 的可重复性,只有一个就足够了。
注意我说的"reproducibility of RandomizedSearchCV"
。对于其中使用的估算器(base_clf
此处),每个估算器都应该random_state
像您一样携带自己的估算器。
现在谈论a single instance of RandomState
,对于顺序代码来说非常好。唯一需要担心的情况是多处理开始时。因此,让我们分析一下程序执行期间发生的步骤。
您设置了一个
RandomState
带有种子的对象。它现在有一个状态。在内部
train_test_split
,使用了 aStratifiedShuffleSplit
(因为您使用了stratify
param),它将使用传递的RandomState
对象在训练和测试数据中拆分和生成排列。所以RandomState
现在的内部状态发生了变化。但它的顺序并没有什么可担心的。现在您
random_state
在skf
. 但是fit()
在RandomizedSearchCV
调用in之前不会发生分裂。所以状态不变。之后,当
search_clf.fit
被调用时,会发生以下情况:_run_search()
执行,它将使用random_state
一次生成所有参数组合(根据给定n_iters
)。所以仍然没有多线程的任何部分发生,一切都很好。evaluate_candidates()
叫做。有趣的部分是这样的:
out = parallel(delayed(_fit_and_score)(clone(base_estimator),
X, y,
train=train, test=test,
parameters=parameters,
**fit_and_score_kwargs)
for parameters, (train, test)
in product(candidate_params,
cv.split(X, y, groups)))
cv.split()
将使用random_state
(改变其状态)来生成训练测试分割clone(estimator)
将克隆估计器的所有参数,(random_state
也)。所以RandomState
fromcv.split
对象的改变状态变成了 in 的基本状态estimator
上述两个步骤从父线程(没有异步性)发生多次(拆分次数 x 参数组合次数)。并且每次
RandomState
克隆原始文件以服务于估算器。所以结果是可重复的。所以当实际的多线程部分开始时,原先
RandomState
是没有使用的,但是每个估计器(线程)都会有自己的副本RandomState
后面的部分
parallel(delayed(_fit_and_score)
仍然是由父线程处理的顺序。
希望这是有道理的,并回答您的问题。Scikit-learn明确要求用户设置如下:
import numpy as np np.random.seed(42)
使整个执行可重现,但你正在做的也将做。
我不完全确定您的最后一个问题,因为我无法在我的系统上重现该问题。我有 4 个内核,当我设置n_jobs=2
或3
我只看到那些内核为 100% 并保持在 20-30% 左右。我的系统规格:
System:
python: 3.6.6 |Anaconda, Inc.| (default, Jun 28 2018, 17:14:51) [GCC 7.2.0]
machine: Linux-4.15.0-20-generic-x86_64-with-debian-buster-sid
Python deps:
pip: 18.1
setuptools: 40.2.0
sklearn: 0.20.1
numpy: 1.15.4
scipy: 1.1.0
Cython: 0.29
pandas: 0.23.4

TA贡献1868条经验 获得超4个赞
在它不使用所有 cpu 内核的方面:
我有同样的问题,可以通过做两件事来解决它。
我已经编写了自己的分发类,并意识到由于一个问题,它非常慢。加快速度有帮助。
我设置
pre_dispatch
了一些合理的东西pre_dispatch=10*os.cpu_count()
。我认为问题在于它在开始将内容安装到其他内核之前准备了所有数据。
添加回答
举报