Python 如何将RandomState与Sklearn RandomizedSearchCV一起在多核上使用
我对在多核上运行时使用Python 如何将RandomState与Sklearn RandomizedSearchCV一起在多核上使用,python,numpy,scikit-learn,scipy,numpy-random,Python,Numpy,Scikit Learn,Scipy,Numpy Random,我对在多核上运行时使用np.random.RandomState和sklearn.model_selection.RandomizedSearchCV的正确方法感到困惑 我使用RandomState生成伪随机数,这样我的结果就可以重现。我给RandomizedSearchCV一个RandomState的实例,并将n_jobs=-1设置为使用所有六个核心 在多核上运行会引入异步元素。我预计这将导致在不同的运行中以不同的顺序从不同的内核请求伪随机数。因此,不同的运行应给出不同的结果,而不是显示再现性
np.random.RandomState
和sklearn.model_selection.RandomizedSearchCV
的正确方法感到困惑
我使用RandomState
生成伪随机数,这样我的结果就可以重现。我给RandomizedSearchCV
一个RandomState
的实例,并将n_jobs=-1
设置为使用所有六个核心
在多核上运行会引入异步元素。我预计这将导致在不同的运行中以不同的顺序从不同的内核请求伪随机数。因此,不同的运行应给出不同的结果,而不是显示再现性
但事实上,结果是可重复的。对于给定的n_iter
(即参数空间中的绘图数量),找到的最佳超参数值在每次运行中都是相同的。如果n_jobs
是一个小于核心数的正数,我也会得到相同的值
具体而言,以下是代码:
import numpy as np
import scipy.stats as stats
from sklearn.datasets import load_iris
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import RandomizedSearchCV, StratifiedKFold, train_test_split
# Use RandomState for reproducibility.
random_state = np.random.RandomState(42)
# Get data. Split it into training and test sets.
iris = load_iris()
X, y = iris.data, iris.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.4, random_state=random_state, stratify=y)
# Prepare for hyper-parameter optimization.
n_iter = 1_000
base_clf = GradientBoostingClassifier(
random_state=random_state, max_features='sqrt')
param_space = {'learning_rate': stats.uniform(0.05, 0.2),
'n_estimators': [50, 100, 200],
'subsample': stats.uniform(0.8, 0.2)}
# Generate data folds for cross validation.
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=random_state)
# Create the search classifier.
search_clf = RandomizedSearchCV(
base_clf, param_space, n_iter=n_iter, scoring='f1_weighted', n_jobs=-1,
cv=skf, random_state=random_state, return_train_score=False)
# Optimize the hyper-parameters and print the best ones found.
search_clf.fit(X_train, y_train)
print('Best params={}'.format(search_clf.best_params_))
我有几个问题
random_state
参数:“伪随机数生成器状态用于从可能值列表中随机均匀采样,而不是scipy.stats分布。”这是否意味着它不会影响参数空间中的分布?上面的代码是否足以确保再现性,或者我是否需要设置np.random.seed()
,或者编写类似以下内容:
distn_learning_rate = stats.uniform(0.05, 0.2)
distn_learning_rate.random_state = random_state
distn_subsample = stats.uniform(0.8, 0.2)
distn_subsample.random_state = random_state
param_space = {'learning_rate': distn_learning_rate,
'n_estimators': [50, 100, 200],
'subsample': distn_subsample}
import numpy as np
np.random.seed(42)
RandomizedSearchCV
再现性的正确方法吗RandomState
的单个实例,或者我应该为train\u test\u split
、GradientBoostingClassifier
、StratifiedKFold
和RandomizedSearchCV
使用单独的实例?另外,的文档说明种子是在RandomState
初始化时设置的。这与设置种子如何交互n_jobs
设置为使用少于所有内核时,我仍然可以在所有内核上看到活动,尽管每个内核的使用级别随着内核数量的增加而增加,所用时间也会减少。这是否只是sklearn和/或macOS优化机器使用我使用的是macOS 10.14.2、Python 3.6.7、Numpy 1.15.4、Scipy 1.1.0和Sklearn 0.20.1。在使用。因此,只有一个
random_状态
就足以保证RandomizedSearchCV的再现性
请注意,我说的是“随机搜索CV的再现性”。对于内部使用的估计器(base\u clf
),每个估计器都应该像您所做的那样携带自己的random\u state
现在我们来讨论一下RandomState的一个实例,对于顺序的代码来说是非常好的。唯一需要担心的是多重处理何时开始。因此,让我们分析一下程序执行过程中发生的步骤
RandomState
对象。它现在有一个状态train\u test\u split
内部,使用了stratifiedshuffliesplit
(因为您使用了stratify
param),它将使用传递的RandomState
对象在train和测试数据中分割和生成置换。因此,RandomState
的内部状态现在已更改。但这是循序渐进的,没什么好担心的skf
中设置此random_state
对象。但在调用RandomizedSearchCV
中的fit()
之前,不会发生拆分。所以状态不变search\u clf.fit
时:
随机状态
一次生成所有参数组合(根据给定的n\u iter
)。因此,多线程仍然没有发生,一切都很好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\u状态也将克隆。因此,从
对象中更改的cv.split
状态将成为RandomState
estimator
- 上述两个步骤从父线程(无异步性)多次发生(拆分次数x参数组合次数)。每次克隆原始
以服务于估计器。因此结果是可重复的RandomState
- 因此,当实际的多线程部分启动时,不会使用原始的
,但每个估计器(线程)都有自己的RandomState
RandomState
distn_learning_rate = stats.uniform(0.05, 0.2)
distn_learning_rate.random_state = random_state
distn_subsample = stats.uniform(0.8, 0.2)
distn_subsample.random_state = random_state
param_space = {'learning_rate': distn_learning_rate,
'n_estimators': [50, 100, 200],
'subsample': distn_subsample}
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
在不使用所有cpu核心的方面: 我有同样的问题,可以通过两件事来解决
- 我写了自己的发行类,并意识到