MSE, RMSE, MAE, MAPE для оценки качества прогнозов временных рядов

При построении моделей прогнозирования временных рядов, для оценки качества чаще всего используют одну или две из следующих четырех метрик: MSE, RMSE, MAE и MAPE. Каждая из них рассказывает свою историю о модели, и понимание этих нюансов может стать разницей между прибыльной стратегией и потерей капитала.

И MSE, RMSE, MAE и MAPE решают одну и ту же задачу — оценить точность моделирования прогноза. Все они измеряют разницу между предсказанными и реальными значениями, но делают это по-разному. MSE и RMSE чувствительны к большим ошибкам, MAE дает среднюю величину ошибки, а MAPE выражает ошибку в процентах от реальных значений.

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

Mean Squared Error (MSE)

MSE — это самая популярная метрика оценки качества прогнозов временных рядов. Она представляет собой среднее арифметическое квадратов разностей между фактическими и прогнозируемыми значениями. Формула ее вычисления достаточно простая:

MSE = (1/n) * Σ(y_actual — y_predicted)²

где:

  • n — общее количество наблюдений (предсказаний);
  • y_actual — фактическое (реальное) значение;
  • y_predicted — предсказанное моделью значение.

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

Представьте ситуацию: ваша модель точно предсказывает движения цены 95% времени с ошибкой в 0.1%, но в один день волатильности ошибается на 5%. MSE будет доминировать именно этой большой ошибкой, создавая впечатление, что модель работает плохо, хотя в реальности она может быть весьма эффективной.

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

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

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import KFold
from lightgbm import LGBMRegressor
import warnings

warnings.filterwarnings('ignore')
np.random.seed(42)

# Генерация временного ряда
n_samples = 600
t = np.arange(n_samples)
prices = np.zeros(n_samples)

micro_trends = [
    {'start': 0, 'end': 100, 'slope': 0.05, 'volatility': 1.5},
    {'start': 100, 'end': 200, 'slope': -0.03, 'volatility': 1.2},
    {'start': 200, 'end': 300, 'slope': 0.0, 'volatility': 0.5},
    {'start': 300, 'end': 400, 'slope': 0.07, 'volatility': 2.0},
    {'start': 400, 'end': 500, 'slope': -0.02, 'volatility': 1.0},
    {'start': 500, 'end': 600, 'slope': 0.0, 'volatility': 0.3}
]

price = 100
for trend in micro_trends:
    for i in range(trend['start'], trend['end']):
        noise = np.random.normal(0, trend['volatility'])
        price += trend['slope'] + noise
        prices[i] = price

df = pd.DataFrame({
    'price': prices,
    'returns': np.concatenate([[0], np.diff(prices)]),
    'volatility': np.abs(np.concatenate([[0], np.diff(prices)]))
})

# Метрики оценки качества прогноза
def calculate_mse(y_true, y_pred):
    return np.mean((y_true - y_pred) ** 2)

def calculate_rmse(y_true, y_pred):
    return np.sqrt(np.mean((y_true - y_pred) ** 2))

def calculate_mae(y_true, y_pred):
    return np.mean(np.abs(y_true - y_pred))

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

# Признаки
def create_features(df, lookback=10):
    features = []
    targets = []

    for i in range(lookback, len(df)):
        price_lags = df['price'].iloc[i-lookback:i].values
        return_lags = df['returns'].iloc[i-lookback:i].values
        vol_lags = df['volatility'].iloc[i-lookback:i].values

        sma_5 = np.mean(price_lags[-5:])
        sma_10 = np.mean(price_lags)
        momentum = price_lags[-1] - price_lags[0]
        volatility = np.std(return_lags)

        feature_vector = np.concatenate([
            price_lags, return_lags, vol_lags,
            [sma_5, sma_10, momentum, volatility]
        ])
        features.append(feature_vector)
        targets.append(df['price'].iloc[i])

    return np.array(features), np.array(targets)

X, y = create_features(df)

# Модель LightGBM и кросс-валидация
kf = KFold(n_splits=6, shuffle=False)
model = LGBMRegressor(n_estimators=250, random_state=123)

y_true_all = []
y_pred_all = []

for train_idx, test_idx in kf.split(X):
    X_train, X_test = X[train_idx], X[test_idx]
    y_train, y_test = y[train_idx], y[test_idx]

    model.fit(X_train, y_train)
    y_pred = model.predict(X_test)

    y_true_all.extend(y_test)
    y_pred_all.extend(y_pred)

y_true_all = np.array(y_true_all)
y_pred_all = np.array(y_pred_all)

# Расчет качества
mse = calculate_mse(y_true_all, y_pred_all)
rmse = calculate_rmse(y_true_all, y_pred_all)
mae = calculate_mae(y_true_all, y_pred_all)
mape = calculate_mape(y_true_all, y_pred_all)

