← Назад к вопросам

Штрафует ли метрика MAPE больше за недопрогноз или перепрогноз

2.0 Middle🔥 121 комментариев
#Метрики и оценка моделей

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Штрафует ли метрика MAPE больше за недопрогноз или перепрогноз?

MAPE (Mean Absolute Percentage Error) **штрафует асимметрично** — недопрогноз штрафуется сильнее, чем перепрогноз. Это критическое свойство, которое нужно учитывать при выборе метрики.

Формула MAPE

MAPE = (1/n) * Σ |Yₜ - Ŷₜ| / |Yₜ| * 100%

где:

  • Yₜ — фактическое значение
  • Ŷₜ — предсказанное значение

Демонстрация асимметрии

import numpy as np

def calculate_mape(y_true, y_pred):
    return np.mean(np.abs((y_true - y_pred) / y_true)) * 100

# Сценарий 1: Фактическое значение = 100
y_true = 100

# Недопрогноз на 50 (предсказали 50, ошибка -50)
y_pred_under = 50
mape_under = calculate_mape(y_true, y_pred_under)

# Перепрогноз на 50 (предсказали 150, ошибка +50)
y_pred_over = 150
mape_over = calculate_mape(y_true, y_pred_over)

print(f"Фактическое значение: {y_true}")
print(f"\nНедопрогноз (предсказано 50):")
print(f"  Ошибка: {50 - 100} = -50")
print(f"  MAPE: {mape_under:.2f}%")
print(f"\nПеперпрогноз (предсказано 150):")
print(f"  Ошибка: {150 - 100} = +50")
print(f"  MAPE: {mape_over:.2f}%")
print(f"\nРазница штрафа: {mape_under - mape_over:.2f}%")

# Output:
# Недопрогноз (предсказано 50):
#   MAPE: 50.00%
# Перепрогноз (предсказано 150):
#   MAPE: 50.00%
# При РАВНЫХ по абсолютной величине ошибках — штраф одинаков!

Когда MAPE штрафует асимметрично?

# Более сложный пример
y_actual = np.array([100, 50, 200, 10])

# Вариант 1: Недопрогноз на 20%
y_pred_under = y_actual * 0.8
error_under = np.abs(y_actual - y_pred_under) / y_actual
mape_1 = np.mean(error_under) * 100

# Вариант 2: Перепрогноз на 25%
y_pred_over = y_actual * 1.25
error_over = np.abs(y_actual - y_pred_over) / y_actual
mape_2 = np.mean(error_over) * 100

print(f"Недопрогноз на 20%: MAPE = {mape_1:.2f}%")
print(f"Перепрогноз на 25%: MAPE = {mape_2:.2f}%")
print(f"\nВывод: При РАЗНЫХ процентах ошибки MAPE одинаков!")
print(f"Логика: недопрогноз на 20% = перепрогноз на 25%")
print(f"Но для бизнеса это может быть СОВСЕМ РАЗНЫЕ последствия")

ASYMMETRY: Недопрогноз vs Перепрогноз (в контексте бизнеса)

# Пример: Спрогнозировали спрос на товар
actual_demand = 100  # Реальный спрос

# Сценарий A: Недопрогнозировали (думали 50)
understocked = 50
stockout_loss = actual_demand - understocked  # Потеряли 50 продаж
missed_revenue = stockout_loss * 20  # 20$ за единицу = 1000$ потерь

# Сценарий B: Перепрогнозировали (думали 150)
overstocked = 150
excess_inventory = overstocked - actual_demand  # 50 единиц в запасе
storage_cost = excess_inventory * 5  # 5$ за хранение = 250$ потерь

print(f"\nНедопрогноз: потеря выручки = {missed_revenue}$")
print(f"Перепрогноз: затраты на хранение = {storage_cost}$")
print(f"\nНедопрогноз штрафует СИЛЬНЕЕ по деньгам!")

# MAPE же говорит: обе ошибки = 50% (если 50 единиц ошибки)
mape_both = 50 / 100 * 100
print(f"\nMAPE для обоих сценариев: {mape_both:.2f}%")
print(f"MAPE НЕ отражает асимметрию в бизнес-последствиях!")

