使用 PyCaret 进行时间序列异常检测
实战教程
使用 PyCaret 进行时间序列异常检测
一篇关于使用 PyCaret 的无监督异常检测模块对时间序列数据进行检测的逐步教程
👉 简介
这是一篇逐步、适合初学者的教程,介绍了如何使用 PyCaret 的无监督异常检测模块在时间序列数据中检测异常。
本教程的学习目标
- 什么是异常检测?异常检测的类型。
- 业务中的异常检测用例。
- 使用 PyCaret 训练和评估异常检测模型。
- 标记异常值并分析结果。
👉 PyCaret
PyCaret 是一个开源的、低代码机器学习库和端到端模型管理工具,用Python编写,用于自动化机器学习工作流程。它因易用性、简单性以及快速高效地构建和部署端到端机器学习原型而广受欢迎。
PyCaret 是一个替代低代码库,可以用少量代码取代数百行代码。这使得实验周期变得指数级快速和高效。
PyCaret 简单且易于使用。PyCaret 中执行的所有操作都顺序存储在 一个Pipeline中,该Pipeline完全自动化用于部署。无论是填补缺失值、独热编码、转换分类数据、特征工程,甚至超参数调整,PyCaret 都可以自动化完成。
要了解更多关于 PyCaret,请查看他们的GitHub。
👉 安装 PyCaret
安装 PyCaret 非常简单,只需几分钟即可完成。我们强烈建议使用虚拟环境,以避免与其他库可能发生的冲突。
PyCaret 的默认安装是 pycaret 的精简版本,只安装了这里列出的硬依赖。
# 安装精简版本(默认)
pip install pycaret
# 安装完整版本
pip install pycaret[full]
当您安装 pycaret 的完整版本时,还会安装这里列出的所有可选依赖。
👉 什么是异常检测
异常检测是一种用于识别与大多数数据显著不同的罕见项目、事件或观察的技术。
通常,异常项目会转化为某种问题,例如:
- 银行欺诈,
- 结构缺陷,
- 医疗问题,
- 错误等。
异常检测算法大致可分为以下几类:
**(a) 监督:** 当数据集具有标识哪些交易是异常和哪些是正常的标签时使用。(这类似于监督分类问题)。
**(b) 无监督:** 无监督意味着没有标签,模型在完 整数据上进行训练,并假设大多数实例是正常的。
(c) 半监督: 模型仅在正常数据上进行训练(没有任何异常)。当训练好的模型用于新数据点时,它可以预测新数据点是正常的还是异常的(基于训练模型中数据的分布)。
👉 PyCaret 异常检测模块
PyCaret 的**异常检测** 模块是一个用于识别罕见项目、事件或观察的无监督机器学习模块。它提供了超过15种算法和多个图表来分析训练模型的结果。
👉 数据集
我将使用包含从2014年7月到2015年1月每半小时的出租车乘客数量的 NYC 出租车乘客数据集。您可以从这里下载数据集。
import pandas as pd
data = pd.read_csv('https://raw.githubusercontent.com/numenta/NAB/master/data/realKnownCause/nyc_taxi.csv')
data['timestamp'] = pd.to_datetime(data['timestamp'])
data.head()
# 创建移动平均线
data['MA48'] = data['value'].rolling(48).mean()
data['MA336'] = data['value'].rolling(336).mean()
# 绘图
import plotly.express as px
fig = px.line(data, x="timestamp", y=['value', 'MA48', 'MA336'], title='NYC 出租车行程', template='plotly_dark')
fig.show()
👉 数据准备
由于算法无法直接处理日期或时间戳数据,我们将从时间戳中提取特征,并在训练模型之前删除实际的时间戳列。
# 删除移动平均列
data.drop(['MA48', 'MA336'], axis=1, inplace=True)
# 将时间戳设置为索引
data.set_index('timestamp', drop=True, inplace=True)
# 将时间序列重采样为小时级别
data = data.resample('H').sum()
# 从日期中创建特征
data['day'] = [i.day for i in data.index]
data['day_name'] = [i.day_name() for i in data.index]
data['day_of_year'] = [i.dayofyear for i in data.index]
data['week_of_year'] = [i.weekofyear for i in data.index]
data['hour'] = [i.hour for i in data.index]
data['is_weekday'] = [i.isoweekday() for i in data.index]
data.head()