Как запустить генератор случайных чисел для scikit-learn?

Я пытаюсь написать модульный тест для некоторого моего кода, который использует scikit-learn. Однако мои модульные тесты кажутся недетерминированными.

Насколько я знаю, единственные места в моем коде, где scikit-learn использует какую-либо случайность, находятся в его модели LogisticRegression и train_test_split, поэтому у меня есть следующее:

RANDOM_SEED = 5
self.lr = LogisticRegression(random_state=RANDOM_SEED)
X_train, X_test, y_train, test_labels = train_test_split(docs, labels, test_size=TEST_SET_PROPORTION, random_state=RANDOM_SEED)

Но это, похоже, не работает — даже когда я передаю фиксированные docs и фиксированные labels, вероятности предсказания в фиксированном наборе проверки меняются от запуска к запуску.

Я также пытался добавить вызов numpy.random.seed(RANDOM_SEED) вверху своего кода, но это тоже не сработало.

Есть ли что-то, что я упускаю? Есть ли способ передать семя в scikit-learn в одном месте, чтобы это семя использовалось во всех вызовах scikit-learn?


person John    schedule 22.11.2016    source источник
comment
Очень вероятно, что в вашем коде что-то еще не так! Использование семени в LR и Splitting будет достаточно, чтобы убедиться, что оно ведет себя детерминировано!   -  person sascha    schedule 22.11.2016
comment
Я не уверен, решит ли это вашу проблему детерминизма, но это неправильный способ использования фиксированного начального числа с scikit-learn. Создайте экземпляр prng=numpy.random.RandomState(RANDOM_SEED), затем передайте его как random_state=prng каждой отдельной функции. Если вы просто передадите RANDOM_SEED, каждая отдельная функция перезапустится и выдаст одни и те же числа в разных местах, что приведет к плохой корреляции.   -  person Robert Kern    schedule 23.11.2016
comment
@RobertKern Можете ли вы уточнить? Я не совсем понимаю, что вы пытаетесь объяснить. Но, конечно, использование int-seed является допустимым подходом к детерминированности этих функций. Может быть, вы говорите о проблемах с распределенным сидированием, но даже если это так, я не могу понять, откуда это берется, и тогда есть гораздо лучшие подходы.   -  person sascha    schedule 23.11.2016
comment
Детерминизм не единственная важная вещь. Статистическая независимость также важна, и вы не получите ее, передав одно и то же целочисленное начальное число нескольким функциям scikit-learn в одном и том же конвейере. Вы хотите, чтобы ровно один экземпляр RandomState использовался всеми функциями в конвейере.   -  person Robert Kern    schedule 23.11.2016
comment
@RobertKern Это зависит от среды / задачи (и, конечно, от PRNG), но здесь не относится к проблеме ОП.   -  person sascha    schedule 23.11.2016
comment
Нет, это просто следующая проблема, с которой столкнется OP после того, как он решит детерминированность (возможно, найдя другую пропущенную часть конвейера, которая принимает аргумент random_state=). Вот почему я поместил это в комментарий. Я категорически заявляю, что способ, который я упомянул, является единственным правильным способом использования указанного семени для среды/задачи OP и PRNG.   -  person Robert Kern    schedule 23.11.2016
comment
Если вам нужна дополнительная помощь, вы можете опубликовать больше кода.   -  person serv-inc    schedule 29.06.2017


Ответы (1)


from sklearn import datasets, linear_model
iris = datasets.load_iris()
(X, y) = iris.data, iris.target
RANDOM_SEED = 5
lr = linear_model.LogisticRegression(random_state=RANDOM_SEED)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=RANDOM_SEED)
lr.fit(X_train, y_train)
lr.score(X_test, y_test)

произвел 0.93333333333333335 несколько раз. То, как вы это сделали, вроде нормально. Другой способ — установить np.random.seed() или использовать Sacred для задокументированной случайности. Использование random_state — это то, что описывается в документах:

Если ваш код основан на генераторе случайных чисел, он никогда не должен использовать такие функции, как numpy.random.random или numpy.random.normal. Такой подход может привести к проблемам с повторяемостью в модульных тестах. Вместо этого следует использовать объект numpy.random.RandomState, который создается из аргумента random_state, переданного классу или функции.

person serv-inc    schedule 29.06.2017