Перекрестная проверка с поиском по сетке дает худшие результаты, чем по умолчанию

Я использую scikitlearn в Python для запуска некоторых базовых моделей машинного обучения. Используя встроенную функцию GridSearchCV (), я определил «лучшие» параметры для различных методов, но многие из них работают хуже, чем значения по умолчанию. Я включаю параметры по умолчанию в качестве опции, поэтому я удивлен, что это произойдет.

Например:

from sklearn import svm, grid_search
from sklearn.ensemble import GradientBoostingClassifier
gbc = GradientBoostingClassifier(verbose=1)
parameters = {'learning_rate':[0.01, 0.05, 0.1, 0.5, 1],  
              'min_samples_split':[2,5,10,20], 
              'max_depth':[2,3,5,10]}
clf = grid_search.GridSearchCV(gbc, parameters)
t0 = time()
clf.fit(X_crossval, labels)
print "Gridsearch time:", round(time() - t0, 3), "s"
print clf.best_params_
# The output is: {'min_samples_split': 2, 'learning_rate': 0.01, 'max_depth': 2}

Это то же самое, что и по умолчанию, за исключением того, что max_depth равно 3. Когда я использую эти параметры, я получаю точность 72% по сравнению с 78% от значения по умолчанию.

Одна вещь, которую я сделал, что я признаю подозрительной, заключалась в том, что я использовал весь свой набор данных для перекрестной проверки. Затем, получив параметры, я запустил его, используя тот же набор данных, разделенный на 75-25 тренировок / тестов.

Есть ли причина, по которой при поиске по сетке не учитывались "превосходные" значения по умолчанию?


person Nicholas Hassan    schedule 20.04.2017    source источник
comment
Не могли бы вы подробнее рассказать о своей cross_validation схеме?   -  person juanpa.arrivillaga    schedule 21.04.2017
comment
@ juanpa.arrivillaga Я новичок в этом и не знаю, какими терминами мне нужно это описать. Я последовал примеру, приведенному в руководстве scikitlearn для функции. scikit-learn.org/stable/ модули / сгенерированные / Я знаю, что по умолчанию используется трехкратная перекрестная проверка   -  person Nicholas Hassan    schedule 21.04.2017


Ответы (2)


Выполнение перекрестной проверки всего вашего набора данных для выбора параметров и / или функций может определенно вызвать проблемы при тестировании на одном и том же наборе данных. Похоже, что это как минимум часть проблемы. Запуск CV на подмножестве ваших данных для оптимизации параметров и сохранение набора задержек для тестирования - хорошая практика.

Предполагая, что вы используете набор данных iris (это набор данных, используемый в пример в вашей ссылке на комментарий), вот пример того, как на оптимизацию параметров GridSearchCV влияет сначала создание набора задержек с помощью _ 3_:

from sklearn import datasets
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import GradientBoostingClassifier

iris = datasets.load_iris()
gbc = GradientBoostingClassifier()
parameters = {'learning_rate':[0.01, 0.05, 0.1, 0.5, 1], 
              'min_samples_split':[2,5,10,20], 
              'max_depth':[2,3,5,10]}

clf = GridSearchCV(gbc, parameters)
clf.fit(iris.data, iris.target)

print(clf.best_params_)
# {'learning_rate': 1, 'max_depth': 2, 'min_samples_split': 2}

Теперь повторите поиск по сетке, используя случайное обучающее подмножество:

from sklearn.model_selection import train_test_split

X_train,X_test,y_train,y_test = train_test_split(iris.data, iris.target, 
                                                 test_size=0.33, 
                                                 random_state=42)

clf = GridSearchCV(gbc, parameters)
clf.fit(X_train, y_train)

print(clf.best_params_)
# {'learning_rate': 0.01, 'max_depth': 5, 'min_samples_split': 2}

Я наблюдаю гораздо более высокую точность классификации с обоими этими подходами, что заставляет меня думать, что, возможно, вы используете разные данные, но здесь демонстрируется основной момент о выполнении выбора параметров при сохранении удерживаемого набора. Надеюсь, это поможет.

person andrew_reece    schedule 20.04.2017
comment
Спасибо! Однако, как вы сказали, даже тот, который использовал весь набор данных, все равно показал более высокую точность, поэтому я думаю, что это нечто большее. Недавно я задал несколько других вопросов, и еще одна большая проблема с моими данными заключается в том, что я не нормализовал их, так что это, вероятно, тоже приведет к некоторым проблемам. Я попробую все эти рекомендации и посмотрю, имеет ли это значение. - person Nicholas Hassan; 21.04.2017

Вы также можете использовать Kfolds cross_validator https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.html.

from sklearn import datasets
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import KFold

iris = datasets.load_iris()
gbc = GradientBoostingClassifier()
parameters = {'learning_rate':[0.01, 0.05, 0.1, 0.5, 1], 
          'min_samples_split':[2,5,10,20], 
          'max_depth':[2,3,5,10]}

cv_test= KFold(n_splits=5)
clf = GridSearchCV(gbc, parameters,cv=cv_test)
clf.fit(iris.data, iris.target)

print(clf.best_params_)
person Özlem Pamuk    schedule 18.05.2019