8

我想分析一些数据(例如,Web 服务响应时间)并获取各种统计信息,主要是百分位数/分位数和突出值的存在。

我知道Statistics::Descriptive,但是,我不想将所有数据存储在内存中。另一方面,将我的结果降低几个百分点就可以了,我只关心巨大的差异。

所以我想出了以下想法:创建一个对数存储桶数组,并计算每个存储桶中的数据点。将数据分布在 6 个数量级并保证 1% 的精度仍然给我留下了6 * log 10 / log 1.01 =~ 1400非常好的存储桶(36 kb 的内存,给定当前 Perl 的标量大小)。

计算百分位数很简单 - 只需将桶计数器相加直到$sum超过$percentage * $total_count

但是,在我开始编写实际代码之前,我想问一下已经存在哪些内存高效统计模块(用于 Perl)和算法。

我发现了这个问题,并且在其中一个答案中提出了类似的方法。不过,还没有找到现成的 Perl 实现。

这是这个 Perlmonks question的略微编辑版本。

4

1 回答 1

1

由于到目前为止我的搜索不成功,我已经启动了一个新模块Statistics::Descriptive::LogScale。希望它会有所帮助。

它通常遵循Statistics::Descriptive::Full的 API ,并添加了一些小的附加功能(例如添加了任意幂的中心和标准化时刻)。我还计划更仔细地研究Statistics::Descriptive::Weighted

#!/usr/bin/perl -w

use strict;
use Statistics::Descriptive::LogScale;

my $stat = Statistics::Descriptive::LogScale->new ();
while(<>) { 
    $stat->add_data(m/(-?\d+(?:\.\d*))/g);
};

# This can also be done in O(1) memory, precisely
printf "Average: %f +- %f\n", 
    $stat->mean, $stat->standard_deviation;

# This requires storing actual data, or approximating
foreach (0.5, 1, 5, 10, 25, 50, 75, 90, 95, 99, 99.5) {
    printf "Percentile($_): %f\n", $stat->percentile($_);
};
于 2013-06-29T10:29:07.773 回答