Java Apache Commons getPercentile () resultado diferente que el percentil MS Excel

Tengo un algoritmo que calcula el percentile(85)con Apache Commonsuna serie de valores (12 valores), para una evaluación posterior con un umbral para tomar una decisión. El resultado es similar al dado por Excel, pero no igual, y a veces esto es crítico para mi aplicación porque con Excel el resultado no pasa el umbral y con Apache Commons Math Javalo hace, así que obtengo resultados diferentes.

Aquí hay un ejemplo: tráfico de Internet (Mbps) cada 2 horas

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

Después de dividir por 1000 Mb (la capacidad del cable) calculo el percentil (85) de la ocupación:

Excel: 0,049153870117

Apache Commons Math: 0.05003126676104001

He descubierto que es posible cambiar la implementación del percentil (no existe uno oficial) con setPercentileImpl(), pero no pude encontrar ningún ejemplo de cómo hacerlo, o el algoritmo de Excel (que es el que era dicho para lograr).

Cualquier ayuda sobre esto será bienvenida.

Gracias.

Respuesta 1

La diferencia es sutil y se debe a suposiciones. Es más fácil de explicar con el caso de 3 elementos. Supongamos que tiene tres elementos (N = 3) a=x[0] < b=x[1] < c=x[2]. Tanto el método Apache como el de Excel dicen que el elemento b es el percentil 50 (la mediana). Sin embargo, difieren para ay c.

El método Apache (y el método al que hace referencia la página NIST ) dicen que aes el percentil 25 y ces el percentil 75%, porque divide el espacio en bloques N + 1, es decir, en cuartos.

El método Excel dice que aes el percentil 0 y cel percentil 100, ya que el espacio se divide en bloques N-1, es decir, a la mitad.

Debido a esto, si desea el método de Excel y no desea codificarlo usted mismo, simplemente puede eliminar el elemento más pequeño y el más grande de su matriz, y llamar al método Apache; debería darle exactamente el mismo resultado, excepto en percentiles más allá de los puntos finales.

Si desea codificarlo usted mismo, a continuación se ofrece una manera fácil. Tenga en cuenta estos problemas:

  • esto ordena la matriz (así que la cambia)
  • esto toma tiempo O (N log (N)) debido a la clasificación. El método Apache utiliza un algoritmo de selección rápida, por lo que toma tiempo O (N) (google "selección rápida" si desea saber más)

Código (no probado o incluso compilado, pero debería darle una idea).

// 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;
 }
Respuesta: 2

La solución fue crear una clase PercentileExcel que es casi una copia del percentil del método commons, excepto por un pequeño cambio sobre cómo calcular la posición:

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

Luego debe agregar esta línea al código para usar la nueva clase para percentil:

setPercentileImpl(PercentileExcel);
Respuesta: 3

No existe una definición única de un percentil calculado a partir de un conjunto de datos. Vea la página de Wikipedia para las definiciones más comunes en uso.

Respuesta: 4

La clase org.apache.commons.math3.stat.descriptive.rank.Percentileya admite la interpolación de estilo Excel, solo necesita habilitarla con 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()));
    }
}
Respuesta: 5

Estoy tratando de usar java.time.LocalDate en mi aplicación de Android, sin embargo, si trato de importarlo, cualquier clase de java.time da un error de símbolo no puede resolver en Android studio 1.1 La única razón por la que ...

Utilizo las pruebas JUnit y AssertJ para mi aplicación Swing escrita en Java 8. Me gustaría probar si el valor del control deslizante cambia cuando se hace clic en un botón, pero no encontré ninguna forma de obtener un valor actual de un ...

Desarrollé y construí mi aplicación Java usando Maven. Necesito admitir Java 1.6, por lo que uso las siguientes propiedades: <maven.compiler.target> 1.6 </maven.compiler.target> <maven.compiler ...

TreeSet elimina diferentes elementos con el mismo valor de Comprator. No quiero que se elimine. ¿Hay alguna forma de controlar esto? ¿O usar otra clase de contenedor? Agregado: OK. Parece que no puedo usar Set. YO ...