我有很多类似于
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)
我正在尝试识别与上述类似的数据集中的异常值。查看正态 QQ 图和直方图,很明显这个样本不是来自正态分布。
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 转换参数的其他方法,例如 usingforecast
或car
packages。还有一些方法使用 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
尽管在转换之后,数据更接近于正态分布的数据,但数据点为 1 会扭曲标准化过程。因此,根本没有检测到明显的异常值。大多数关于标准化数据的文章、博客文章或类似媒体从不谈论这些极端情况。
当我开始输入这个问题时,我想问是否还有其他可以处理 1 的转换方法,但我意识到这并不重要。
您将如何处理数据集中有许多相同的值?特别是,如果它们处于两个极端,例如数据集的最小值或最大值。