方法
Prophet异常检测使用了Prophet时间序列预测。基本的Prophet模型是一个可分解的单变量时间序列模型,结合了趋势、季节性和节假日效应。该模型预测还包括一个围绕估计的趋势部分的不确定性区间。另外,完全的贝叶斯推断也可以以增加计算量为代价。然后,不确定性区间的上限和下限值可以作为每个时间点的离群点阈值。首先,计算从观测值到最近的不确定度边界(上限或下限)的距离。如果观察值在边界内,离群点得分等于负距离。因此,当观测值与模型预测值相等时,离群点得分最低。如果观察值在边界之外,得分等于距离测量,观察值被标记为离群点。然而,该方法的一个主要缺点是,当新的数据进来时,你需要重新调整模型。这对于具有实时检测的应用来说是不可取的。
数据集
这个例子使用了地球化学研究所记录的天气时间序列数据集。该数据集包含14个不同的特征,如空气温度、大气压力和湿度。这些都是在2003年开始,每10分钟收集一次。我们只使用2009年至2016年期间收集的数据。
import matplotlib.pyplot as plt import numpy as np import os import pandas as pd import tensorflow as tf
加载数据集
df = pd.read_csv(csv_path) df['Date Time'] = pd.to_datetime(df['Date Time'], format='%d.%m.%Y %H:%M:%S') df.head()
选择子集来测试Prophet模型。
n_prophet = 10000
Prophet模型需要得到一个有两列的DataFrame:一列名为ds,包含时间戳,一列名为y,包含要评估的时间序列。我们只看温度数据。
print(df_T.shape) df_T.head()
plt.plot(df_T['ds'], df_T['y'])
加载或定义离群检测
你可以将预训练的模型保存在本地目录的文件路径中,并加载检测模型。或者,你也可以从头开始训练一个检测模型。
filepath = 'my_path' # 改为下载模型的目录 if outlier_detector: # 加载预训练的离群检测器 filepath = os.path.join(filepath, detector_name) else: # 初始化、拟合并保存离群检测 od.fit(df_T)
请查看文档以及原始的Prophet文档,了解如何定制基于Prophet的异常值检测器,并添加季节性因素、假期、选择饱和逻辑增长模型或应用参数正则化。
预测测试数据中的异常值
定义测试数据。重要的是,测试数据的时间与训练数据一致。下面我们通过比较测试数据框的前几行和训练数据框的最后几行来检查这一点。
df_T_test = pd.DataFrame(data=d)
df_T.tail()
预测测试数据的异常值。
predict( df_T_test )
结果可视化
我们可以用Prophet将我们的预测结果可视化。包括历史预测。
model.predict(future) model.plot(forecast)
我们还可以绘制预测中不同成分的细分。预测的不确定性区间是由外推趋势的MAP估计值决定的。
plot_component(forecast)
很明显,我们对未来的预测越远,决定离群值阈值的不确定性区间就越大。
让我们把实际数据与离群点阈值的上限和下限预测值叠加起来,检查我们预测的离群点在哪里。
plot(x='ds', y=['y', 'yhat', 'yhat_upper', 'yhat_lower'])
异常点的得分和预测。
np.zeros(n_periods) plot(x='ds', y=['score', 'threshold'])
当我们进一步预测未来时,随着不确定性的增加,离群点的分数自然呈下降趋势。
让我们来看看一些个别的离群值。
outlier = fcst.loc[fcst['score'] > 0] print((outlier.shape[0]))