我有许多类似于
的数据框times = c("2015-12-30 20:00:00", "2016-01-06 20:00:00",
"2016-01-08 20:00:00", "2016-01-11 20:00:00",
"2016-01-13 20:00:00", "2016-01-14 20:00:00",
"2016-01-15 20:00:00", "2016-01-18 20:00:00",
"2016-01-20 20:00:00", "2016-01-21 20:00:00",
"2016-01-25 20:00:00")
counts = c(7, 14, 61, 1, 2, 66, 10, 35, 1, 304, 2)
df <- data.frame(timestamp = as.POSIXct(times, format="%Y-%m-%d %H:%M:%S",
tz="Pacific/Auckland"),
count = counts)
我试图识别与上面类似的数据集中的异常值。查看正常的Q-Q图和直方图,很明显这个样本不是正态分布。
hist(df$count)
qqnorm(df$count)
qqline(df$count)
接下来,我使用Box-Cox功率变换并尝试将数据接近正态分布数据。
lambda <- geoR::boxcoxfit(df$count)$lambda
df$transformed <- car::bcPower(df$count, lambda=lambda)
注意:我知道查找Box-Cox转换参数的其他方法,例如使用forecast
或car
个包。还有一些方法使用Box-Cox转换函数的扩展族并优化https://stats.stackexchange.com/a/35717/101902答案中的变量。我没有使用forecast
的原因之一是,在大多数情况下,我的数据不是等距的,并且不具有典型的时间序列属性。另一个原因是我需要自动化这个过程。任何适合GLM的方法,或者,LM盲目地只返回没有用的东西。
转换数据并计算转换数据的z分数后,我们得到
timestamp count transformed zscore
1 2015-12-30 20:00:00 7 1.7922836 -0.14446864
2 2016-01-06 20:00:00 14 2.3618561 0.22598616
3 2016-01-08 20:00:00 61 3.4646761 0.94326978
4 2016-01-11 20:00:00 1 0.0000000 -1.31018523
5 2016-01-13 20:00:00 2 0.6729577 -0.87248782
6 2016-01-14 20:00:00 66 3.5198741 0.97917102
7 2016-01-15 20:00:00 10 2.0895953 0.04890541
8 2016-01-18 20:00:00 35 3.0646823 0.68311037
9 2016-01-20 20:00:00 1 0.0000000 -1.31018523
10 2016-01-21 20:00:00 304 4.5195550 1.62937200
11 2016-01-25 20:00:00 2 0.6729577 -0.87248782
虽然在转换之后,数据更接近于正态分布的数据,但是具有1s的数据点正在使标准化过程发生偏差。因此,根本检测不到明确的异常值。关于标准化数据的大多数文章,博客文章或类似媒体从不谈论这些极端情况。
当我开始输入这个问题时,我会问是否有其他可以处理1的转换方法,但我意识到这并不重要。
您如何处理数据集中的许多相同值?特别是,如果它们处于两个极端,例如数据集的最小值或最大值。