Введение

Модели машинного обучения часто требуют тонкой настройки для достижения оптимальной производительности в заданном наборе данных. Оптимизация гиперпараметров играет решающую роль в этом процессе. В этой статье мы рассмотрим концепции гиперпараметров, способы их установки и методы поиска наилучшей гиперпараметризации для данной проблемы. Мы будем использовать набор данных алмазов, доступный на Kaggle, и работать с Google Colab для наших примеров кода. Две цели, с которыми мы будем работать, это «карат» и «цена».

Что такое гиперпараметры (и разница между параметрами модели)

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

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

Настройка гиперпараметров (также обсудите значения по умолчанию)

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

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

Поиск лучшей гиперпараметризации

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

Настройте с помощью CV поиска по сетке (используйте «cut» в качестве целевой переменной)

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

Давайте продемонстрируем поиск по сетке, используя набор данных алмазов и целевую переменную «карат».

Вместо этого мы будем использовать переменную «cut» в качестве цели. Поскольку «cut» — это категориальная переменная, мы будем использовать RandomForestClassifier из scikit-learn. Основные гиперпараметры, которые мы будем настраивать с помощью GridSearchCV, — это n_estimators, max_depth и min_samples_split.

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

# Import necessary libraries
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV

# Load the dataset
url = "https://raw.githubusercontent.com/fenago/datasets/main/diamonds.csv"
diamonds = pd.read_csv(url)

# Preprocessing
label_encoder = LabelEncoder()
diamonds['cut'] = label_encoder.fit_transform(diamonds['cut'])
diamonds['color'] = label_encoder.fit_transform(diamonds['color'])
diamonds['clarity'] = label_encoder.fit_transform(diamonds['clarity'])

# Split the dataset into training and test sets
X = diamonds.drop('cut', axis=1)
y = diamonds['cut']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Scale the features
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

Теперь, когда наш набор данных предварительно обработан и готов к использованию, мы можем создать модель RandomForestClassifier и настроить GridSearchCV.

# Create a RandomForestClassifier model
rf = RandomForestClassifier()

# Define hyperparameters to be tuned
hyperparameters = {
    'n_estimators': [10, 50, 100, 200],
    'max_depth': [None, 10, 20, 30],
    'min_samples_split': [2, 5, 10]
}

# Create the GridSearchCV object
grid_search = GridSearchCV(estimator=rf, param_grid=hyperparameters, cv=5, n_jobs=-1, verbose=1)

# Fit the model on the training set
grid_search.fit(X_train, y_train)

# Get the best hyperparameters found by GridSearchCV
best_params = grid_search.best_params_
print("Best hyperparameters found by GridSearchCV:", best_params)

# Evaluate the model on the test set
test_score = grid_search.score(X_test, y_test)
print("Test set accuracy with best hyperparameters:", test_score)

В этом примере мы загружаем набор данных бриллиантов и предварительно обрабатываем категориальные признаки с помощью LabelEncoder. Затем мы разделяем набор данных на обучающие и тестовые наборы и масштабируем функции с помощью StandardScaler.

Затем мы создаем модель RandomForestClassifier и определяем гиперпараметры для настройки с помощью GridSearchCV. Мы проводим 5-кратную перекрестную проверку и используем все доступные ядра ЦП для параллельной обработки (n_jobs=-1). После подгонки модели к обучающему набору мы печатаем лучшие гиперпараметры, найденные GridSearchCV, и оцениваем точность модели на тестовом наборе.

