Если вы здесь только для кода, перейдите к нижней части статьи. Вы получите то, что хотите. Если вы не против прочитать, вы также поймете, почему!

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

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

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

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

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

Почему?

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

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

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

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

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

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

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

Как?

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

import pandas as pd
import time
from sklearn.ensemble import GradientBoostingRegressor, HistGradientBoostingRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error

# Load the data into a pandas DataFrame
df = pd.read_csv("data.csv")

# Split the data into features (X) and target (y)
X = df.drop("target", axis=1)
y = df["target"]

# Split the data into training and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Train a traditional gradient boosting regressor
gb_regressor = GradientBoostingRegressor(loss="ls",
                                        learning_rate=0.1,
                                        n_estimators=100,
                                        subsample=0.8,
                                        criterion="mae",
                                        random_state=42)

start_time = time.time()
gb_regressor.fit(X_train, y_train)
gb_training_time = time.time() - start_time

# Make predictions on the test set
gb_predictions = gb_regressor.predict(X_test)

# Calculate the mean absolute error of the predictions
gb_mae = mean_absolute_error(y_test, gb_predictions)

# Train a histogram based gradient boosting regressor
hgb_regressor = HistGradientBoostingRegressor(loss="least_squares",
                                              learning_rate=0.1,
                                              n_iter_no_change=5,
                                              max_iter=100,
                                              max_leaf_nodes=31,
                                              random_state=42)

start_time = time.time()
hgb_regressor.fit(X_train, y_train)
hgb_training_time = time.time() - start_time

# Make predictions on the test set
hgb_predictions = hgb_regressor.predict(X_test)

# Calculate the mean absolute error of the predictions
hgb_mae = mean_absolute_error(y_test, hgb_predictions)

# Print the mean absolute error and training time of the two models
print(f"Mean absolute error of traditional gradient boosting: {gb_mae:.2f}")
print(f"Training time of traditional gradient boosting: {gb_training_time:.2f} seconds")
print(f"Mean absolute error of histogram based gradient boosting: {hgb_mae:.2f}")
print(f"Training time of histogram based gradient boosting: {hgb_training_time:.2f} seconds")

В этом коде мы используем класс GradientBoostingRegressor из scikit-learn для обучения традиционного регрессора повышения градиента и класс HistGradientBoostingRegressor для обучения регрессора повышения градиента на основе гистограммы. Мы используем метод fit для обучения моделей на обучающих данных и метод predict для прогнозирования тестовых данных. Наконец, мы используем функцию mean_absolute_error из scikit-learn для оценки производительности моделей и вывода средней абсолютной ошибки прогнозов.