Почему метрика MAPE асимметрична?

«Почему метрика MAPE асимметрична?» — вопрос из категории Метрики и функции потерь, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

MAPE (Mean Absolute Percentage Error) асимметрична из-за своей формулы, где ошибка нормируется на фактическое значение:

MAPE = (100% / n) * Σ |(Actual - Forecast) / Actual|

Причина асимметрии:

  1. Нижняя граница ошибки: Когда прогноз (Forecast) превышает фактическое значение (Actual), максимальное значение MAPE стремится к 100% (если Forecast >> Actual, то дробь (F - A)/A может быть большой, но это все еще одна сторона).
  2. Верхняя граница ошибки отсутствует: Когда прогноз меньше фактического значения, и особенно если Actual близко к нулю, знаменатель становится очень маленьким, что может привести к неограниченно большим значениям MAPE (например, 1000% и более).

Практический пример:

import numpy as np

def mape(actual, forecast):
    return np.mean(np.abs((actual - forecast) / actual)) * 100

# Случай 1: Завышенный прогноз
actual = 100
forecast_over = 150  # Ошибка: (100-150)/100 = -0.5 -> |0.5| -> 50%
print(f'MAPE (over): {mape(actual, forecast_over):.1f}%')

# Случай 2: Заниженный прогноз (симметричный случай)
forecast_under = 50   # Ошибка: (100-50)/100 = 0.5 -> 50%
print(f'MAPE (under): {mape(actual, forecast_under):.1f}%')

# Случай 3: Заниженный прогноз при малом actual (проблема асимметрии)
actual_small = 10
forecast_zero = 0     # Ошибка: (10-0)/10 = 1 -> 100%
# А если actual = 1, а forecast = 0, то ошибка уже 1000%
print(f'MAPE (small actual): {mape(actual_small, forecast_zero):.1f}%')

Вывод: Из-за этой асимметрии MAPE сильно штрафует заниженные прогнозы для малых фактических значений и не подходит для данных, содержащих нули или близкие к нулю значения. В таких случаях лучше использовать симметричную sMAPE, MAE или масштабированную ошибку, например, MASE.