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

Но что, если они хотят спрогнозировать не только одну оценку, но и вероятный диапазон? Это называется интервалом прогнозирования, а общий метод их получения известен как квантильная регрессия. В этом посте я опишу, как формализуется эта проблема; как реализовать это в шести линейных, древовидных и глубоких методах обучения (в Python - вот блокнот Jupyter); и как они работают с реальными наборами данных.

Квантильная регрессия минимизирует квантильные потери

Подобно тому, как регрессии минимизируют функцию потерь квадрата ошибок для прогнозирования одноточечной оценки, квантильные регрессии минимизируют квантильные потери при прогнозировании определенного квантиля. Самый популярный квантиль - это медиана или 50-й процентиль, и в этом случае потеря квантиля - это просто сумма абсолютных ошибок. Другие квантили могут давать конечные точки интервала прогнозирования; например, средний 80-процентный диапазон определяется 10-м и 90-м процентилями. Потери квантилей различаются в зависимости от оцениваемого квантиля, так что большее количество отрицательных ошибок наказывается больше для более высоких квантилей, а более положительные ошибки наказываются больше для более низких квантилей.

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

Давайте посмотрим на каждую строку отдельно:

  • Средняя синяя линия показывает медиану, которая симметрична относительно нуля, где все потери равны нулю, потому что прогноз был идеальным. Пока все выглядит хорошо: медиана направлена ​​на то, чтобы разделить набор прогнозов пополам, поэтому мы хотим взвесить заниженные оценки наравне с завышенными. Как мы скоро увидим, потеря квантиля вокруг медианы составляет половину абсолютного отклонения, поэтому 0,5 при -1 и +1 и 0 при 0.
  • Голубая линия показывает 10-й процентиль, который определяет меньшие потери для отрицательных ошибок и более высокие потери для положительных ошибок. 10-й процентиль означает, что, по нашему мнению, существует 10-процентная вероятность того, что истинное значение ниже этого прогнозируемого значения, поэтому имеет смысл приписывать меньший убыток заниженным оценкам, чем завышенным.
  • Темно-синяя линия показывает 90-й процентиль, который является обратной схемой 10-го процентиля.

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

Учитывая эту интуицию, вот формула квантильной потери (источник):

И в коде Python, где мы можем заменить разветвленную логику оператором maximum:

def quantile_loss(q, y, f):
  # q: Quantile to be evaluated, e.g., 0.5 for median.
  # y: True value.
  # f: Fitted (predicted) value.
  e = y - f
  return np.maximum(q * e, (q - 1) * e)

Далее мы рассмотрим шесть методов - OLS, линейную квантильную регрессию, случайные леса, повышение градиента, Keras и TensorFlow - и посмотрим, как они работают с некоторыми реальными данными.

Данные

В этом анализе будет использоваться Набор данных о жилищном строительстве Бостона, который содержит 506 наблюдений, представляющих города в районе Бостона. Он включает 13 характеристик наряду с целевой средней стоимостью домов, занимаемых владельцами. Таким образом, квантильная регрессия позволяет прогнозировать долю городов (не домов) со средней стоимостью жилья ниже значения.

Я обучаю модели на 80 процентах и ​​тестирую оставшиеся 20 процентов. Для упрощения визуализации в первом наборе моделей используется одна особенность: AGE, доля занятых владельцами единиц, построенных до 1940 года. Как и следовало ожидать, в городах со старыми домами стоимость домов ниже, хотя соотношение между ними довольно шумное.

Для каждого метода мы прогнозируем 10-й, 30-й, 50-й, 70-й и 90-й процентили в тестовой выборке.

Обычный метод наименьших квадратов

Хотя OLS предсказывает среднее, а не медианное значение, мы все же можем вычислять интервалы предсказания на его основе на основе стандартных ошибок и обратного нормального CDF:

def ols_quantile(m, X, q):
  # m: OLS statsmodels model.
  # X: X matrix.
  # q: Quantile.
  mean_pred = m.predict(X)
  se = np.sqrt(m.scale)
  return mean_pred + norm.ppf(q) * se

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

Линейная квантильная регрессия

Линейные модели выходят за рамки среднего значения до медианы и других квантилей. Линейная квантильная регрессия предсказывает данный квантиль, ослабляя допущение о параллельном тренде OLS, в то же время сохраняя линейность (под капотом это минимизирует квантильные потери). Это просто с statsmodels:

sm.QuantReg(train_labels, X_train).fit(q=q).predict(X_test)
# Provide q.

Случайные леса

Наш первый отход от линейных моделей - это случайные леса, набор деревьев. Хотя эта модель не предсказывает квантили явным образом, мы можем рассматривать каждое дерево как возможное значение и вычислять квантили, используя его эмпирический CDF (Андо Саабас написал об этом больше):

def rf_quantile(m, X, q):
  # m: sklearn random forests model.
  # X: X matrix.
  # q: Quantile.
  rf_preds = []
  for estimator in m.estimators_:
    rf_preds.append(estimator.predict(X))
  # One row per record.
  rf_preds = np.array(rf_preds).transpose()
  return np.percentile(rf_preds, q * 100, axis=1)

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

Повышение градиента

Другой древовидный метод - это повышение градиента, scikit-learn реализация которого поддерживает явное квантильное предсказание:

ensemble.GradientBoostingRegressor(loss='quantile', alpha=q)

Хотя он и не такой резкий, как случайные леса, он не очень хорош и для одноэлементной модели.

Керас (глубокое обучение)

Keras - удобная оболочка для нейросетевых инструментов, включая TensorFlow. Мы можем использовать глубокие нейронные сети для прогнозирования квантилей, передавая функцию квантильных потерь. Код в некоторой степени сложен, поэтому посмотрите Блокнот Jupyter или прочтите больше Сачина Абейвардана, чтобы увидеть, как он работает.

В основе наиболее глубоких сетей лежат линейные модели с изгибами (называемые выпрямленными линейными единицами или ReLU), которые мы можем увидеть здесь визуально: Керас предсказывает большее скопление ценностей домов для городов около 70 процентов из них было построено до 1940 года, при этом разветвляется больше на очень низком и очень высоком конце возраста. Это хороший прогноз, основанный на подборе тестовых данных.

TensorFlow

Одним из недостатков Keras является то, что каждый квантиль необходимо обучать отдельно. Чтобы использовать шаблоны, общие для квантилей, нам нужно обратиться к самому TensorFlow. См. Блокнот Jupyter и статью Джейкоба Цвейга, чтобы узнать об этом больше.

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

Что лучше всего?

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

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

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

Большие наборы данных дают больше возможностей для улучшения по сравнению с OLS

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

Древовидные методы вернулись, и хотя OLS улучшилась, разрыв между OLS и другими не-древовидными методами увеличился.

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

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