【发布时间】:2019-05-12 14:34:34
【问题描述】:
我对在多核上运行时使用 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_))
我有几个问题。
尽管有异步方面,为什么我得到可重现的结果?
-
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的单个实例,还是应该为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。
【问题讨论】:
标签: python numpy scikit-learn scipy numpy-random