Ответ
MAPE (Mean Absolute Percentage Error) асимметрична из-за своей формулы, где ошибка нормируется на фактическое значение:
MAPE = (100% / n) * Σ |(Actual - Forecast) / Actual|
Причина асимметрии:
- Нижняя граница ошибки: Когда прогноз (
Forecast) превышает фактическое значение (Actual), максимальное значение MAPE стремится к 100% (еслиForecast >> Actual, то дробь(F - A)/Aможет быть большой, но это все еще одна сторона). - Верхняя граница ошибки отсутствует: Когда прогноз меньше фактического значения, и особенно если
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.
Ответ 18+ 🔞
Э, слушай, вот эта ваша MAPE — вообще хитрая жопа, ей-богу. С виду вроде простая формула, а подвох там овердохуища.
Смотри, в чём прикол. Она же ошибку на фактическое значение делит: (100% / n) * Σ |(Actual - Forecast) / Actual|. Ну, типа, в процентах всё понятно будет. А фишка в том, что у неё границы — хуй с горы, а не ровные.
Где собака зарыта:
- Если переоценил (прогноз больше факта): Ну, допустим, накосячил в два раза. Ошибка будет, скажем, 100%. Вроде много, но это ещё цветочки.
- А вот если недооценил, да ещё и факт маленький: Вот тут начинается ёперный театр. Потому что если
Actualблизок к нулю, то знаменатель в дроби — просто пиздец какой маленький. И эта дробь взлетает до небес. Может быть и 1000%, и 10000% — предела-то нет! Полная асимметрия, доверия к такой метрике — ноль ебать.
Ну, чтобы совсем понятно было, накидаю кода:
import numpy as np
def mape(actual, forecast):
return np.mean(np.abs((actual - forecast) / actual)) * 100
# Ситуация первая: Напрогнозировал с запасом
actual = 100
forecast_over = 150 # Ошибка: (100-150)/100 = -0.5 -> модуль 0.5 -> 50%
print(f'MAPE (переоценил): {mape(actual, forecast_over):.1f}%')
# Ситуация вторая: Не доложил (симметричный случай, для приличия)
forecast_under = 50 # Ошибка: (100-50)/100 = 0.5 -> тоже 50%
print(f'MAPE (недооценил): {mape(actual, forecast_under):.1f}%')
# Ситуация третья: А вот теперь ловушка
actual_small = 10
forecast_zero = 0 # Ошибка: (10-0)/10 = 1 -> 100%
# А представь, actual = 1, а forecast = 0? Ошибка уже 1000%, Карл!
print(f'MAPE (маленький факт и ноль): {mape(actual_small, forecast_zero):.1f}%')
Итог, чувак: Из-за этой ебаной асимметрии MAPE просто вмандяривает нереальные штрафы, если ты промахнулся мимо маленьких значений или, не дай бог, там нули в данных есть. Получается, что она не штрафует, а просто издевается. Поэтому если в твоих рядах есть нули или значения околонулевые — беги от MAPE как от огня. Лучше посмотри в сторону sMAPE, MAE или той же MASE. С ними хоть волнение ебать не будет, что из-за одного нуля вся статистика накрылась медным тазом.