Добрый день, уважаемые читатели. Темой сегодняшней статьи станет объединение множества трансформаторов и классификатора в конвейер sklearn с сеточным поиском лучшей комбинации параметров.
Сеточный поиск настройки гиперпараметров
Подпишись на группу Вконтакте и Телеграм-канал. Там еще больше полезного контента для программистов.
А на моем YouTube-канале ты найдешь обучающие видео по программированию. Подписывайся!
Сеточный поиск — алгоритм поиска лучшей выборки гиперпараметров модели.
Он довольно прост:
- выбираете модель обучения
- выбираете метрику оценки (
accuracy
/recall
и т.д. для классификации,R^2
для регрессии) - определяете массивы с различными вариантами значения определённого гиперпараметра
- создаёте сетку путём прямого произведения массивов (тут может быть непонятно, пример ниже)
- обучаете модель с различными вариантами настройки для определения лучшей комбинации
Пример с сеткой поиска:
C_param = [1, 2, 3] gamma_param = [10, 20, 30] C_gamma_param = [ (1, 10) (2, 10) (3, 10) (1, 20) (2, 20) (3, 10) (1, 30) (2, 30) (3, 30) ]
Конвейер sklearn
Конвейер — объединение трансформаторов и модели для последовательной обработки данных и предсказания на обработанных данных.
Трансформатор в sklearn
— класс, в котором определены методы transform
и fit_transform
.
Модель в sklearn
— класс, в котором определен метод predict
.
Конвейер в sklearn представлен классом Pipeline
из под-модуля sklearn.pipeline.
Его создание будет продемонстрировано непосредственно на практике, когда мы перейдём к нашей задаче.
Задача классификации
Задача — создать модель, которая сможет с высокой точностью предсказывать, является ли определённая звезда пульсаром, основываясь на некоторые показатели.
Прим. В реальных задачах вам нередко придётся (если уже не приходилось) ознакомиться с предметной областью. Предлагаю и здесь не нарушать эту «традицию» и прочитать в Википедии, что же такое пульсар.
В качестве набора для обучения и тестирования моделей мною был выбран датасет из Kaggle, который содержит информацию о восьми признаках различных звёзд. Я часто тестирую на этом наборе определённые модели классификации, поскольку он довольно «чист».
Модель обучения — классификатор на основе последовательной нейросети, алгоритм которой реализован в классеsklearn.neural_network.MLPClassifier
.
Создание конвейера
Я начну реализацию с импорта всех необходимых нам имён. Хоть их и можно импортировать по мере надобности в программе, однако PEP8 рекомендует делать это в начале файла.
In[1]: import pandas as pd import numpy as np from sklearn.preprocessing import StandardScaler from sklearn.pipeline import Pipeline from sklearn.model_selection import GridSearchCV from sklearn.model_selection import train_test_split from sklearn.neural_network import MLPClassifier
Загрузка данных, используя pandas
:
In[2]: pulsar_df = pd.read_csv('pulsar_stars.csv') pulsar_df.head(5)
Отделение исходных признаков от цели предсказания.
In[3]: X = pulsar_df.drop(['target_class'], axis=1).values y = pulsar_df['target_class'].values X[:1], y[:1] Out[3]: (array([[140.5625 , 55.68378214, -0.23457141, -0.6996484 , 3.19983278, 19.11042633, 7.97553179, 74.24222492]]), array([0], dtype=int64))
Также необходимо разделить данные на тренировочный и тестовый набор. Для этого используется стандартный для этой задачи инструмент — функцию train_test_split
из под-модуля sklearn.model_selection
.
In[4]: X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
Прекрасно. Теперь, когда готовы все данные, можно приступить к «постройке» конвейера.
Первым шагом моей последовательности станет стандартизация. Т. к. это понятие довольно часто использовалось в моих статьях, то просто оставлю ссылку на одну статью с описанием нормализации и стандартизации.
Алгоритм стандартизации реализован в классе StandardScaler
. Так же создадим экземпляр класса классификатора.
In[5]: scaler = StandardScaler() clf = MLPClassifier()
Далее создаём массив последовательности «шагов» конвейера. Сначала необходимо стандартизировать данные, а уже затем выполнить предсказание. Выглядит это так:
In[6]: steps = [('normalizer', scaler), ('classifier', clf)] pipe = Pipeline(steps)
Запомните, под каким «именем» я указал классификатор, в будущем это пригодится.
Сеточный поиск
Теперь пора выбирать гиперпараметры. Я осуществил поиск трёх параметров — максимального кол-ва итераций, параметра alpha
для регуляризации и кол-ва скрытых слоёв сети.
In[7]: params = \ {'classifier__solver': ['lbfgs'], 'classifier__max_iter': [300, 500, 700], 'classifier__alpha': 10.0 ** -np.arange(7, 10), 'classifier__hidden_layer_sizes': np.arange(7, 10)} grid_search = GridSearchCV(pipe, params)
Обратите внимание, как заданны имена параметров. Именно об этом шла речь чуть выше. Теперь используется метод fit()
, чтобы адаптировать нашу «модель».
Сам алгоритм сеточного поиска
In[8]: grid_search.fit(X_train, y_train) print(grid_search.score(X_test, y_test)) #0.982122905027933 grid_search.best_params_ Out[8]: {'classifier__alpha': 1e-09, 'classifier__hidden_layer_sizes': 9, 'classifier__max_iter': 700, 'classifier__solver': 'lbfgs'}
С помощью метода score()
проводится оценка точности модели на тестовых данных, в атрибуте best_params_
хранится словарь с лучшей комбинацией гиперпараметров.
Заключение
В этой статье я продемонстрировал реализацию простого конвейера, а также провёл сеточный поиск, используя для этих задач библиотеку машинного обучения sklearn
.
Надеюсь этот материал был вам полезен. Желаю вам незатухающего градиента и данных без шумов.
Документ .ipynb с исходным кодом можно загрузить и просмотреть по ссылке.
Также рекомендую прочитать статью Анализ данных PornHub или двойное проникновение в визуализацию. А также подписывайтесь на группу ВКонтакте, Telegram и YouTube-канал. Там еще больше полезного и интересного для программистов.