Теперь, когда мы увидели, как можно использовать GridSearchCV для оптимизации гиперпараметров, давайте обсудим некоторые дополнительные сведения и советы.

  1. GridSearchCV исследует все комбинации гиперпараметров, а это означает, что он может потребовать значительных вычислительных ресурсов, особенно когда существует много возможных значений для каждого гиперпараметра. Помните об этом при определении пространства поиска гиперпараметров.
  2. При работе с большими наборами данных может оказаться полезным использовать меньшее подмножество данных или уменьшить количество перекрестных проверок, чтобы ускорить процесс.
  3. Всегда убедитесь, что вы используете подходящую метрику оценки для вашей проблемы. По умолчанию GridSearchCV использует метод оценки score (точность для классификации, R^2 для регрессии). Однако вы также можете указать пользовательские функции оценки.
  4. Помимо RandomForestClassifier, scikit-learn предлагает множество других классификаторов, таких как LogisticRegression, KNeighborsClassifier и SupportVectorClassifier. Вы можете поэкспериментировать с этими моделями и настроить их гиперпараметры с помощью GridSearchCV, следуя подходу, аналогичному показанному в этом примере.
  5. Наконец, помните, что GridSearchCV не всегда может быть лучшим выбором для оптимизации гиперпараметров. Как обсуждалось ранее, возможно, стоит рассмотреть альтернативы, такие как RandomizedSearchCV или методы байесовской оптимизации, особенно при работе с большими пространствами поиска или ограниченными вычислительными ресурсами.

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

Преимущества и недостатки поиска по сетке

Преимущества:

  1. Системный подход — тестируются все возможные комбинации в заданной сетке.
  2. Может найти оптимальные значения гиперпараметров, если они находятся в пределах области поиска.

Недостатки:

  1. Вычислительно дорого — особенно для больших областей поиска и сложных моделей.
  2. Может не найти оптимальные гиперпараметры, если они лежат за пределами определенного пространства поиска.

Random Search CV (используйте «цену» в качестве целевой переменной)

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

Давайте продемонстрируем случайный поиск, используя набор данных алмазов и целевую переменную «цена».

Теперь мы будем использовать переменную «цена» в качестве цели и продемонстрируем RandomizedSearchCV для оптимизации гиперпараметров. Поскольку «цена» — непрерывная переменная, мы будем использовать RandomForestRegressor из scikit-learn. Основные гиперпараметры, которые мы будем настраивать с помощью RandomizedSearchCV, — это n_estimators, max_depth и min_samples_split.

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

# Import necessary libraries
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import RandomizedSearchCV

# Load the dataset
url = "https://raw.githubusercontent.com/fenago/datasets/main/diamonds.csv"
diamonds = pd.read_csv(url)

# Preprocessing
label_encoder = LabelEncoder()
diamonds['cut'] = label_encoder.fit_transform(diamonds['cut'])
diamonds['color'] = label_encoder.fit_transform(diamonds['color'])
diamonds['clarity'] = label_encoder.fit_transform(diamonds['clarity'])

# Split the dataset into training and test sets
X = diamonds.drop('price', axis=1)
y = diamonds['price']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Scale the features
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

Теперь, когда наш набор данных предварительно обработан и готов к использованию, мы можем создать модель RandomForestRegressor и настроить RandomizedSearchCV.

# Create a RandomForestRegressor model
rf = RandomForestRegressor()

# Define hyperparameters to be tuned
hyperparameters = {
    'n_estimators': [10, 50, 100, 200],
    'max_depth': [None, 10, 20, 30],
    'min_samples_split': [2, 5, 10]
}

# Create the RandomizedSearchCV object
random_search = RandomizedSearchCV(estimator=rf, param_distributions=hyperparameters, n_iter=10, cv=5, n_jobs=-1, verbose=1, random_state=42)

# Fit the model on the training set
random_search.fit(X_train, y_train)

# Get the best hyperparameters found by RandomizedSearchCV
best_params = random_search.best_params_
print("Best hyperparameters found by RandomizedSearchCV:", best_params)

# Evaluate the model on the test set
test_score = random_search.score(X_test, y_test)
print("Test set R^2 score with best hyperparameters:", test_score)

В этом примере мы загружаем набор данных бриллиантов и предварительно обрабатываем категориальные признаки с помощью LabelEncoder. Затем мы разделяем набор данных на обучающие и тестовые наборы и масштабируем функции с помощью StandardScaler.

Затем мы создаем модель RandomForestRegressor и определяем гиперпараметры для настройки с помощью RandomizedSearchCV. Мы проводим 5-кратную перекрестную проверку и используем все доступные ядра ЦП для параллельной обработки (n_jobs=-1). После подгонки модели к обучающему набору мы печатаем лучшие гиперпараметры, найденные с помощью RandomizedSearchCV, и оцениваем показатель R^2 модели на тестовом наборе.