Критические проблемы MAPE

1. Бесконечность при Yₜ = 0

y_true = [100, 50, 0, 200]  # Есть нулевое значение
y_pred = [95, 52, 1, 205]

# MAPE не определена при y_true[2] = 0!
# Возникает деление на ноль
mape = calculate_mape(y_true, y_pred)  # inf или nan
print(f"MAPE: {mape}")

2. Асимметрия относительно нуля

# Максимальная ошибка при недопрогнозе не превышает 100%
# Но при перепрогнозе может быть неограниченной!

y_true = 10

# Недопрогноз: минимум = 0, максимум MAPE = 100%
y_pred_min = 0
mape_min = calculate_mape(y_true, y_pred_min)
print(f"Максимум ошибки при недопрогнозе: {mape_min:.2f}%")

# Перепрогноз: может быть 200%, 500%, 1000%...
y_pred_huge = 1000
mape_huge = calculate_mape(y_true, y_pred_huge)
print(f"Ошибка при огромном перепрогнозе: {mape_huge:.2f}%")

print(f"\nAsymmetry: недопрогноз штрафуется максимум на 100%")
print(f"            перепрогноз может быть штрафован на 1000%+")

Решения для асимметрии

1. Weighted MAPE (с учётом последствий)

def weighted_mape(y_true, y_pred, cost_underestimate=10, cost_overestimate=1):
    errors = y_pred - y_true
    weighted_error = np.zeros_like(errors, dtype=float)
    
    # Недопрогноз штрафуется сильнее
    mask_under = errors < 0
    weighted_error[mask_under] = np.abs(errors[mask_under]) / y_true[mask_under] * cost_underestimate
    
    # Перепрогноз штрафуется слабее
    mask_over = errors > 0
    weighted_error[mask_over] = np.abs(errors[mask_over]) / y_true[mask_over] * cost_overestimate
    
    return np.mean(weighted_error) * 100

y_true = np.array([100, 50, 200])
y_pred = np.array([80, 60, 180])

mape_standard = calculate_mape(y_true, y_pred)
mape_weighted = weighted_mape(y_true, y_pred, cost_underestimate=10, cost_overestimate=1)

print(f"Стандартная MAPE: {mape_standard:.2f}%")
print(f"Weighted MAPE: {mape_weighted:.2f}%")
print(f"Взвешенная версия штрафует недопрогноз сильнее")

2. Использование RMSE (симметричная метрика)

from sklearn.metrics import mean_squared_error, mean_absolute_error

y_true = np.array([100, 50, 200, 10])
y_pred = np.array([90, 60, 210, 5])

rmse = np.sqrt(mean_squared_error(y_true, y_pred))
mae = mean_absolute_error(y_true, y_pred)

print(f"RMSE: {rmse:.2f}")
print(f"MAE: {mae:.2f}")
print(f"\nRMSE и MAE — симметричные метрики")
print(f"Одинаково штрафуют над- и недопрогноз")

3. Asymmetric MAPE

def asymmetric_mape(y_true, y_pred):
    # Штрафует недопрогноз в 1.5 раза сильнее
    errors = np.abs(y_pred - y_true) / y_true
    
    weights = np.where(y_pred < y_true, 1.5, 1.0)
    return np.mean(errors * weights) * 100

mape_asym = asymmetric_mape(y_true, y_pred)
print(f"Asymmetric MAPE: {mape_asym:.2f}%")

Рекомендации по использованию

MAPE хороша когда:

  • Нет нулевых значений в y_true
  • Над- и недопрогноз имеют одинаковые бизнес-последствия
  • Нужна интерпретируемая метрика (в процентах)

НЕ используй MAPE когда:

  • Есть нулевые или близкие к нулю значения
  • Недопрогноз опаснее перепрогноза (или наоборот)
  • Нужна полная симметричность штрафа

Альтернативы:

  • RMSE — для симметричного штрафа
  • MAE — для простой линейной ошибки
  • Weighted metrics — для учёта бизнес-логики
  • sMAPE (Symmetric MAPE) — менее асимметричная

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