You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在时间序列预测图中添加95%置信区间?代码相关疑问咨询

关于时间序列预测图中95%置信区间的问题解答

首先得明确:你当前代码里的置信区间计算逻辑是完全错误的,不是把0.1换成0.05就能解决的,咱们一步步拆解问题:


1. 你的置信区间计算错在哪?

原来的代码行:

ci = 0.1 * np.std(y_for)/np.mean(y_for)

这本质是用预测值的变异系数(标准差/均值)乘以0.1,和统计意义上的95%置信区间没有任何关系。95%置信区间的核心是围绕预测值,考虑预测误差的分布,而不是预测值本身的离散程度。

如果假设预测误差服从正态分布,95%置信区间对应的是「预测值 ± 1.96 × 预测的标准误差」——这里的标准误差是模型预测的不确定性,不是预测值的标准差。


2. 关于正态性假设的疑问

是的,如果你用「1.96倍标准误差」的方式计算置信区间,确实隐含了预测误差服从正态分布的假设。如果你的时间序列数据或预测误差明显不符合正态性(比如厚尾、偏态),这种方法会不准确,此时更适合用非参数方法(比如bootstrap)生成置信区间。


3. 自动生成置信区间的实用方法

最省心的方式是用statsmodels这类专业时间序列库,它的模型(比如ARIMA、SARIMAX)在预测时会直接返回置信区间,无需手动计算。下面是完整的示例代码:

方法1:用statsmodels内置置信区间(推荐)

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.statespace.sarimax import SARIMAX

# 替换成你的数据和预测步长
data = df1['Annualised vol21']
forecast_horizon = 你的预测步长数值

# 拟合模型(这里用SARIMAX,你可以换成自己的模型,比如ARIMA)
model = SARIMAX(data[:-forecast_horizon], order=(1,1,1), seasonal_order=(0,0,0,0))
results = model.fit()

# 直接获取拟合值、预测值和95%置信区间
fitted_values = results.fittedvalues
forecast_values = results.get_forecast(steps=forecast_horizon).predicted_mean
confidence_interval = results.get_forecast(steps=forecast_horizon).conf_int()

# 整理数据用于绘图
volatility = pd.DataFrame({
    'actual': data.values,
    'model': np.append(fitted_values, forecast_values)
}, index=data.index)

y_train = volatility['actual'][:-forecast_horizon]
y_fit = volatility['model'][:-forecast_horizon]
y_test = volatility['actual'][-forecast_horizon:]
y_for = volatility['model'][-forecast_horizon:]

# 绘图
plt.plot(y_train.index, y_train, label='Train')
plt.plot(y_test.index, y_test, label='Test')
plt.plot(y_fit.index, y_fit, label='Fitted')
plt.plot(y_for.index, y_for, label='Forecasted')

# 绘制95%置信区间
plt.fill_between(y_for.index, confidence_interval[:,0], confidence_interval[:,1], 
                 color='b', alpha=.3, label='95% Confidence Interval')

plt.legend()
plt.ylim(0, 0.2)
plt.xlim(5000, 5500)
plt.show()

方法2:Bootstrap非参数置信区间(适合非正态数据)

如果你的数据不满足正态性,可以用bootstrap方法手动生成置信区间,无需分布假设:

# 定义bootstrap置信区间计算函数
def bootstrap_prediction_ci(y_true, y_fitted, y_forecast, n_iter=1000):
    # 提取拟合阶段的误差
    fit_errors = y_true[:-len(y_forecast)] - y_fitted
    ci_lower = []
    ci_upper = []
    # 多次重采样误差生成预测区间
    for _ in range(n_iter):
        resampled_errors = np.random.choice(fit_errors, size=len(y_forecast), replace=True)
        bootstrap_pred = y_forecast + resampled_errors
        ci_lower.append(np.percentile(bootstrap_pred, 2.5))
        ci_upper.append(np.percentile(bootstrap_pred, 97.5))
    return np.array([ci_lower, ci_upper]).T

# 计算bootstrap置信区间
boot_ci = bootstrap_prediction_ci(volatility['actual'], y_fit, y_for)

# 绘图时替换置信区间即可
plt.fill_between(y_for.index, boot_ci[:,0], boot_ci[:,1], 
                 color='b', alpha=.3, label='95% Bootstrap CI')

内容的提问来源于stack exchange,提问作者Luigi87

火山引擎 最新活动