В чём разница между MAE, MSE и RMSE?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между MAE, MSE и RMSE
Введение
MAE (Mean Absolute Error), MSE (Mean Squared Error) и RMSE (Root Mean Squared Error) — это три наиболее распространённые метрики для оценки качества моделей регрессии. Они измеряют ошибку предсказания, но по-разному штрафуют за большие ошибки.
1. MAE (Mean Absolute Error) — Средняя абсолютная ошибка
MAE вычисляет среднее абсолютное отклонение предсказаний от реальных значений.
Формула:
MAE = (1/n) * sum(|y_actual - y_pred|)
import numpy as np
from sklearn.metrics import mean_absolute_error
# Пример
y_actual = np.array([3, -0.5, 2, 7])
y_pred = np.array([2.5, 0.0, 2, 8])
# Ручной расчёт
errors = np.abs(y_actual - y_pred)
print(f"Ошибки: {errors}") # [0.5, 0.5, 0.0, 1.0]
mae = np.mean(errors)
print(f"MAE: {mae:.3f}") # 0.5
# Через sklearn
mae_sklearn = mean_absolute_error(y_actual, y_pred)
print(f"MAE (sklearn): {mae_sklearn:.3f}") # 0.5
Характеристики:
- Измеряется в тех же единицах, что и целевая переменная
- Одинаково штрафует за ошибки любого размера (линейная шкала)
- Устойчива к выбросам (outliers)
- Легко интерпретируется: "в среднем ошибка составляет X единиц"
2. MSE (Mean Squared Error) — Средняя квадратичная ошибка
MSE вычисляет среднее значение квадратов ошибок.
Формула:
MSE = (1/n) * sum((y_actual - y_pred)^2)
from sklearn.metrics import mean_squared_error
# Пример с теми же данными
y_actual = np.array([3, -0.5, 2, 7])
y_pred = np.array([2.5, 0.0, 2, 8])
# Ручной расчёт
errors_squared = (y_actual - y_pred) ** 2
print(f"Квадраты ошибок: {errors_squared}") # [0.25, 0.25, 0.0, 1.0]
mse = np.mean(errors_squared)
print(f"MSE: {mse:.3f}") # 0.375
# Через sklearn
mse_sklearn = mean_squared_error(y_actual, y_pred)
print(f"MSE (sklearn): {mse_sklearn:.3f}") # 0.375
Характеристики:
- Измеряется в квадратах единиц целевой переменной (сложнее интерпретировать)
- Квадратичный штраф за ошибки -> большие ошибки получают больше веса
- Чувствительна к выбросам (outliers сильно увеличивают MSE)
- Используется в оптимизации (градиентный спуск хорошо работает с MSE)
Почему большие ошибки штрафуются сильнее:
errors = [1, 2, 3]
print("MAE для [1, 2, 3]:", np.mean(np.abs(errors))) # (1+2+3)/3 = 2.0
print("MSE для [1, 2, 3]:", np.mean(np.array(errors)**2)) # (1+4+9)/3 = 4.67
# Видно, что ошибка 3 получает вес 9 вместо 3
3. RMSE (Root Mean Squared Error) — Корневая средняя квадратичная ошибка
RMSE — это квадратный корень из MSE.
Формула:
RMSE = sqrt(MSE) = sqrt((1/n) * sum((y_actual - y_pred)^2))
from sklearn.metrics import mean_squared_error
# Пример
y_actual = np.array([3, -0.5, 2, 7])
y_pred = np.array([2.5, 0.0, 2, 8])
# Ручной расчёт
mse = mean_squared_error(y_actual, y_pred)
rmse = np.sqrt(mse)
print(f"RMSE: {rmse:.3f}") # 0.612
# Или напрямую
rmse_direct = np.sqrt(np.mean((y_actual - y_pred) ** 2))
print(f"RMSE (прямо): {rmse_direct:.3f}") # 0.612
Характеристики:
- Измеряется в тех же единицах, что и целевая переменная (как MAE)
- Сохраняет чувствительность MSE к выбросам, но в исходных единицах
- Компромисс между интерпретируемостью MAE и математическими свойствами MSE
- Более популярна в practice, чем MSE, из-за единиц измерения
Сравнение MAE, MSE и RMSE
| Параметр | MAE | MSE | RMSE |
|---|---|---|---|
| Формула | mean(abs(y-pred)) | mean((y-pred)^2) | sqrt(mean((y-pred)^2)) |
| Единицы | Исходные единицы | Квадраты единиц | Исходные единицы |
| Штраф за ошибки | Линейный | Квадратичный | Квадратичный (в исходных единицах) |
| Чувствительность к выбросам | Низкая | Высокая | Высокая |
| Интерпретируемость | Отличная | Плохая | Хорошая |
| Дифференцируемость | Нет (разрыв в 0) | Да | Да |
Практический пример с выбросом
import numpy as np
from sklearn.metrics import mean_absolute_error, mean_squared_error
# Данные БЕЗ выброса
y_actual_normal = np.array([1, 2, 3, 4, 5])
y_pred_normal = np.array([1.1, 2.1, 3.1, 4.1, 5.1])
mae_normal = mean_absolute_error(y_actual_normal, y_pred_normal)
mse_normal = mean_squared_error(y_actual_normal, y_pred_normal)
rmse_normal = np.sqrt(mse_normal)
print("Без выброса:")
print(f" MAE: {mae_normal:.4f}")
print(f" MSE: {mse_normal:.4f}")
print(f" RMSE: {rmse_normal:.4f}")
# Данные С выбросом
y_actual_outlier = np.array([1, 2, 3, 4, 100]) # 100 вместо 5
y_pred_outlier = np.array([1.1, 2.1, 3.1, 4.1, 5.1])
mae_outlier = mean_absolute_error(y_actual_outlier, y_pred_outlier)
mse_outlier = mean_squared_error(y_actual_outlier, y_pred_outlier)
rmse_outlier = np.sqrt(mse_outlier)
print("\nС выбросом (y=100 вместо y=5):")
print(f" MAE: {mae_outlier:.4f}")
print(f" MSE: {mse_outlier:.4f}")
print(f" RMSE: {rmse_outlier:.4f}")
print("\nРост метрик:")
print(f" MAE растёт на {mae_outlier/mae_normal:.2f}x")
print(f" MSE растёт на {mse_outlier/mse_normal:.2f}x")
print(f" RMSE растёт на {rmse_outlier/rmse_normal:.2f}x")
# Результат:
# Без выброса:
# MAE: 0.1000
# MSE: 0.0100
# RMSE: 0.1000
#
# С выбросом (y=100 вместо y=5):
# MAE: 19.2800 <- растёт в 192.8x
# MSE: 1806.0100 <- растёт в 180601x !!
# RMSE: 42.4988 <- растёт в 424.9x
Видно, что MSE намного чувствительнее к выбросам, чем MAE и RMSE.
Когда что использовать
Используй MAE если:
- Все ошибки одинаково важны
- В данных есть выбросы (outliers)
- Нужна легкая интерпретация
- Пример: предсказание цены дома (ошибка на 10k лучше -10k и +10k в среднем)
Используй MSE/RMSE если:
- Большие ошибки критичнее малых
- Нужно наказывать модель за редкие большие ошибки
- Используешь стандартные методы оптимизации
- Пример: предсказание критичной величины (напряжение сети, дозировка лекарства)
Практическая рекомендация:
- Вычисляй все три метрики
- Смотри на RMSE или MAE для интерпретации (в исходных единицах)
- Если MAE и RMSE сильно отличаются -> есть выбросы или несбалансированные ошибки
- Для оптимизации модели -> обучай на MSE/RMSE
Сравнение на графике
import matplotlib.pyplot as plt
errors = np.linspace(-5, 5, 100)
mae_loss = np.abs(errors)
mse_loss = errors ** 2
rmse_loss = np.sqrt(mse_loss)
plt.figure(figsize=(10, 6))
plt.plot(errors, mae_loss, label='MAE (линейная)', linewidth=2)
plt.plot(errors, mse_loss, label='MSE (квадратичная)', linewidth=2)
plt.plot(errors, rmse_loss, label='RMSE (квадратичная в исходных единицах)', linewidth=2)
plt.xlabel('Ошибка (y_actual - y_pred)')
plt.ylabel('Значение метрики')
plt.title('Сравнение MAE, MSE и RMSE')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
# MSE растёт квадратично, MAE растёт линейно, RMSE растёт медленнее MSE
Вывод: выбор метрики зависит от конкретной задачи и того, насколько критичны для вас большие ошибки.