Я озадачен правильным способом использования 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}
В целом, это правильный способ установкиup 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 и Sklearn0.20.1.