所以这是一个部分数学,部分红宝石,部分统计问题,我只是不知道从哪里开始这样的东西,因为它可能比我准备的更大的东西但是,也许有人能够对如何为这类事情实施解决方案有所启发。
基本上,随着时间的推移,我有一组整数,比如我的哈希看起来像:
{ :count => 20, :timestamp => 1304566372 }
{ :count => 23, :timestamp => 1304566382 }
{ :count => 23, :timestamp => 1304566392 }
{ :count => 24, :timestamp => 1304566402 }
{ :count => 25, :timestamp => 1304566412 }
{ :count => 22, :timestamp => 1304566422 }
{ :count => 12, :timestamp => 1304566432 } # <= outlier
{ :count => 21, :timestamp => 1304566442 }
{ :count => 20, :timestamp => 1304566452 }
这组数据会大得多,但这可以作为一个例子,所以我想做的就是找到与平均值差别最大的结果,但整数将遵循一种曲线,所以你不能只是平均整套。图片就像对网站的访问者分析。
我想我的问题是,使用ruby,我可以使用数学来概括曲线并找出哪些项目与曲线的那一段上的平均值相差最远吗?
我不是最好的数学家,所以我可能完全使用错误的术语来描述这个。非常感谢所有人的帮助或提示!
答案 0 :(得分:6)
假设整数值属于正态分布,您可以应用3-sigma rule(标准偏差)来查找异常值。
假设您想快速计算整数列表的平均值和标准差。你可以像这样增强Enumerable:
module Enumerable
def sum
self.inject(0){|accum, i| accum + i }
end
def mean
self.sum/self.length.to_f
end
def sample_variance
m = self.mean
sum = self.inject(0){|accum, i| accum +(i-m)**2 }
(1/self.length.to_f*sum)
end
def standard_deviation
return Math.sqrt(self.sample_variance)
end
end
然后,您必须确定异常值的标准。在3-sigma规则下,所有整数值的95%将落在距平均值的标准偏差值(2 sigma)的两倍之内。因此,您可以说任何与平均值的差异大于2个标准差的值都是异常值。
例如,假设您将count
值总结为名为a
的数组:
a = [ 20, 23, 23, 24, 25, 22, 12, 21, 29 ]
m = a.mean
# => 22.11111111111111
sd = a.standard_deviation
# => 4.331908597692872
# assuming Ruby 1.9.2
a.keep_if { |n| (m-n).abs > (2*sd) }
# => results in 12 remaining
答案 1 :(得分:1)
如果您只是在寻找一个起点,我建议进行文献搜索[1]以“检测时间序列数据中的异常值”如果您可以将某种方程拟合到数据中,您可以查看在距曲线有多远的地方。如果系统更复杂且无法轻松建模,您可以遵循许多策略,例如......
只需查看数据点之间count
的增量即可。在您的系列中,增量列表为[3,0,1,1,-3,-10,9,-1]
。您可以查找超过此列表平均值的值超过几个标准差。实际上,你是通过寻找线斜率的大变化来寻找尖峰。
查看3到5个左右的小窗口,例如首先看1,2,3点然后点2,3,4,然后3,4,5等。这类似于第一种方法,但算法会有点不同。
有关数据性质的更多信息,可能会选择某种最佳算法,但快速和肮脏可能足够接近。
[1]这是一个老派的术语,只是一种说“谷歌”的奇特方式