print("Метрики ошибок модели LightGBM:")
print(f"  MSE:  {mse:.4f}")
print(f"  RMSE: {rmse:.4f}")
print(f"  MAE:  {mae:.4f}")
print(f"  MAPE: {mape:.2f}%")

# Визуализация прогноза
plt.figure(figsize=(15, 8))
plt.plot(y_true_all, label='Фактические значения', linewidth=2, color='dimgray')
plt.plot(y_pred_all, label='Прогноз (LightGBM)', linewidth=2, color='steelblue')
plt.title('Фактические значения vs Прогноз')
plt.xlabel('Наблюдение')
plt.ylabel('Цена')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

Прогнозирование временного ряда бустингом LightGBM

Рис. 1: Прогнозирование временного ряда бустингом LightGBM

Метрики ошибок модели LightGBM:

MSE: 5.3867
RMSE: 2.3209
MAE: 1.5118
MAPE: 1.44%

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

Это видно как по графику, где предсказания модели достаточно точно повторяют реальные значения, так и по метрикам: средняя абсолютная ошибка (MAE) составила около 1.5, а средняя процентная ошибка (MAPE) всего 1.44%, что говорит о высокой точности модели на большинстве интервалов. Учитывая разнообразие поведения временного ряда, модель продемонстрировала устойчивость к резким колебаниям и шуму.

Читайте также:  Методы аппроксимации временных рядов

Что касаемо метрик. Разные метрики ошибок отражают разные аспекты качества модели:

  • MSE и RMSE имеют значения выше при прочих равных, так как они более чувствительны;
  • MAE показывает среднюю ошибку в тех же единицах, что и цена, и позволяет интуитивно оценить, насколько в среднем модель ошибается;
  • MAPE выражает ту же ошибку в процентах и особенно полезен для бизнес-интерпретации, когда важно понимать относительное отклонение от фактической цены.

Root Mean Squared Error (RMSE)

RMSE является квадратным корнем из MSE, что возвращает метрику к исходным единицам измерения. Эта особенность делает RMSE более интерпретируемой по сравнению с MSE — если мы прогнозируем цену акции в долларах, то RMSE также будет выражена в долларах, что позволяет легко понять практическое значение ошибки.

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

Формула вычисления RMSE:

RMSE = sqrt( (1/n) * Σ (y_i — y_pred_i)^2 )

где:

  • y_i — фактическое значение;
  • y_pred_i — предсказанное значение;
  • n — количество наблюдений;
  • Σ — сумма по всем наблюдениям.

Практическое преимущество RMSE проявляется при сравнении моделей для одного и того же актива. Если модель имеет RMSE=0.5, а модель B RMSE=0.9, то мы можем сказать, что модель A в среднем ошибается на полдоллара меньше. Такая интерпретируемость удобнее при представлении результатов менеджменту или клиентам.

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

# Кросс-валидация с различными моделями
kf = KFold(n_splits=5, shuffle=True, random_state=42)
models = {
    'Random Forest': RandomForestRegressor(n_estimators=100, random_state=42),
    'Linear Regression': LinearRegression()
}

results = {}

for name, model in models.items():
    mse_scores = []
    rmse_scores = []
    mae_scores = []
    mape_scores = []
    
    for train_idx, test_idx in kf.split(X):
        X_train, X_test = X[train_idx], X[test_idx]
        y_train, y_test = y[train_idx], y[test_idx]
        
        model.fit(X_train, y_train)
        y_pred = model.predict(X_test)
        
        mse_scores.append(calculate_mse(y_test, y_pred))
        rmse_scores.append(calculate_rmse(y_test, y_pred))
        mae_scores.append(calculate_mae(y_test, y_pred))
        mape_scores.append(calculate_mape(y_test, y_pred))
    
    results[name] = {
        'MSE': np.mean(mse_scores),
        'RMSE': np.mean(rmse_scores),
        'MAE': np.mean(mae_scores),
        'MAPE': np.mean(mape_scores)
    }

# Визуализация результатов
fig, axes = plt.subplots(1, 4, figsize=(16, 6)) 
metrics = ['MSE', 'RMSE', 'MAE', 'MAPE']

for i, metric in enumerate(metrics):
    ax = axes[i]
    model_names = list(results.keys())
    values = [results[name][metric] for name in model_names]
    
    bars = ax.bar(model_names, values, color=['darkgray', 'darkslategray'])
    ax.set_title(f'{metric} Comparison', fontsize=12, fontweight='bold')
    ax.set_ylabel(metric)
    
    for bar, value in zip(bars, values):
        ax.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.01,
                f'{value:.3f}', ha='center', va='bottom')
    
    ax.grid(False)
    if i < 3:
        ax.set_xlabel('')
        ax.tick_params(axis='x', which='both', bottom=False, top=False, labelbottom=False)