Теперь, когда мы увидели, как RandomizedSearchCV можно использовать для оптимизации гиперпараметров, давайте обсудим некоторые дополнительные идеи и советы.

  1. В отличие от GridSearchCV, RandomizedSearchCV не исследует все комбинации гиперпараметров. Вместо этого он выбирает фиксированное количество комбинаций (определяется параметром n_iter). Это делает его более эффективным с точки зрения вычислений, особенно когда существует много возможных значений для каждого гиперпараметра.
  2. RandomizedSearchCV может исследовать более широкий диапазон значений гиперпараметров по сравнению с GridSearchCV, что может помочь найти лучшие комбинации.
  3. Как и в случае с GridSearchCV, помните о вычислительных затратах при определении пространства поиска гиперпараметров. Вы можете контролировать количество итераций, чтобы сбалансировать точность поиска и время вычислений.
  4. При работе с большими наборами данных может оказаться полезным использовать меньшее подмножество данных или уменьшить количество перекрестных проверок, чтобы ускорить процесс.
  5. Всегда убедитесь, что вы используете подходящую метрику оценки для вашей проблемы. По умолчанию RandomizedSearchCV использует метод оценки score (точность для классификации, R^2 для регрессии). Однако вы также можете указать пользовательские функции оценки.
  6. Помимо RandomForestRegressor, scikit-learn предлагает множество других регрессоров, таких как LinearRegression, Ridge, Lasso и SupportVectorRegressor. Вы можете поэкспериментировать с этими моделями и настроить их гиперпараметры с помощью RandomizedSearchCV, следуя подходу, аналогичному показанному в этом примере.
  7. Наконец, помните, что RandomizedSearchCV — это всего лишь один из вариантов оптимизации гиперпараметров. Как обсуждалось ранее, возможно, стоит рассмотреть альтернативы, такие как GridSearchCV или методы байесовской оптимизации, особенно при работе с конкретными требованиями к пространству поиска или вычислительными ограничениями.

В заключение, RandomizedSearchCV предлагает более эффективный подход к поиску оптимальных гиперпараметров по сравнению с GridSearchCV, особенно при работе с большими пространствами поиска. Он позволяет исследовать более широкий диапазон значений гиперпараметров с меньшим количеством итераций, что делает его подходящим выбором для многих задач машинного обучения. Как всегда, помните о компромиссах и вычислительных требованиях и при необходимости изучайте альтернативные методы. Удачного тюнинга!

Преимущества и недостатки случайного поиска

Преимущества:

  1. Более эффективен, чем поиск по сетке, особенно для больших областей поиска.
  2. Может исследовать более широкий диапазон значений гиперпараметров.
  3. Можно найти хороший набор гиперпараметров с меньшим количеством итераций.

Недостатки:

  1. Отсутствует систематический подход Grid Search.
  2. Может потребоваться больше итераций, чтобы найти оптимальные гиперпараметры.
  3. Производительность зависит от количества итераций и стратегии выборки.

Байесовская оптимизация

В этом бонусном разделе мы продемонстрируем оптимизацию гиперпараметров с использованием байесовской оптимизации с моделью XGBoost. Мы будем использовать переменную «карат» в качестве цели. Поскольку «карат» — непрерывная переменная, мы будем использовать XGBRegressor из библиотеки XGBoost.

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

!pip install bayesian-optimization
# Import necessary libraries
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, LabelEncoder
import xgboost as xgb
from bayes_opt import BayesianOptimization

# Load the dataset
url = "https://raw.githubusercontent.com/fenago/datasets/main/diamonds.csv"
diamonds = pd.read_csv(url)

# Preprocessing
label_encoder = LabelEncoder()
diamonds['cut'] = label_encoder.fit_transform(diamonds['cut'])
diamonds['color'] = label_encoder.fit_transform(diamonds['color'])
diamonds['clarity'] = label_encoder.fit_transform(diamonds['clarity'])

# Split the dataset into training and test sets
X = diamonds.drop('carat', axis=1)
y = diamonds['carat']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Scale the features
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

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

