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

我有一个algorithm,用Apache Commons计算一系列值(12个值)的percentile(85) ),以便稍后用阈值进行评估以作出决定。 结果与Excel给出的结果类似,但并不相同,有时候这对于我的应用程序来说是至关重要的,因为使用excel结果没有通过阈值,并且在Java使用Apache Commons Math,所以我得到了不同的结果。

这里是一个例子:每2小时互联网stream量(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()来改变百分位数的实现(它不存在官方的setPercentileImpl() ,但我找不到任何如何做这个的例子,或者Excelalgorithm(这是一个我被告知实现)。

任何有关这方面的帮助将受到欢迎。

谢谢。

差别是微妙的,并由于假设。 用3元素的情况来解释是最容易的。 假设你有三个元素(N = 3) a=x[0] < b=x[1] < c=x[2] 。 Apache和Excel方法都表示元素b是第50百分位数(中值)。 然而,他们不同的ac

Apache方法 (以及NIST页面引用的方法 )认为a是第25百分位, c是75%百分位,因为它将空间分成N + 1个区块,即分成几个区域。

Excel方法表示a是第0百分位, c是第100百分位,因为空间被分成N-1个区块,也就是一半。

因此,如果你想使用Excel方法,并且不想自己编写代码,那么可以从数组中删除最小和最大的元素,然后调用Apache方法 – 它应该给你完全相同的结果,除了在终点以外的百分位数上。

如果你想自己编写代码,下面给出一个简单的方法。 注意这些问题:

  • 这种sorting数组(所以改变它)
  • 这会由于sorting而花费O(N log(N))时间。 Apache方法使用快速selectalgorithm,所以需要O(N)的时间(谷歌“快速select”,如果你想知道更多)

代码(没有testing甚至编译,但应该给你一个想法)。

 // 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; } 

解决scheme是创build一个类PercentileExcel,这几乎是commons方法的百分点的副本,除了如何计算位置的小改动:

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

然后,您需要将此行添加到代码中,以便使用新的百分比类:

 setPercentileImpl(PercentileExcel); 

从数据集计算的百分位数没有唯一的定义。 请参阅维基百科页面 ,了解最常用的定义。

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())); } }