plt.tight_layout()
plt.show()

Сравнение показателей MSE, RMSE, MAE, MAPE после обучения моделей Random Forest, Linear Regression

Рис. 2: Сравнение показателей MSE, RMSE, MAE, MAPE после обучения моделей Random Forest, Linear Regression

На примере выше мы видим что модель линейной регрессии показала наименьшие ошибки по всем метрикам одновременно — MSE, RMSE, MAE и MAPE — это говорит о ее стабильном и согласованном превосходстве на данном наборе данных.

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

Mean Absolute Error (MAE)

MAE представляет собой среднее арифметическое абсолютных разностей между фактическими и прогнозируемыми значениями. Ключевое отличие от MSE и RMSE заключается в использовании линейной, а не квадратичной функции потерь. Это делает MAE значительно менее чувствительной к выбросам, что особенно важно для средне и долгосрочных стратегий.

В моей практике я часто сталкивался с ситуациями, когда рыночные события (объявления ФРС, геополитические кризисы, корпоративные скандалы) создавали экстремальные движения цен, которые практически невозможно предсказать. MAE в таких случаях дает более стабильную оценку общего качества модели, не позволяя нескольким выбросам исказить представление о производительности.

Читайте также:  23 способа визуализации котировок с помощью Mplfinance

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

Экономическая интерпретация MAE

Одно из главных преимуществ MAE — простота экономической интерпретации. Если MAE равна 0.25$ при прогнозировании цены акции, это означает, что в среднем модель ошибается на 25 центов. Такая прозрачность лучше работает при расчете транзакционных издержек и потенциальной прибыльности стратегии.

В контексте управления рисками MAE предоставляет консервативную оценку типичной ошибки модели. Это позволяет более точно рассчитывать размеры позиций и устанавливать stop-loss уровни. Я часто использую MAE как базовый параметр для определения минимального спреда, необходимого для покрытия неточности прогнозов.

# Детальный анализ влияния выбросов на различные метрики
def analyze_outlier_impact(y_true, y_pred_base, outlier_multipliers=[1, 2, 5, 10]):
    """
    Анализирует влияние выбросов различной силы на метрики качества
    """
    results = []
    
    for multiplier in outlier_multipliers:
        y_pred = y_pred_base.copy()
        
        # Добавляем выбросы к 5% предсказаний
        n_outliers = len(y_pred) // 20
        outlier_indices = np.random.choice(len(y_pred), n_outliers, replace=False)
        outlier_errors = np.random.normal(0, multiplier, n_outliers)
        y_pred[outlier_indices] += outlier_errors
        
        metrics = {
            'outlier_strength': multiplier,
            'MSE': calculate_mse(y_true, y_pred),
            'RMSE': calculate_rmse(y_true, y_pred),
            'MAE': calculate_mae(y_true, y_pred),
            'MAPE': calculate_mape(y_true, y_pred)
        }
        results.append(metrics)
    
    return pd.DataFrame(results)

# Создаем базовые предсказания с помощью Random Forest
rf_model = RandomForestRegressor(n_estimators=100, random_state=42)
train_size = int(0.8 * len(X))
X_train, X_test = X[:train_size], X[train_size:]
y_train, y_test = y[:train_size], y[train_size:]

rf_model.fit(X_train, y_train)
y_pred_base = rf_model.predict(X_test)

# Анализ влияния выбросов
outlier_analysis = analyze_outlier_impact(y_test, y_pred_base)

# Визуализация влияния выбросов
fig, axes = plt.subplots(2, 2, figsize=(15, 10))
metrics_to_plot = ['MSE', 'RMSE', 'MAE', 'MAPE']