# Function to optimize
def xgb_cv(n_estimators, max_depth, gamma, min_child_weight, subsample, data, target):
    estimator = xgb.XGBRegressor(
        n_estimators=int(n_estimators),
        max_depth=int(max_depth),
        gamma=gamma,
        min_child_weight=min_child_weight,
        subsample=subsample,
        random_state=42,
    )
    cval = cross_val_score(estimator, data, target, scoring='neg_mean_squared_error', cv=5)
    return cval.mean()

# BayesianOptimization
def optimize_xgb(data, target):
    def xgb_crossval(n_estimators, max_depth, gamma, min_child_weight, subsample):
        return xgb_cv(
            n_estimators=n_estimators,
            max_depth=max_depth,
            gamma=gamma,
            min_child_weight=min_child_weight,
            subsample=subsample,
            data=data,
            target=target,
        )

    optimizer = BayesianOptimization(
        f=xgb_crossval,
        pbounds={
            "n_estimators": (50, 500),
            "max_depth": (3, 10),
            "gamma": (0, 1),
            "min_child_weight": (0, 10),
            "subsample": (0.5, 1),
        },
        random_state=42,
        verbose=2,
    )
    optimizer.maximize(init_points=5, n_iter=10)
    return optimizer.max

Теперь мы будем использовать функцию optimize_xgb для выполнения байесовской оптимизации гиперпараметров модели XGBoost.

from sklearn.model_selection import cross_val_score

# Find optimal hyperparameters using Bayesian Optimization
best_params = optimize_xgb(X_train, y_train)
print("Best hyperparameters found by Bayesian Optimization:", best_params)

# Train the XGBoost model with the best hyperparameters
best_xgb = xgb.XGBRegressor(
    n_estimators=int(best_params["params"]["n_estimators"]),
    max_depth=int(best_params["params"]["max_depth"]),
    gamma=best_params["params"]["gamma"],
    min_child_weight=best_params["params"]["min_child_weight"],
    subsample=best_params["params"]["subsample"],
    random_state=42,
)

best_xgb.fit(X_train, y_train)

# Evaluate the model on the test set
from sklearn.metrics import mean_squared_error, r2_score

y_pred = best_xgb.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print("Test set Mean Squared Error with best hyperparameters:", mse)
print("Test set R^2 score with best hyperparameters:", r2)

В этом примере мы загружаем набор данных бриллиантов и предварительно обрабатываем категориальные признаки с помощью LabelEncoder. Затем мы разделяем набор данных на обучающие и тестовые наборы и масштабируем функции с помощью StandardScaler.

Затем мы определяем функцию xgb_cv, которая вычисляет среднеквадратичную ошибку с перекрестной проверкой для заданного набора гиперпараметров. Затем мы создаем функцию optimize_xgb, которая использует байесовскую оптимизацию для оптимизации функции xgb_cv.

Наконец, мы используем функцию optimize_xgb, чтобы найти лучшие гиперпараметры для модели XGBoost, обучить модель с помощью этих гиперпараметров и оценить ее производительность на тестовом наборе, используя среднеквадратичную ошибку и оценку R^2.

Использование байесовской оптимизации с XGBoost может дать отличные результаты для настройки гиперпараметров, часто обеспечивая лучшую производительность, чем GridSearchCV или RandomizedSearchCV. Этот подход может быть более эффективным в вычислительном отношении и исследовать более широкий диапазон значений гиперпараметров. Однако важно отметить, что байесовская оптимизация может быть более сложной в реализации и не всегда может гарантировать лучшие результаты. Обязательно поэкспериментируйте с различными методами оптимизации и настройками гиперпараметров, чтобы найти наилучшую конфигурацию для вашей конкретной проблемы. Удачного тюнинга!

Заключение

В этой статье мы обсудили важность гиперпараметров в моделях машинного обучения и способы их оптимизации с помощью методов поиска в сетке и случайного поиска. Мы продемонстрировали оба метода, используя набор данных по бриллиантам с параметрами «карат» и «цена» в качестве целевых переменных.

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

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