我有一个算法,用percentile(85)
计算一系列值{12}的Apache Commons
,以便稍后评估一个阈值来做出决定。结果与Excel给出的结果类似,但不相等,有时这对我的应用程序至关重要,因为使用excel时,结果不会超过阈值,并且Java
中的Apache Commons Math会这样做,所以我获得不同的输出。
这是一个例子:互联网流量(Mbps)每2小时
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算法(这是我被告知要实现的)。
欢迎任何有关此事的帮助。
谢谢。
答案 0 :(得分:10)
差异是微妙的,并且由于假设。最容易用3元素的情况来解释。假设您有三个元素(N = 3)a=x[0] < b=x[1] < c=x[2]
。 Apache和Excel方法都说元素b是第50个百分位数(中位数)。但是,它们与a
和c
不同。
Apache method(和the method referenced by the NIST page)说a
是第25百分位,c
是75%百分位数,因为它将空间划分为N + 1个区块,也就是进入宿舍。
Excel方法表示a
是第0百分位数,c
是第100百分位数,因为空间被划分为N-1个区块,即一半。
因此,如果你想要Excel方法并且你不想自己编写代码,你可以从数组中删除最小和最大的元素,并调用Apache方法 - 它应该给你完全的除了终点以外的百分位数,结果相同。
如果您想自己编写代码,请在下面给出一个简单的方法。请注意以下问题:
代码(未测试或甚至编译,但应该给你一个想法)。
// 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;
}
答案 1 :(得分:5)
解决方案是创建一个 PercentileExcel 类,这几乎是公共方法百分位数的副本,除了如何计算位置的小变化:
pos=(1+p*(n-1))/100;
然后,您需要将此行添加到代码中,以便将新类用于百分位数:
setPercentileImpl(PercentileExcel);
答案 2 :(得分:4)
没有从数据集计算的百分位数的唯一定义。有关最常用的定义,请参阅Wikipedia page。
答案 3 :(得分:2)
类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()));
}
}
答案 4 :(得分: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);