Разные значения на выходе при одинаковых параметрах при классификации данных
Подбираю параметры для наилучшего обучения модели классификации.
Делаю это так:
print('Исходная обученность: ', lgb_m_REZ)
g = 775
max_score = 0
g_best = 0
i_best = 0
while g < 779:
i = 25
X_train2, X_test2, y_train2, y_test2 = train_test_split(X, y, test_size=0.33, random_state=g)
while i < 28:
param_grid = {
'max_features' : ['auto','sqrt', 'log2'],
'learning_rate' : [ 0.05 , 0.1 , 0.2 , 0.3 ],
'random_state' : [i],
}
svc = GradientBoostingClassifier()
clf = GridSearchCV(svc, param_grid)
clf.fit(X_train2, y_train2)
print('random_state sample: ', g)
print('random_state model: ', i)
print('При подборе параметров: ', clf.best_score_)
print('При подборе параметров: ', clf.best_params_)
if clf.best_score_>lgb_m_REZ and clf.best_score_> max_score:
max_score = clf.best_score_
g_best = g
i_best = i
print('Лучшее значение при подборе параметров: ', max_score, 'i ', i_best,'g ', g_best)
i+=1
g+=1
Получаю к примеру значения, которые дают лучший вариант, чем при первом прогоне модели:
{'learning_rate': 0.3, 'max_features': 'sqrt', 'random_state': 25}
g = 775
i = 25
Подставляю их вот так:
X_train3, X_test3, y_train3, y_test3 = train_test_split(X, y, test_size=0.33, random_state=775)
lgb_m1 = GradientBoostingClassifier(max_features='sqrt', learning_rate= 0.3, random_state=25)
lgb_m1.fit( X_train3, y_train3)
print(lgb_m_REZ)
res3 = lgb_m1.predict(X_test3)
print('Доля правильно угаданных значений: ', accuracy_score(res3, y_test3))
В итоге, результаты разные.
Где я ошибся? Что я делаю не так?
Ответы (1 шт):
Похоже вы не совсем понимаете для чего и как используется параметр random_state в Scikit-Learn.
Этот параметр используется исключительно для того, чтобы при нескольких запусках команды с одинаковыми входными параметрами получать одинаковые результаты. Т.е. использование этого параметра позволяет получать детерминированные результаты для функций и методов классов, которые используют генератор случайных чисел.
Подбирать random_state для того чтобы получить чуть лучший результат при разбиении выборки или при обучении модели - не имеет смысла. Ведь модель обучается для того, чтобы предсказывать значения для неизвестных выборок.
Подобранный для обучающей и тестовой выборок random_state никак не гарантирует лучший результат для неизвестной выборки данных.
Поэтому нет смысла тратить ресурсы впустую и подбирать random_state - он используется только для воспроизведения результатов.
Лучше подбирать настоящие гиперпараметры модели, например n_estimators, criterion, min_samples_split, min_samples_leaf, max_depth, etc.
Иногда для воспроизводимости результата приходится явно задавать задавать значение np.random.seed().
Я бы переписал ваш код следующим образом:
random_state = 123
np.random.seed(random_state)
X_train2, X_test2, y_train2, y_test2 = \
train_test_split(X, y, test_size=0.33, random_state=random_state)
param_grid = {
'max_features' : ['auto','sqrt', 'log2'],
'learning_rate' : [ 0.05 , 0.1 , 0.2 , 0.3 ],
'n_estimators': [50, 100, 250, 500],
'criterion': ['friedman_mse','mse','mae']
}
svc = GradientBoostingClassifier(random_state=random_state)
np.random.seed(random_state)
clf = GridSearchCV(svc, param_grid, random_state=random_state)
clf.fit(X_train2, y_train2)
после этого используйте лучшие подобранные параметры или же можно воспользоваться уже обученной с лучшими параметрами моделью: clf.best_estimator_
clf.best_estimator_.score(X_test2, y_test2)