Узнайте, как использовать функцию GridSearchCV в sklearn для оптимизации вашей модели машинного обучения

Двумя ключевыми проблемами машинного обучения являются поиск правильного алгоритма для использования и оптимизация вашей модели. Если вы знакомы с машинным обучением, вы, возможно, работали с такими алгоритмами, как линейная регрессия, логистическая регрессия, деревья решений, машины опорных векторов и т. Д. После того, как вы решили использовать конкретный алгоритм для своей модели машинного обучения, следующая задача заключается в том, как для точной настройки гиперпараметров вашей модели, чтобы ваша модель хорошо работала с имеющимся у вас набором данных. В этой статье я хочу сосредоточиться на последней части - настройке гиперпараметров вашей модели. Каким бы сложным ни казался этот термин, точную настройку гиперпараметров на самом деле можно довольно легко выполнить с помощью функции GridSearchCV в модуле sklearn.

Выполнение классификации с использованием логистической регрессии

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

Для решения проблемы классификации вы также можете использовать другие алгоритмы, такие как машины опорных векторов (SVM), K-Nearest Neighbours (KNN), Naive Bayes и другие. Но в этой статье я буду использовать логистическую регрессию.

Во-первых, давайте загрузим набор данных и загрузим его в Pandas DataFrame:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
bc = load_breast_cancer()
df = pd.DataFrame(bc.data, columns = bc.feature_names)
df['diagnosis'] = bc.target
df

Первые 30 столбцов представляют собой различные признаки, а последний столбец - диагноз (0 для злокачественных и 1 для доброкачественных). Для простоты я буду использовать 30 столбцов для обучения и последний столбец в качестве цели.

В идеале вы должны выполнить выбор функций, чтобы отфильтровать те столбцы, которые демонстрируют коллинеарность, а также столбцы, которые не имеют сильной корреляции с целью.

Давайте извлечем значения для функций и меток и сохраним их в виде массивов:

dfX = df.iloc[:,:-1]   # Features - 30 columns
dfy = df['diagnosis']  # Label - last column
X = dfX.values
y = dfy.values
print(X.shape)   # (569, 30); 2D array
print(y.shape)   # (569,);    1D array

Разделите набор данных на обучающий набор и набор для тестирования:

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y,
                                       test_size=0.25, 
                                       random_state=2)

На следующем рисунке показано использование наборов данных для обучения и тестирования:

Затем стандартизируйте наборы данных для обучения и тестирования:

from sklearn import preprocessing
scaler = preprocessing.StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.fit_transform(X_test)

Класс StandardScaler изменяет масштаб данных, чтобы получить среднее значение 0 и стандартное отклонение 1 (единичное отклонение).

Стандартизация набора данных является общим требованием для многих оценщиков машинного обучения: они могут вести себя плохо, если отдельные функции не более или менее выглядят как стандартные нормально распределенные данные (например, по Гауссу с нулевым средним и единичной дисперсией). Источник: https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.StandardScaler.html

Наконец, используйте класс LogisticRegression из sklearn для построения модели с использованием обучающего набора, а затем используйте набор тестирования для получения прогнозов для всех элементов в наборе тестирования:

from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression()
logreg.fit(X_train,y_train)
y_pred = logreg.predict(X_test)

Чтобы узнать, насколько хорошо работает ваша модель, узнайте ее точность:

from sklearn import metrics
print("Accuracy:",metrics.accuracy_score(y_test, y_pred))
# OR
print("Accuracy:",logreg.score(X_test, y_test))

Вы можете получить точность, используя функцию score () модели, которую вы только что построили, или функцию precision_score () из метрик модуль.

Точность приведенного выше фрагмента кода:

Accuracy: 0.9790209790209791

Понимание перекрестной проверки

Чтобы понять, как оптимизировать вашу модель, построенную с использованием предыдущего раздела с помощью GridSearchCV, вам необходимо понять, что такое перекрестная проверка. Помните, в предыдущем разделе мы разделили набор данных на обучающий и тестовый?

Набор для тестирования используется для оценки производительности модели, которую вы обучили с помощью набора для обучения. Хотя это хороший способ оценить модель, он может не дать вам точного представления о ее характеристиках. Насколько вам известно, данные в наборе для тестирования могут быть искажены, и их использование для оценки модели может дать очень предвзятый результат. Гораздо лучший способ - разделить весь набор данных на k-кратные (или k-части, то есть k-кратное означает разделение набора данных на 10 равных частей). Из k-кратных складок используйте 1 кратность для тестирования и k-1 кратность для обучения:

На каждой итерации записывайте показатели (например, точность, точность и т. Д.), А в конце всех итераций вычисляйте среднее значение этих показателей. Это дает вашей модели хорошее сочетание ваших данных для обучения и тестирования и дает лучший тест производительности вашей модели. Этот процесс разделения ваших данных на k-кратное смещение и использование 1 кратного для тестирования и k-1 кратного для тестирования известен как перекрестная проверка k-кратности.

Использование GridSearchCV для настройки гиперпараметров

