百分点计算不匹配使用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()的文档,它使用百分比估计algorithm,如此getPercentile()logging的。

可以从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分位数函数可以select使用Hyndman&Fan中讨论的九种方法中的任何一种)。

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

请注意,通过使用Percentile类,Apache库允许您使用R7algorithm或任何其他algorithm。 像这样的事情应该做的伎俩:

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

(请注意,我没有testing过)。