Ответ
При обучении градиентного бустинга (Gradient Boosting) на каждом шаге построения нового базового алгоритма (обычно дерева) вычисляется антиградиент функции потерь относительно текущих предсказаний модели. Размерность этого градиента равна числу объектов в обучающей выборке n.
Объяснение:
Мы оптимизируем аддитивную модель F(x) = sum_{m=1}^{M} gamma_m * h_m(x), минимизируя эмпирический риск L(y, F(x)). На шаге m мы фиксируем текущую модель F_{m-1}(x) и ищем базовый алгоритм h_m(x), который лучше всего аппроксимирует антиградиент.
Градиент вычисляется для каждого объекта обучающей выборки:
g_i = - [∂L(y_i, F(x_i)) / ∂F(x_i)], где i = 1, ..., n.
Пример расчета для квадратичной ошибки (MSE) в Python:
import numpy as np
# Исходные данные: n = 5 объектов
y_true = np.array([3.0, 5.1, 2.8, 6.0, 4.2]) # Истинные значения
F_current = np.array([2.5, 4.9, 3.2, 5.5, 4.0]) # Текущие предсказания модели
# Функция потерь MSE: L(y, F) = (y - F)^2 / n
# Градиент по F: dL/dF = 2 * (F - y) / n
gradient = 2 * (F_current - y_true) / len(y_true)
print("Вектор градиента (размерность n):")
print(gradient)
print(f"Форма градиента: {gradient.shape}") # Вывод: (5,)
Как это используется в алгоритмах (XGBoost, LightGBM, CatBoost):
- Для каждого объекта вычисляется значение градиента
g_i. - Новое дерево строится так, чтобы его предсказания
h_m(x_i)были как можно ближе к-g_i(решается задача аппроксимации градиента). По сути, мы обучаем дерево регрессии на псевдо-остатках. - Для задач классификации (логистическая потеря) градиент имеет другую формулу, но его размерность по-прежнему
(n,)(или(n, n_classes)для многоклассовой).
Итог: Размерность (n,) фундаментальна, так как градиентный бустинг — это итеративная оптимизация в пространстве значений модели на конкретных обучающих точках.
Ответ 18+ 🔞
Э, слушай, тут один вопрос про градиентный бустинг, который у всех в голове кашу делает. Разбираемся, чтобы не быть мандой с ушами.
Короче, представь: ты учишь эту адскую модель, и на каждом шаге она пытается исправить свои же косяки. Как? Считает, насколько она обосралась на каждом конкретном примере из твоей выборки. Вот эта вот величина «насколько обосралась» — это и есть антиградиент, или, как умные говорят, псевдо-остаток.
Суть в чём: размерность этого самого вектора градиента — это ровно столько, сколько у тебя объектов в обучающей выборке, n. Потому что для каждого чувака i в твоих данных ты считаешь свою отдельную производную потерь. Не в общем, а именно для его предсказания. Получается вектор длиной n, где на i-той позиции написано, грубо говоря, «эй, модель, вот тут ты проебалась на столько-то».
Пример, чтобы не быть полупидором в теме. Берём самую простую потерю — MSE, квадраты ошибок.
import numpy as np
# Допустим, у нас 5 наблюдений (n = 5)
y_true = np.array([3.0, 5.1, 2.8, 6.0, 4.2]) # То, что было на самом деле
F_current = np.array([2.5, 4.9, 3.2, 5.5, 4.0]) # То, что наша модель сейчас наворотила
# Считаем градиент для MSE. Формулу помнишь? dL/dF = 2*(F - y)/n
gradient = 2 * (F_current - y_true) / len(y_true)
print("Вектор градиента (размерность n):")
print(gradient) # Смотри, пять чисел — по одному на каждый объект!
print(f"Форма градиента: {gradient.shape}") # Вот тебе и (5,)
Видишь? (5,). Не (5, 10), не (1,), а ровно n чисел. Вот это и есть тот самый вектор, который размерности (n,). Каждое число — это указание дереву, которое мы будем строить следующим: «смотри, на этом примере вот на столько ты должен скорректировать предсказание вверх или вниз».
Как это впихивают в XGBoost, LightGBM и прочие CatBoost'ы? Всё просто до охуения:
- На каждой итерации для всей твоей выборки из
nобъектов высчитывается этот самый вектор градиентаg_i. Это и есть целевые значения для обучения нового дерева. - Потом говорят: «Так, дерево-регрессор, иди сюда. Вот тебе фичи
X, а вот целевая переменная — этот самый вектор-g_i(антиградиент). Научись его предсказывать». Дерево строят, чтобы его листовые значения были как можно ближе к этим самым целевым поправкам. - Для классификации формула градиента другая, ёпта, но принцип тот же — на выходе будет вектор размерности
(n,)для бинарной задачи или(n, n_classes)для многоклассовой. Суть не меняется — учимся на ошибках для каждого объекта в отдельности.
Итог, блядь: Размерность (n,) — это не просто так, это фундамент. Потому что градиентный бустинг — это не какая-то абстрактная хуйня, а итеративная подгонка модели под конкретные косяки на конкретных точках данных. Каждому объекту — своя персональная поправка. Вот и вся магия, без всякой ебушки-воробушки.