Java Apache Commons getPercentile()与MS Excel百分位数不同的结果

问题描述 投票:11回答:5

我有一种算法,该算法使用一系列值(12个值)的percentile(85)计算Apache Commons,以便稍后使用阈值进行评估以做出决策。结果类似于Excel给出的结果,但不相等,有时这对我的应用程序很关键,因为使用excel时结果不会超过阈值,而使用Java中的Apache Commons Math可以达到此阈值,所以我得到了不同输出。

这里是一个示例:每2小时Internet流量(Mbps)

32,7076813360000000 41,2580429776000000 45,4453940200000000 48,8044409456000000 46,7462847936000000 49,8028100056000000 54,3719451144000000 41,9708134600000000 29,4371963240000000 22,4667255616000000 20,0388452248000000 28,7807757104000000

除以1000 Mb(电缆的容量)后,我计算出职业的百分比(85):

Excel:0,049153870117

Apache Commons Math:0.05003126676104001

我发现可以用setPercentileImpl()更改百分位数的实现(它不存在正式版本),但是我找不到如何执行此操作的示例或Excel算法(是告诉我要实现的目标)。

欢迎您提供任何帮助。

谢谢。

java excel statistics apache-commons percentile
5个回答
10
投票

差异是细微的,是基于假设的。用3元素的情况最容易解释。假设您有三个元素(N = 3)a=x[0] < b=x[1] < c=x[2]。 Apache和Excel方法都说元素b是第50个百分位数(中位数)。但是对于ac,它们是不同的。

Apache method(和the method referenced by the NIST page表示a是第25个百分位数,c是75%的百分位数,因为它将空间分成N + 1个块,即四分之一。

Excel方法说a是第0个百分点,c是第100个百分点,因为该空间被分成N-1个块,即一半。

因此,如果您要使用Excel方法并且不想自己编写代码,则可以从数组中删除最小和最大的元素,然后调用Apache方法-它应该为您提供完全相同的结果,但超出终点的百分位数除外。

如果您想自己编写代码,下面提供了一种简单的方法。请注意以下问题:

  • 这将对数组进行排序(因此将其更改)
  • 由于排序,这需要O(N log(N))时间。 Apache方法使用快速选择算法,因此需要O(N)时间(如果您想了解更多,请使用Google“ quickselect”)]

代码(未经测试,甚至未编译,但应该可以给您带来启发)。

// warning - modifies data 
double excelPercentile(double [] data, double percentile) { array
    Arrays.sort(data);
    double index = percentile*(data.length-1);
    int lower = (int)Math.floor(index);
    if(lower<0) { // should never happen, but be defensive
       return data[0];
    }
    if(lower>=data.length-1) { // only in 100 percentile case, but be defensive
       return data[data.length-1);
    }
    double fraction = index-lower;
    // linear interpolation
    double result=data[lower] + fraction*(data[lower+1]-data[lower]);
    return result;
 }

5
投票

该解决方案正在创建一个类PercentileExcel,该类几乎是commons方法中的百分位数的副本,只是对如何计算位置进行了微小的更改:

pos=(1+p*(n-1))/100;

然后您需要将此行添加到代码中,以便将新类用于百分位数:

setPercentileImpl(PercentileExcel);

4
投票

没有从数据集计算得出的百分位数的唯一定义。有关使用中最常见的定义,请参见Wikipedia page


4
投票

org.apache.commons.math3.stat.descriptive.rank.Percentile类已经支持Excel样式插值,您只需要通过EstimationType.R_7启用它即可。>

public class PercentileExcel extends Percentile {
    public PercentileExcel() throws MathIllegalArgumentException {

    super(50.0,
          EstimationType.R_7, // use excel style interpolation
          NaNStrategy.REMOVED,
          new KthSelector(new MedianOf3PivotingStrategy()));
    }
}

0
投票

我无法评论pbirnie的答案,但是以下不需要新类的替代方法在3.6中可行:Percentile p = new Percentile(50.0).withEstimationType(EstimationType.R_7) .withNaNStrategy(NaNStrategy.REMOVED) .withKthSelector(new KthSelector(new MedianOf3PivotingStrategy()))

© www.soinside.com 2019 - 2024. All rights reserved.