在多核上运行时,我对使用np.random.RandomState
with的正确方法感到困惑。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_))
我有几个问题。
尽管有异步方面,为什么我得到可重现的结果?
关于参数的文档
RandomizedSearchCV
说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}
总的来说,这是设置
RandomizedSearchCV
重现性的正确方法吗?RandomState
是使用ok的单个实例,还是应该为train_test_split
、GradientBoostingClassifier
、StratifiedKFold
和使用单独的实例RandomizedSearchCV
?此外,文档np.random.seed
说种子是在RandomState
初始化时设置的。这与RandomizedSearchCV
设置种子有何相互作用?当
n_jobs
设置为使用少于所有核心时,我仍然可以看到所有核心上的活动,尽管每个核心的使用水平会随着核心数量的增加而增加并且经过的时间会减少。这只是 sklearn 和/或 macOS 优化机器使用吗?
我正在使用 macOS 10.14.2、Python 3.6.7、Numpy 1.15.4、Scipy 1.1.0 和 Sklearn 0.20.1。