В нашем предыдущем примере класса LogisticRegression мы создали экземпляр класса LogisticRegression, не передавая ему никаких инициализаторов. Вместо этого мы полагаемся на значения по умолчанию для различных параметров, таких как:

  • штраф - укажите норму штрафа.
  • C - величина, обратная силе регуляризации; меньшие значения указывают на более сильную регуляризацию.
  • решатель - алгоритм для использования в задаче оптимизации.
  • max_iter - максимальное количество итераций, необходимых для схождения решателей.

Хотя в некоторых случаях можно полагаться на значения этих параметров по умолчанию (известные как гиперпараметры в машинном обучении), всегда хорошо иметь возможность точно настроить их значения, чтобы алгоритм работал. лучше всего подходит для вашего типа данных. К сожалению, найти идеальную комбинацию гиперпараметров, идеально подходящую для ваших данных, - нетривиальная задача. Здесь на помощь приходит GridSearchCV.

GridSearchCV - это функция, которая входит в пакет model_selection sklearn. Это позволяет вам указать разные значения для каждого гиперпараметра и опробовать все возможные комбинации при подборе вашей модели. Он выполняет обучение и тестирование с использованием перекрестной проверки вашего набора данных - отсюда и аббревиатура «CV» в GridSearchCV. Конечным результатом GridSearchCV является набор гиперпараметров, которые наилучшим образом соответствуют вашим данным в соответствии с метрикой скоринга, по которой вы хотите оптимизировать свою модель.

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

from sklearn.model_selection import GridSearchCV
import warnings
warnings.filterwarnings('ignore')
# parameter grid
parameters = {
    'penalty' : ['l1','l2'], 
    'C'       : np.logspace(-3,3,7),
    'solver'  : ['newton-cg', 'lbfgs', 'liblinear'],
}

Обратите внимание, что я отключил предупреждения, поскольку функция GridSearchCV () имеет тенденцию генерировать довольно много предупреждений.

Затем вы можете вызвать функцию GridSearchCV (), используя алгоритм, который вы используете, вместе с различными аргументами, как показано ниже:

logreg = LogisticRegression()
clf = GridSearchCV(logreg,                    # model
                   param_grid = parameters,   # hyperparameters
                   scoring='accuracy',        # metric for scoring
                   cv=10)                     # number of folds

Функция GridSearchCV () возвращает экземпляр LogisticRegression (в этом примере, основанный на используемом вами алгоритме), который затем можно обучить, используя свой обучающий набор:

clf.fit(X_train,y_train)

Когда вы закончите обучение, вы можете распечатать настроенные гиперпараметры, а также точность обучения:

print("Tuned Hyperparameters :", clf.best_params_)
print("Accuracy :",clf.best_score_)

Вот результат, который я получил при запуске приведенного выше фрагмента кода:

Tuned Hyperparameters : {'C': 0.1, 
                         'penalty': 'l2', 
                         'solver': 'liblinear'}
Accuracy : 0.983499446290144

Точность 0,9835 теперь намного лучше, чем прежняя точность 0,9790.

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

logreg = LogisticRegression(C = 0.1, 
                            penalty = 'l2', 
                            solver = 'liblinear')
logreg.fit(X_train,y_train)
y_pred = logreg.predict(X_test)
print("Accuracy:",logreg.score(X_test, y_test))

На следующем рисунке показано, что мы сделали:

Обратите внимание:

  • GridSearchCV использует обучающий набор и набор проверки для выполнения перекрестной проверки.
  • Как только GridSearchCV нашел значения для гиперпараметров, мы используем настроенные значения параметров для построения новой модели с использованием обучающего набора.
  • Используя набор для тестирования, теперь мы можем оценить нашу новую модель.

Применяемый здесь подход позволяет нам иметь метрику, с помощью которой мы можем измерить эффективность нашей новой модели.

Другой способ использования GridSearchCV - подогнать его с использованием всего набора данных, как показано ниже:

parameters = {
    'penalty' : ['l1','l2'], 
    'C'       : np.logspace(-3,3,7),
    'solver'  : ['newton-cg', 'lbfgs', 'liblinear'],
}
logreg = LogisticRegression()
clf = GridSearchCV(logreg, 
                   param_grid = parameters,
                   scoring = 'accuracy', 
                   cv = 10)
clf.fit(X,y)

Приведенный выше фрагмент кода возвращает следующий результат:

Tuned Hyperparameters : {'C': 1000.0, 
                         'penalty': 'l1', 
                         'solver': 'liblinear'}
Accuracy : 0.9701754385964911

На следующем рисунке показано, что мы только что сделали:

В этом случае вы позволяете GridSearchCV использовать весь набор данных для получения настроенных параметров, а затем использовать вновь полученные значения для построения новой модели.

Применяемый здесь подход позволяет нам определить лучшие гиперпараметры для нашего набора данных, но не позволяет точно оценить вашу модель.

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

Резюме

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

Вот ссылки на мои предыдущие статьи о выборе функций: