sklearn RandomForestClassifier.fit() не воспроизводится, несмотря на установленное случайное состояние и тот же ввод

#python #machine-learning #random #scikit-learn #random-forest

Вопрос:

При настройке модели случайного леса с использованием Scikit-learn я заметил, что ее оценка точности была разной после разных запусков, хотя я использовал один и тот же экземпляр RandomForestClassifier и те же данные в качестве входных. Я попробовал поиск в Google и функцию поиска StackExchange, но единственный случай, который я смог найти, отдаленно похожий на этот, — это this post , но там проблема заключалась в создании экземпляра классификатора без надлежащего случайного состояния, что не относится к моей проблеме.

Я использую следующий код:

 clf = RandomForestClassifier( n_estimators=65, max_features = 9, max_depth= 'sqrt', random_state = np.random.RandomState(123) )

X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state = np.random.RandomState(159) )
clf.fit(X_train, y_train)
y_pred=clf.predict(X_test)
 

X и y — это мои данные и соответствующие метки, но я обнаружил, что набор данных не повлиял на проблему. Когда я запускаю строку train_test_split, я каждый раз получаю одно и то же разделение, поэтому случайности нет. Запуск predict() с той же подогнанной моделью также каждый раз дает одинаковые результаты, предполагая, что моя проблема отличается от сообщения, на которое я ссылался выше. Однако после каждого запуска fit() predict() выдает другое предсказание! Это происходит даже тогда, когда я не касаюсь X_train и y_train. Поэтому просто запустите эти две строки

 clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
 

каждый раз выдает другой результат. Насколько я могу судить из документации .fit() не должен делать ничего случайного. Без воспроизводимого вывода невозможно настроить модель, поэтому я уверен, что где-то есть ошибка. Чего мне не хватает? Кто-нибудь сталкивался с этим раньше или у кого-нибудь есть какие-либо подсказки относительно того, почему это происходит?

Ответ №1:

Не используйте RandomState объект numpy, если вы будете повторно запускать fits и ожидать тех же результатов. Вместо этого используйте только целое число для random_state .

Из глоссария sklearn, используя numpy RandomState :

Многократный вызов функции приведет к повторному использованию одного и того же экземпляра и приведет к разным результатам.

RandomState Объект заполняется (с вашим 123), но затем сохраняется для каждого вызова fit , продолжая захватывать новые случайные числа, никогда не сбрасываясь.

Быстрая проверка:

 clf = RandomForestClassifier(random_state=314)
preds = {}
for i in range(10):
    preds[i] = clf.fit(X, y).predict_proba(X)
all(np.allclose(preds[i], preds[i 1]) for i in range(9))
# > True

clf = RandomForestClassifier(random_state=np.random.RandomState(314))
preds = {}
for i in range(10):
    preds[i] = clf.fit(X, y).predict_proba(X)
all(np.allclose(preds[i], preds[i 1]) for i in range(9))
# > False
 

Комментарии:

1. Спасибо за ответ! Сейчас я действительно в замешательстве, так как именно так я написал это в первую очередь, но я изменил его на RandomState, потому что ничего не было воспроизводимым, похожим на сообщение, на которое я ссылался ранее. Странно то, что я изменил все обратно на random_state = int, и теперь результат каждый раз один и тот же, и я не могу воспроизвести проблему, с которой я столкнулся до реализации RandomState. Вчера я даже пытался установить случайное начальное значение с помощью np.random.seed, и это ничего не изменило. Итак, в итоге мой код такой же, как и при первом появлении проблемы, но теперь он работает.

2. «Многократный вызов функции приведет к повторному использованию одного и того же экземпляра и приведет к разным результатам». Я этого не знал, спасибо! Похоже, я неправильно понял, что делает RandomState. Я принял ваш ответ и надеюсь, что проблема, которая заставила меня отказаться от random_state=int, не вернется.