使用 apache 的百分位数计算不匹配。math3.stat.descriptive

Percentile calculation mismatch using apache.math3.stat.descriptive

我正在计算以下数字列表的第 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 个百分位,所以我不知道这个值是从哪里来的。

根据 getPercentile() 的文档,它正在使用百分位数 估计 算法,如记录 here

Percentiles can be estimated from N measurements as follows: for the pth percentile, set p(N+1) equal to k+d for k an integer, and d, a fraction greater than or equal to 0 and less than 1.

  1. For 0<k<N,  Y(p)=Y[k]+d(Y[k+1]−Y[k])

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

    Note that any p ≤ 1/(N+1) will simply be set to the minimum value.

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

    Note that any p ≥ N/(N+1) will simply be set to the maximum value.

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

您将其拆分为整个部分 k (15) 和 d (0.2)。 k 属于上述第 3 类。即预估百分位数为最大值.


如果您继续阅读我上面链接的 NIST 文章,您将看到标题为 "Note that there are other ways of calculating percentiles in common use" 的部分。他们建议您参考 Hyndman & Fann 的一篇文章,其中描述了几种计算百分位数的替代方法。认为有 one NIST 方法是一种误解。 Hyndman & Fann 中的方法由标签 R1R9 表示。文章接着说:

Some software packages set 1+p(N−1) equal to k+d and then proceed as above. This is method R7 of Hyndman and Fan. This is the method used by Excel and is the default method for R (the R quantile function can optionally use any of the nine methods discussed in Hyndman & Fan).

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

请注意,Apache 库允许您使用 R7 算法或任何其他算法,方法是使用 Percentile class。这样的事情应该可以解决问题:

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

(请注意,我还没有测试过)。