前言
本文主要记录使用时间序列模型进行预测及异常值检测的相关笔记
1. 简介
在数据分析中,常常有根据时间变化而变化的数据,这时难免会出现一些异常数据,比如突然增大、突然变小等情况,此时我们就可以使用Facebook提出的Prohpet算法进行异常值检测。这个方法主要是激昂数据波动情况拟合值的置信区间作为判断是否为异常值的上下界。本文将利用此算法在一个数据集上进行检测。
2. 步骤
本次判断的异常值主要为PM2.5的浓度变化随时间变化情况,并判断异常值。下面是具体步骤:
1、首先我们读入数据,将数据存储到一个时序数据变量中,然后输出时间序列数据的波动情况;
2、通过时序数据获得时序数据拟合模型,然后对数据变化趋势和波动情况进行拟合(其中包含了默认置信度95%下的上下界);
3、通过第2步获得的置信区间的上下界,来确定样本中那些数据为异常值,并赋值新建的一个变量。最后根据第2步获得的预测值与第3步获得的异常值还有原始数据进行可视化。
计算某一列值从第一行到当前行的累计和
表table1中有id列和num列,计算从第一行的num值到当前行的num值累计和。
3. 代码
import matplotlib
import seaborn as sns
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pmdarima as pm
from fbprophet import Prophet
matplotlib.rcParams['axes.unicode_minus'] = False
# 解决图像显示中文的问题
sns.set(font="Kaiti", style="ticks", font_scale=1.4)
# 判断并返回异常值
def outlier_detection(forecast):
index = np.where((forecast["y"] <= forecast["yhat_lower"]) |
(forecast["y"] >= forecast["yhat_upper"]), True, False)
return index
if __name__ == "__main__":
# 数据准备
data_ini = pd.read_csv('Ar.csv')
data = pm.datasets.load_gasoline()
datadf = pd.DataFrame({"y": data_ini['PM2']})
datadf["ds"] = data_ini['B']
# 可视化时间序列的变化情况
datadf.plot(x="ds", y="y", style="b-o", figsize=(14, 7))
plt.ylabel('样\n本\n值\n', rotation=0, verticalalignment='bottom',
horizontalalignment='left', labelpad=19, y=0.36)
plt.grid()
plt.savefig('时间序列结果.pdf')
plt.show()
model = Prophet(growth="linear", daily_seasonality=False,
weekly_seasonality=False,
seasonality_mode='multiplicative',
interval_width=0.95, # 获取95%的置信区间
)
model = model.fit(datadf) # 使用数据拟合模型
forecast = model.predict(datadf) # 使用模型对数据进行预测
forecast["y"] = datadf["y"].reset_index(drop=True)
# 输出前5行已有数据
forecast[["ds", "y", "yhat", "yhat_lower", "yhat_upper"]].head()
outlier_index = outlier_detection(forecast)
outlier_df = datadf[outlier_index] # 异常数据
print("异常值的数量为:", sum(outlier_index))
# 可视化异常值的结果
fig, ax = plt.subplots()
# 置信区间可视化
ax.fill_between(forecast["ds"].values, forecast["yhat_lower"],
forecast["yhat_upper"], color='b', alpha=.2,
label="95%置信区间")
# 预测值可视化
forecast.plot(x="ds", y="yhat", style="b-", figsize=(14, 7),
label="预测值", ax=ax)
# kind="scatter"意思为制作散点图,s控制点的大小
forecast.plot(kind="scatter", x="ds", y="y", c="k", s=20, label="原始数据", ax=ax)
# 异常值点可视化
outlier_df.plot(kind="scatter", x="ds", y="y", s=60, style="rs", ax=ax, label="异常值")
plt.ylabel('样\n本\n值\n', rotation=0, verticalalignment='bottom', horizontalalignment='left', labelpad=19, y=0.36)
plt.legend(loc=2)
plt.grid()
plt.savefig('时间序列结果预测加异常值检测.pdf')
plt.show()
4. 结果图展示
首先是原始数据的时间序列图,结果如下:
然后是预测模型图及异常值图,结果如下:
如上图所示,异常值在阴影范围之外。
5. 参考资料及数据文件获取
参考资料:Python时序数据的异常值检测.
数据文件:百度云链接-点击此处 提取码:ebf5