【问题标题】:Percentile calculation mismatch using apache.math3.stat.descriptive使用 apache.math3.stat.descriptive 的百分位数计算不匹配
【发布时间】:2015-05-20 16:15:31
【问题描述】:

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

【问题讨论】:

    标签: java excel apache-commons-math


    【解决方案1】:

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

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

    1. 对于 0(p)=Y[k]+d(Y[k+1] sub>−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 库确实允许您通过使用Percentile 类来使用R7 算法或任何其他算法。像这样的东西应该可以解决问题:

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

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

    【讨论】:

    • 感谢您的回答。 Excel 中的 PERCENTILE 函数使用与 NIST 计算不同的方法 - 但根据wikipedia,Excel 2010 函数 PERCENTIL.EXC 应该产生与 NIST 相同的答案。我还没有尝试过,但我认为它是正确的。
    • @eeijlar 我在回答中添加了更多信息以解决您的评论。
    猜你喜欢
    • 2012-04-05
    • 1970-01-01
    • 2017-09-04
    • 2015-02-25
    • 1970-01-01
    • 2011-12-29
    • 2013-06-20
    • 2016-07-28
    • 2017-08-29
    相关资源
    最近更新 更多