Вопрос или проблема
Насколько я знаю, и поправьте меня, если я не прав, использование кросс-валидации для настройки гиперпараметров нецелесообразно, когда у меня есть огромный набор данных. В таком случае лучше разделить данные на обучающий, валидационный и тестовый наборы; а затем выполнять настройку гиперпараметров с помощью валидационного набора.
В случае, если я программирую, я хотел бы использовать scikit, набор данных о дрожжах, доступный по адресу: http://archive.ics.uci.edu/ml/datasets/yeast; и, например, настроить количество эпох.
Сначала я разделил свой обучающий, валидационный и тестовый наборы, используя train_test_split дважды в соответствии с одним ответом, который я видел здесь. График потерь, который я получил, следующий для 1500 максимальных итераций:
Затем я хотел использовать свой валидационный набор с списком различных значений для гиперпараметра максимальных итераций. График, который я получил, следующий (с некоторыми сообщениями предупреждения о не-сходимости для значений max_iter менее 1500):
Итак, у меня есть первый вопрос. Похоже, что для значения max_iter равного 3000 точность составляет примерно 64%, так что мне следует выбрать это значение для гиперпараметра max_iter; это правильно? Я вижу по графику, что также красная линия 3000 имеет меньшее значение потерь, чем другие сравниваемые варианты.
Моя программа на данный момент следующая:
import numpy as np
import pandas as pd
from sklearn import model_selection, linear_model
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from sklearn.neural_network import MLPClassifier
import matplotlib.pyplot as plt
from sklearn.model_selection import GridSearchCV
def readFile(file):
head=["seq_n","mcg","gvh","alm","mit","erl","pox","vac","nuc","site"]
f=pd.read_csv(file,delimiter=r"\s+")
f.columns=head
return f
def NeuralClass(X,y):
X_train,X_test,y_train,y_test=model_selection.train_test_split(X,y,test_size=0.2)
print (len(X)," ",len(X_train))
X_tr,X_val,y_tr,y_val=model_selection.train_test_split(X_train,y_train,test_size=0.2)
mlp=MLPClassifier(activation="relu",max_iter=1500)
mlp.fit(X_train,y_train)
print (mlp.score(X_train,y_train))
plt.plot(mlp.loss_curve_)
max_iter_c=[500,1000,2000,3000]
for item in max_iter_c:
mlp=MLPClassifier(activation="relu",max_iter=item)
mlp.fit(X_val,y_val)
print (mlp.score(X_val,y_val))
plt.plot(mlp.loss_curve_)
plt.legend(max_iter_c)
def main():
f=readFile("yeast.data")
list=["seq_n","site"]
X=f.drop(list,1)
y=f["site"]
NeuralClass(X,y)
Второй вопрос, является ли мой подход действительным? Я видел много информации в интернете, и все указывают на кросс-валидацию для настройки гиперпараметров, но я хочу провести ее с помощью валидационного набора.
Любая помощь?
PD. Я пытался использовать раннюю остановку, и результаты были плохими по сравнению с теми, которые я получил с помощью метода, который я запрограммировал.
Спасибо
Мне кажется, что вы вручную итерируете через гиперпараметры.
scikit-learn
имеет множество вспомогательных функций, которые упрощают перебор всех параметров с использованием различных стратегий: https://scikit-learn.org/stable/modules/grid_search.html#grid-search
Во-вторых, если бы я “вручную” настраивал гиперпараметры, я бы разделил свои данные на 3: обучение, тестирование и валидацию (названия не важны)
Я бы изменил свои гиперпараметры, обучил модель, используя обучающие данные
, протестировал ее, используя тестовые данные
. Я бы повторял этот процесс до тех пор, пока не получил “лучшие” параметры, а затем в конце провел бы проверку с использованием валидационных данных
в качестве sanity check (должны быть похожие оценки).
С помощью вспомогательных функций scikit-learn
я просто разделяю данные на две части. Использую GridSearchCV
с одной частью, а затем в конце, используя лучшие параметры (сохраненные в атрибуте best_estimator_
), провожу проверку с помощью второй части.
# определение перебора параметров
param_grid = { 'max_iter' : [100, 1000, 10000] }
# определение сеточного поиска
clf = GridSearchCV(mlp, param_grid, cv=5)
# выполнение поиска
clf.fit(X, y)
# лучший оценщик
clf._best_estimator
Для информации, каждый оценщик и их соответствующие оценки также доступны как атрибуты (см. https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html#sklearn.model_selection.GridSearchCV), что означает, что вы можете проверить результат каждой CV, если хотите убедиться, что получили лучшие параметры.
Как видите, вы можете избежать чрезмерных размышлений о том, было ли CV правильным подходом, используя в конечном итоге валидационный набор в качестве sanity check.
Ответ или решение
Тонкая настройка гиперпараметров с использованием валидационного набора данных
В современных задачах машинного обучения выбор оптимальных гиперпараметров модели является критически важным этапом, влияющим на качество и точность предсказаний. Работая с большими наборами данных, как в случае с используемым вами набором данных по дрожжам (yeast dataset), зачастую стоит предпочесть метод валидационного набора данных для настройки гиперпараметров, особенно если традиционная перекрестная проверка оказывается ресурсоемкой.
1. Обоснование разделения данных
Как вы правильно заметили, при работе с большими наборами данных целесообразно разделить данные на три части: обучающую, валидационную и тестовую выборки. Обучающая выборка используется для обучения модели, валидационная — для настройки гиперпараметров, а тестовая — для конечной оценки производительности модели на данных, которые модель не видела ранее.
2. Процесс настройки гиперпараметров
Ваше решение использовать валидационный набор данных для настройки параметров, таких как max_iter
, вполне обосновано. Убедитесь, что подходящие значения для max_iter
выбраны в зависимости от результатов валидационной выборки. Судя по графику, значение max_iter = 3000
обеспечивает наилучший результат, что поддерживается как точностью, так и значением функции потерь. Следовательно, вы можете выбрать 3000 как оптимальное значение для гиперпараметра max_iter
.
3. Код для настройки гиперпараметра
Ваш код в целом реализует идею, однако можно оптимизировать его, используя функции скейта Scikit-learn, сэкономив время и усилия:
from sklearn.model_selection import GridSearchCV
# Определим диапазон гиперпараметров для поиска
param_grid = {'max_iter': [500, 1000, 1500, 3000]}
# Создаем экземпляр MLPClassifier и GridSearchCV
mlp = MLPClassifier(activation="relu")
grid_search = GridSearchCV(mlp, param_grid, cv=5)
# Обучение модели
grid_search.fit(X_tr, y_tr)
# Получение лучшей модели
best_model = grid_search.best_estimator_
print(f"Лучшие гиперпараметры: {grid_search.best_params_}")
# Проверка на валидационном наборе
validation_score = best_model.score(X_val, y_val)
print(f"Точность на валидационном наборе: {validation_score}")
4. Заключение
Ваш подход к настройке гиперпараметров не только применим, но и может быть улучшен с использованием встроенных инструментов Scikit-learn. Важно помнить, что использование валидационного набора данных для итоговой проверки качества модели — это оправданный и обоснованный выбор, особенно когда ресурсы вычисления ограничены.
Использование таких инструментов, как GridSearchCV
, поможет вам эффективно находить параметры, которые позволяют лучшему соответствовать вашим данным, не теряя в качестве, а также сохраняя время и ресурсы. Успехов в ваших дальнейших экспериментах с моделью!