评估指标与误差分析

准确评估时序预测模型性能是模型选择和优化的关键环节。不同的指标适用于不同的业务场景,合理的评估方法能够帮助选择最适合特定需求的预测模型。

常用评估指标

绝对误差类指标

from sklearn.metrics import mean_absolute_error, mean_squared_error
import numpy as np
 
# 平均绝对误差(MAE)
mae = mean_absolute_error(y_true, y_pred)
 
# 均方误差(MSE)
mse = mean_squared_error(y_true, y_pred)
 
# 均方根误差(RMSE)
rmse = np.sqrt(mean_squared_error(y_true, y_pred))
 
# 平均绝对百分比误差(MAPE)
def mape(y_true, y_pred):
    return np.mean(np.abs((y_true - y_pred) / y_true)) * 100
 
# 对称平均绝对百分比误差(SMAPE)
def smape(y_true, y_pred):
    return 100 * np.mean(2 * np.abs(y_pred - y_true) / (np.abs(y_true) + np.abs(y_pred)))

各指标适用场景

指标优点缺点适用场景
MAE易于理解,对异常值不敏感无法区分过高和过低预测需要直观理解误差大小的场景
MSE/RMSE惩罚大误差,适合控制极端错误受异常值影响大大误差成本高的场景,如库存预测
MAPE可比较不同量级指标对零值敏感业务汇报,但数据不接近零
SMAPE解决MAPE的零值问题上限为200%数据可能包含零或接近零值的场景

预测评估方法

静态预测评估

最简单的评估方法,直接用训练好的模型在测试集上预测:

# 分割训练集和测试集
train_data = df[df.index < '2023-01-01']
test_data = df[df.index >= '2023-01-01']
 
# 训练模型
model.fit(X_train, y_train)
 
# 在测试集上预测
y_pred = model.predict(X_test)
 
# 计算评估指标
print(f"MAE: {mean_absolute_error(y_test, y_pred)}")
print(f"RMSE: {np.sqrt(mean_squared_error(y_test, y_pred))}")

滚动预测评估

更接近实际预测场景,通过逐步向前移动预测窗口:

# 滚动预测函数
def rolling_forecast(model, data, start_idx, end_idx, window_size, step_size=1):
    actuals, predictions = [], []
    
    for i in range(start_idx, end_idx - window_size + 1, step_size):
        # 训练数据截止到i
        train_data = data.iloc[:i]
        # 预测未来window_size期
        test_data = data.iloc[i:i+window_size]
        
        # 准备特征
        X_train = prepare_features(train_data)
        y_train = train_data['target']
        X_test = prepare_features(test_data)
        y_test = test_data['target']
        
        # 训练并预测
        model.fit(X_train, y_train)
        pred = model.predict(X_test)
        
        # 收集结果
        actuals.extend(y_test.tolist())
        predictions.extend(pred.tolist())
    
    return actuals, predictions

时间序列交叉验证

用于更可靠地评估模型在未来的表现:

from sklearn.model_selection import TimeSeriesSplit
 
# 创建时间序列分割器
tscv = TimeSeriesSplit(n_splits=5)
 
# 交叉验证
cv_scores = []
for train_idx, test_idx in tscv.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)
    
    score = mean_absolute_error(y_test, y_pred)
    cv_scores.append(score)
 
print(f"Cross-validation MAE scores: {cv_scores}")
print(f"Average MAE: {np.mean(cv_scores)}")

预测区间与置信度

在业务决策中,了解预测的不确定性也很重要:

# 使用预测分位数估计预测区间
from sklearn.ensemble import GradientBoostingRegressor
 
# 分位数回归模型
lower_model = GradientBoostingRegressor(loss='quantile', alpha=0.1)
mid_model = GradientBoostingRegressor(loss='ls')
upper_model = GradientBoostingRegressor(loss='quantile', alpha=0.9)
 
# 训练模型
lower_model.fit(X_train, y_train)
mid_model.fit(X_train, y_train)
upper_model.fit(X_train, y_train)
 
# 预测
y_lower = lower_model.predict(X_test)
y_mid = mid_model.predict(X_test)
y_upper = upper_model.predict(X_test)
 
# 可视化预测区间
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 6))
plt.plot(y_test.index, y_test, 'b-', label='Actual')
plt.plot(y_test.index, y_mid, 'r-', label='Prediction')
plt.fill_between(y_test.index, y_lower, y_upper, color='pink', alpha=0.3, label='90% Interval')
plt.legend()
plt.title('Forecast with Prediction Intervals')
plt.show()

误差分析与模型诊断

误差分布分析

# 计算误差
errors = y_test - y_pred
 
# 误差统计分析
error_stats = {
    'mean': np.mean(errors),
    'std': np.std(errors),
    'min': np.min(errors),
    'max': np.max(errors),
    'skewness': stats.skew(errors)
}
print(error_stats)
 
# 误差直方图
plt.figure(figsize=(10, 6))
plt.hist(errors, bins=30, alpha=0.7)
plt.axvline(0, color='red', linestyle='--')
plt.title('Error Distribution')
plt.xlabel('Error')
plt.ylabel('Frequency')
plt.show()

残差分析

# 残差图
plt.figure(figsize=(10, 6))
plt.scatter(y_pred, errors)
plt.axhline(y=0, color='r', linestyle='--')
plt.title('Residual Plot')
plt.xlabel('Predicted Values')
plt.ylabel('Residuals')
plt.show()
 
# 残差自相关检验
from statsmodels.graphics.tsaplots import plot_acf
plot_acf(errors, lags=30)
plt.title('Autocorrelation of Residuals')
plt.show()
 
# Ljung-Box检验
from statsmodels.stats.diagnostic import acorr_ljungbox
lb_test = acorr_ljungbox(errors, lags=[15])
print(f"Ljung-Box Test: p-value = {lb_test[1][0]}")

常见错误分析

系统性错误

  • 趋势偏移:模型无法捕捉数据中的趋势变化
    • 解决方法:添加趋势特征或使用差分
  • 季节性错误:在季节性高峰或低谷表现不佳
    • 解决方法:加强季节性特征或使用季节性模型
  • 水平偏移:整体预测水平过高或过低
    • 解决方法:检查特征处理和模型偏差

预测时长与准确性

  • 短期预测(1-7天)通常较准确
  • 中期预测(8-30天)准确性会下降
  • 长期预测(>30天)不确定性显著增加

与其他模块的关系

评估指标与误差分析是检验时序分析-数据预处理与趋势识别时序分析-传统统计模型时序分析-机器学习模型时序分析-深度学习模型效果的关键手段。不同评估指标适合不同的时序分析-应用场景,例如库存预测可能更关注RMSE,而销售预测可能更关注MAPE。在开发时序分析-混合方法时,评估指标也是选择最佳组合的依据。