异常检测在时间序列数据中的应用

异常检测数据科学中的一个重要环节,它涉及到识别偏离数据集常规行为的数据点。异常数据可能表明关键事件,如金融欺诈、软件问题或潜在机会,比如用户购买模式的变化。

时间序列异常检测

时间序列的异常检测过程分为三个步骤:将时间序列分解为底层变量(趋势、季节性、残差),创建带有某些阈值的上下阈值,并识别超出阈值的数据点作为异常。

案例研究

将从新加坡政府网站下载数据集,该数据集展示了按住宅类型划分的家庭总电力消耗(以GWh为单位)。新加坡政府数据网站的数据非常容易下载。

该数据集由能源市场管理局管理,每年发布一次,遵循新加坡开放数据许可。

安装和加载R包

在这个练习中,将使用R中两个关键的时间序列异常检测包:anomalize和timetk。这些包要求对象被创建为时间tibble,因此还将加载tibble包。首先,安装并加载这些库。

pkg <- c('tidyverse','tibbletime','anomalize','timetk') install.packages(pkg) library(tidyverse) library(tibbletime) library(anomalize) library(timetk)

加载数据

在上一步中,已经从新加坡政府网站下载了按住宅类型划分的总电力消耗文件(以GWh为单位)。让将CSV文件加载到R数据框中。

df <- read.csv("C:/Anomaly Detection in R/total-household-electricity-consumption.csv") head(df,5)

数据处理

在应用任何异常算法之前,需要将数据转换为日期格式。原始的“月份”列是因子格式,有很多级别。让将其转换为日期类型,并在数据框中仅选择相关列。

df$month <- paste(df$month, "01", sep="-") df$month <- as.Date(df$month,format="%Y-%m-%d") df <- df %>% select(month,overall) df <- as_tibble(df) class(df)

使用‘anomalize’包

R的‘anomalize’包支持数据中异常检测的工作流程。主要函数包括time_decompose()、anomalize()和time_recompose()。

df_anomalized <- df %>% time_decompose(overall, merge = TRUE) %>% anomalize(remainder) %>% time_recompose() df_anomalized %>% glimpse()

可视化异常

然后可以使用plot_anomalies()函数可视化异常。

df_anomalized %>% plot_anomalies(ncol = 3, alpha_dots = 0.75)

调整趋势和季节性

使用anomalize进行调整非常简单,因为一切都是通过日期或DateTime信息完成的,所以可以直观地选择有意义的时间跨度增量(例如“5分钟”或“1个月”)。

首先,注意频率和趋势为自动选择了。这是有意为之的。参数frequency = “auto”和trend = “auto”是默认值。可以使用plot_anomaly_decomposition()来可视化这种分解。

p1 <- df_anomalized %>% plot_anomaly_decomposition() + ggtitle("Freq/Trend = 'auto'") p1

调整局部参数

局部参数调整是通过调整函数内参数来执行的。下面调整趋势为“2周”,这将导致趋势过于拟合。

p2 <- df %>% time_decompose(overall, frequency = "auto", trend = "2 weeks") %>% anomalize(remainder) %>% plot_anomaly_decomposition() + ggtitle("Trend = 2 Weeks (Local)")

调整全局参数

也可以通过使用set_time_scale_template()全局调整。将“3个月”的趋势更改为“2周”,用于时间尺度=“天”。使用time_scale_template()检索anomalize开始的默认模板,mutate()在所需位置更改趋势字段,并使用set_time_scale_template()更新全局选项中的模板。可以使用get_time_scale_template()检索更新后的模板,以验证更改是否已正确执行。

time_scale_template() %>% mutate(trend = ifelse(time_scale == "day", "2 weeks", trend)) %>% set_time_scale_template() get_time_scale_template()

提取异常数据点

现在,可以提取实际的异常数据点。为此,可以运行以下代码。

df %>% time_decompose(overall) %>% anomalize(remainder) %>% time_recompose() %>% filter(anomaly == 'Yes')

调整Alpha和Max Anoms

alpha和max_anoms是控制anomalize()函数的两个参数。

Alpha

可以调整alpha,默认设置为0.05。默认情况下,带仅覆盖范围之外的部分。

p4 <- df %>% time_decompose(overall) %>% anomalize(remainder, alpha = 0.05, max_anoms = 0.2) %>% time_recompose() %>% plot_anomalies(time_recomposed = TRUE) + ggtitle("alpha = 0.05")

如果减少alpha,它会增加带的大小,使得成为异常值更加困难。这里,可以看到带的大小已经翻倍。

p5 <- df %>% time_decompose(overall) %>% anomalize(remainder, alpha = 0.025, max_anoms = 0.2) %>% time_recompose() %>% plot_anomalies(time_recomposed = TRUE) + ggtitle("alpha = 0.025")

Max Anoms

max_anoms参数用于控制数据中可以作为异常的最大百分比。让调整alpha = 0.3,以便几乎所有东西都是异常值。现在让尝试比较max_anoms = 0.2(允许20%的异常)和max_anoms = 0.05(允许5%的异常)。

p6 <- df %>% time_decompose(overall) %>% anomalize(remainder, alpha = 0.3, max_anoms = 0.2) %>% time_recompose() %>% plot_anomalies(time_recomposed = TRUE) + ggtitle("20% Anomalies") p7 <- df %>% time_decompose(overall) %>% anomalize(remainder, alpha = 0.3, max_anoms = 0.05) %>% time_recompose() %>% plot_anomalies(time_recomposed = TRUE) + ggtitle("5% Anomalies")

这是一个用于在R中处理时间序列的工具包,用于绘制、整理和特征工程时间序列数据,以进行预测和机器学习预测。

交互式异常可视化

df %>% timetk::plot_anomaly_diagnostics(month,overall, .facet_ncol = 2) df %>% timetk::tk_anomaly_diagnostics(month, overall) %>% filter(anomaly=='Yes')
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485