for i, metric in enumerate(metrics_to_plot):
    ax = axes[i//2, i%2]
    ax.plot(outlier_analysis['outlier_strength'], 
            outlier_analysis[metric], 
            marker='o', linewidth=2, color='black', markersize=8)
    ax.set_xlabel('Сила выбросов (множитель)')
    ax.set_ylabel(metric)
    ax.set_title(f'Влияние выбросов на {metric}')
    ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

print("Анализ чувствительности к выбросам:")
print(outlier_analysis.round(4))

Влияние выбросов на показатели MSE, RMSE, MAE, MAPE

Рис. 3: Влияние выбросов на показатели MSE, RMSE, MAE, MAPE

Анализ чувствительности к выбросам:
   outlier_strength     MSE    RMSE     MAE    MAPE
0                 1  0.7438  0.8625  0.6169  0.5507
1                 2  1.0166  1.0083  0.6533  0.5835
2                 5  2.5299  1.5906  0.7969  0.7167
3                10  7.0225  2.6500  0.8313  0.7457

Этот анализ демонстрирует отличие в поведении метрик при наличии аномальных значений. Вы заметите, что MSE и RMSE растут квадратично с увеличением силы выбросов, в то время как MAE демонстрирует значительно более стабильное поведение. Это объясняется фундаментальными математическими свойствами данных метрик и имеет прямое практическое значение.

В реальной торговле такое поведение означает, что модель, оптимизированная по MAE, будет более стабильно работать в условиях рыночной неопределенности. Она не будет «паниковать» из-за единичных экстремальных событий и сохранит свою прогностическую способность в нормальных рыночных условиях.

Mean Absolute Percentage Error (MAPE)

MAPE выражает ошибку в процентах от фактического значения, что делает эту метрику масштабно-независимой. Это особенно ценно при сравнении моделей для активов с различными ценовыми уровнями — акции стоимостью $10 и $1000 могут быть сравнены напрямую через MAPE.

В портфельном управлении MAPE становится незаменимой при оценке моделей для различных классов активов. Модель с MAPE 2% одинаково хороша как для прогнозирования цены акции в $50, так и для облигации номиналом $1000. Эта универсальность позволяет создавать единые критерии качества для всего портфеля.

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

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

Кроме того, MAPE асимметрична по своей природе. Положительная ошибка (переоценка) влияет на MAPE иначе, чем отрицательная ошибка (недооценка) той же величины. Это может привести к смещенным оценкам качества модели, особенно если прогнозы систематически смещены в одну сторону.

Визуализация асимметрии метрики MAPE при одинаковых абсолютных ошибках на разных уровнях истинных значений

Рис. 4: Визуализация асимметрии метрики MAPE при одинаковых абсолютных ошибках на разных уровнях истинных значений

Давайте посмотрим внимательно на визуализации выше и разберемся что здесь происходит:

  • Левый график («MAPE при y + error») показывает, как резко возрастает процентная ошибка (MAPE), если мы переоцениваем значение на фиксированную абсолютную величину при малом масштабе истинного значения — особенно сильно при y_true около 1, где даже малая абсолютная ошибка дает огромный процент;
  • Средний график («MAPE при y — error») демонстрирует поведение MAPE при занижении прогноза на ту же абсолютную величину; здесь видно, что MAPE также высока при малых значениях y_true, но растет не так драматично, особенно если предсказание приближается к нулю;
  • Правый график («Асимметрия: MAPE(y+e) — MAPE(y-e)») показывает разницу между переоценкой и недооценкой — именно здесь наглядно видна асимметрия MAPE: при одинаковой по модулю ошибке вверх и вниз результат неравномерный, особенно ярко выраженный при низких значениях y_true.
Читайте также:  Методы разделения деревьев решений: Gini, Энтропия, Gain Ratio, Хи-квадрат, Variance Reduction, Classification Error

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

В контексте торговых стратегий эта асимметрия может привести к систематическому смещению в оценке качества модели. Если ваша модель склонна к переоценке цен (что часто происходит в бычьих рынках), MAPE будет «наказывать» такие ошибки сильнее, чем недооценку. Это необходимо учитывать при оптимизации параметров модели и интерпретации результатов.

Сравнительный анализ метрик в различных рыночных условиях

Поведение метрик в трендовых рынках

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

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

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

Волатильные рынки и чувствительность метрик

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

RMSE, будучи квадратным корнем из MSE, также демонстрирует высокую чувствительность к волатильности, но в меньшей степени. Важно отметить, что RMSE может служить индикатором изменения рыночного режима — резкое увеличение RMSE часто предвещает период повышенной неопределенности.

MAE остается наиболее стабильной метрикой в волатильных условиях. Эта стабильность делает ее предпочтительным выбором для мониторинга производительности модели в реальном времени. Если MAE увеличивается постепенно, это может указывать на системные изменения в рыночной структуре, а не на временные флуктуации.

Заключение

Каждая из представленных метрик решает специфические задачи в количественном анализе:

  • MSE и RMSE, благодаря своей чувствительности к выбросам, незаменимы при выявлении моделей, склонных к катастрофическим ошибкам — важное свойство в алготрейдинге, где один серьезный промах может уничтожить накопленную прибыль;
  • MAE предоставляет более стабильную и интерпретируемую оценку типичной ошибки, что делает ее оптимальным выбором для мониторинга производительности в реальном времени и работы в волатильных рыночных условиях;
  • MAPE, несмотря на проблемы с асимметричностью и чувствительностью к значениям близким к нулю, остается единственным масштабно-независимым инструментом для сравнения моделей различных активов в портфельном управлении.

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

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