11

percentile(85)我有一个算法,可以计算Apache Commons一系列值(12个值)的值,以便稍后使用阈值进行评估以做出决定。结果类似于 Excel 给出的结果,但不相等,有时这对我的应用程序至关重要,因为使用 excel 的结果没有通过阈值,而使用 Apache Commons MathJava则可以,所以我得到不同的输出。

这是一个示例:每 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

阿帕奇公共数学:0.05003126676104001

我发现可以用 更改百分位数的实现(它不存在官方的)setPercentileImpl(),但我找不到如何做到这一点的任何示例,或者 Excel 算法(我是告诉实现)。

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

谢谢你。

4

5 回答 5

10

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

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

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

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

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

  • 这对数组进行排序(所以改变它)
  • 由于排序,这需要 O(N log(N)) 时间。Apache 方法使用快速选择算法,因此需要 O(N) 时间(如果您想了解更多信息,请使用谷歌“快速选择”)

代码(未经测试甚至编译,但应该给你一个想法)。

// 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;
 }
于 2011-05-10T12:53:53.320 回答
5

解决方案是创建一个类PercentileExcel,它几乎是 commons 方法的 percentile 的副本,除了如何计算位置的小变化:

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

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

setPercentileImpl(PercentileExcel);
于 2012-01-11T16:25:35.643 回答
5

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()));
    }
}
于 2015-06-12T13:26:08.993 回答
4

从数据集计算的百分位数没有唯一的定义。有关最常用的定义,请参阅Wikipedia 页面。

于 2011-05-10T12:27:16.270 回答
1

以下不需要新类的替代方案在 3.6 中有效:

DescriptiveStatistics ds = new DescriptiveStatistics();
Percentile p = new Percentile(50.0).withEstimationType(EstimationType.R_7)
                .withNaNStrategy(NaNStrategy.REMOVED)
                .withKthSelector(new KthSelector(new 
                  MedianOf3PivotingStrategy()))
ds.setPercentileImpl(p);
于 2020-01-09T15:18:54.837 回答