1

我正在计算以下数字列表的第 95 个百分位:

66,337.8,989.7,1134.6,1118.7,1097.9,1122.1,1121.3,1106.7,871,325.2,285.1,264.1,295.8,342.4

apache 库使用 NIST 标准来计算百分位数,这与 Excel 使用的方法相同。根据 Excel,上面列表的第 95 个百分位应该是 1125.85。

但是,使用以下代码,我得到了不同的结果:

DescriptiveStatistics shortList = new DescriptiveStatistics();



@BeforeTest
@Parameters("shortStatsList")
private void buildShortStatisticsList(String list) {
    StringTokenizer tokens = new StringTokenizer(list, ",");
    while (tokens.hasMoreTokens()) {
        shortList.addValue(Double.parseDouble(tokens.nextToken()));
    }
}

@Test
@Parameters("95thPercentileShortList")
public void percentileShortListTest(String percentile) {
    Assert.assertEquals(Double.toString(shortList.getPercentile(95)), percentile);
}

这失败并显示以下消息:

java.lang.AssertionError: expected:<1125.85> but was:<1134.6>
at org.testng.Assert.fail(Assert.java:89)
at org.testng.Assert.failNotEquals(Assert.java:489)

1134.6是列表中的最大值,不是第95个百分位,所以我不知道这个值是从哪里来的。

4

1 回答 1

3

根据它的文档,getPercentile()它使用的是百分位估计算法,如此处所记录

百分位数可以从 N 个测量值中估计如下:对于第 p 个百分位数,设置 p(N+1) 等于 k+d,对于 k 一个整数,d,一个大于或等于 0 且小于 1 的分数。

  1. 对于 0<k<N,Y (p) =Y [k] +d(Y [k+1] -Y [k] )

  2. 对于 k=0,Y (p) =Y [1]

    请注意,任何 p ≤ 1/(N+1) 都将简单地设置为最小值。

  3. 对于 k≥N,Y (p) =Y [N]

    请注意,任何 p ≥ N/(N+1) 都将简单地设置为最大值。

基本上,这意味着将请求的百分位数 (0.95) 乘以 (N+1)。在你的情况下,N 是 15,N+1 是 16,所以你得到 15.2。

您将其拆分为整个部分k(15) 和d(0.2)。k属于上述第 3 类。也就是说,估计的百分位数是最大值


如果您继续阅读我在上面链接的 NIST 文章,您将看到标题为“请注意,还有其他计算常用百分位数的方法”的部分。他们向您推荐 Hyndman & Fann 的一篇文章,该文章描述了几种计算百分位数的替代方法。认为只有一种NIST 方法是一种误解。Hyndman & Fann 中的方法由标签R1R9表示。文章接着说:

一些软件包将 1+p(N-1) 设置为等于 k+d,然后如上进行。这是 Hyndman 和 Fan 的方法 R7。这是 Excel 使用的方法,也是 R 的默认方法(R 分位数函数可以选择使用 Hyndman & Fan 中讨论的九种方法中的任何一种)。

Apache 默认使用的方法DescriptiveStatistics是 Hyndman & Fan 的R6。Excel 使用的方法是R7。它们都是“NIST 方法”,但是对于少量的测量,它们可以给出不同的结果。

请注意,Apache 库确实允许您通过使用该类来使用R7算法或任何其他算法。Percentile这样的事情应该可以解决问题:

DescriptiveStatistics shortList = new DescriptiveStatistics();
shortList.setPercentileImpl( new Percentile().
                                 withEstimationType( Percentile.EstimationType.R_7 ) );

(请注意,我没有对此进行测试)。

于 2015-05-19T18:14:52.940 回答