平稳性与稳定性

Python 中的时间序列机器学习

Chris Holdgraf

Fellow, Berkeley Institute for Data Science

平稳性

  • 平稳时间序列的统计特性随时间不变
  • 如:均值、标准差、趋势
  • 大多数时间序列在某种程度上是非平稳的
Python 中的时间序列机器学习

Python 中的时间序列机器学习

模型稳定性

  • 非平稳数据会导致模型结果波动
  • 模型学到的统计特性可能随数据改变
  • 因此我们对参数真值的把握更不确定
  • 如何量化这种情况?
Python 中的时间序列机器学习

用交叉验证量化参数稳定性

  • 一种方法:交叉验证
  • 在每次迭代中计算模型参数
  • 跨所有 CV 切分评估参数稳定性
Python 中的时间序列机器学习

自助法估计均值

  • 自助法是常见的波动性评估方法
  • 自助法步骤:
    1. 从数据中随机有放回抽样
    2. 计算样本均值
    3. 重复多次(上千次)
    4. 计算结果分位数(通常 2.5、97.5)

得到每个系数均值的"95% 置信区间"。

Python 中的时间序列机器学习

自助法估计均值

from sklearn.utils import resample

# cv_coefficients has shape (n_cv_folds, n_coefficients)
n_boots = 100
bootstrap_means = np.zeros(n_boots, n_coefficients)
for ii in range(n_boots):
    # Generate random indices for our data with replacement, 
    # then take the sample mean
    random_sample = resample(cv_coefficients)
    bootstrap_means[ii] = random_sample.mean(axis=0)

# Compute the percentiles of choice for the bootstrapped means
percentiles = np.percentile(bootstrap_means, (2.5, 97.5), axis=0)
Python 中的时间序列机器学习

绘制自助采样得到的系数

fig, ax = plt.subplots()
ax.scatter(many_shifts.columns, percentiles[0], marker='_', s=200)
ax.scatter(many_shifts.columns, percentiles[1], marker='_', s=200)

Python 中的时间序列机器学习

评估模型性能的稳定性

  • 使用 TimeSeriesSplit 时,可随时间"绘制"模型分数
  • 有助于发现拉低分数的时间段
  • 也可用于发现非平稳信号
Python 中的时间序列机器学习

模型性能的时间变化

def my_corrcoef(est, X, y):
    """Return the correlation coefficient 
    between model predictions and a validation set."""
    return np.corrcoef(y, est.predict(X))[1, 0]

# Grab the date of the first index of each validation set
first_indices = [data.index[tt[0]] for tr, tt in cv.split(X, y)]

# Calculate the CV scores and convert to a Pandas Series
cv_scores = cross_val_score(model, X, y, cv=cv, scoring=my_corrcoef)
cv_scores = pd.Series(cv_scores, index=first_indices)
Python 中的时间序列机器学习

将模型分数可视化为时间序列

fig, axs = plt.subplots(2, 1, figsize=(10, 5), sharex=True)

# Calculate a rolling mean of scores over time
cv_scores_mean = cv_scores.rolling(10, min_periods=1).mean()
cv_scores.plot(ax=axs[0])
axs[0].set(title='Validation scores (correlation)', ylim=[0, 1])

# Plot the raw data
data.plot(ax=axs[1])
axs[1].set(title='Validation data')
Python 中的时间序列机器学习

模型分数可视化

Python 中的时间序列机器学习

时间序列交叉验证中的固定窗口

# 仅保留训练数据的最后 100 个点
window = 100

# 使用该窗口大小初始化 CV
cv = TimeSeriesSplit(n_splits=10, max_train_size=window)
Python 中的时间序列机器学习

非平稳信号

Python 中的时间序列机器学习

¡Vamos a practicar!

Python 中的时间序列机器学习

Preparing Video For Download...