Algoritmo para monitorear dinámicamente cuantiles

24

Quiero estimar el cuantil de algunos datos. Los datos son tan grandes que no pueden almacenarse en la memoria. Y los datos no son estáticos, siguen llegando nuevos datos. ¿Alguien conoce algún algoritmo para monitorear los cuantiles de los datos observados hasta ahora con memoria y cómputo muy limitados? Encuentro útil el algoritmo P2 , pero no funciona muy bien para mis datos, que están distribuidos de forma extremadamente pesada.

sinoTrinity
fuente
Para algunas ideas (en el contexto de la estimación de medianas) vea el hilo en stats.stackexchange.com/q/346/919 .
whuber
3
Esta pregunta se crossposted en math.SE.
cardenal

Respuestas:

16

El algoritmo P2 es un buen hallazgo. Funciona haciendo varias estimaciones del cuantil, actualizándolas periódicamente y usando interpolación cuadrática (no lineal, no cúbica) para estimar el cuantil. Los autores afirman que la interpolación cuadrática funciona mejor en las colas que la interpolación lineal y que la cúbica se volvería demasiado exigente y difícil.

No indica exactamente cómo falla este enfoque para sus datos de "cola pesada", pero es fácil de adivinar: las estimaciones de cuantiles extremos para distribuciones de cola pesada serán inestables hasta que se recopile una gran cantidad de datos. Pero esto va a ser un problema (en menor medida) incluso si tuviera que almacenar todos los datos, ¡así que no espere milagros!

En cualquier caso, ¿por qué no establecer marcadores auxiliares, llamémoslos y x 6, dentro de los cuales está muy seguro de que el cuantil se ubicará y almacenará todos los datos que se encuentran entre x 0 y x 6 ? Cuando se llene el búfer, deberá actualizar estos marcadores, manteniendo siempre x 0x 6 . Se puede idear un algoritmo simple para hacer esto a partir de una combinación de (a) la estimación actual P2 del cuantil y (b) los recuentos almacenados del número de datos menor que x 0 y el número de datos mayor que x 6x0x6x0x6x0x6x0x6. De esta manera, puede, con gran certeza, estimar el cuantil tan bien como si tuviera todo el conjunto de datos siempre disponible, pero solo necesita un búfer relativamente pequeño.

Específicamente, propongo una estructura de datos para mantener información parcial sobre una secuencia de n valores de datos x 1 , x 2 , ... , x n . Aquí, y es una lista vinculada(k,y,n)nx1,x2,,xny

y=(x[k+1](n)x[k+2](n)x[k+m](n)).

En esta notación denota el i ésimo más pequeño de los n x valores leído hasta ahora. m es una constante, el tamaño del búfer y .x[i](n)ithn xmy

El algoritmo comienza rellenando con los primeros m valores de datos encontrados y colocándolos en orden, de menor a mayor. Sea q el cuantil a estimar; por ejemplo, q = 0.99. Al leer x n + 1 hay tres acciones posibles:ymqqxn+1

  • Si , incremente k .xn+1<x[k+1](n)k

  • Si , no haga nada.xn+1>x[k+m](n)

  • De lo contrario, inserte en y .xn+1y

En cualquier caso, incremente .n

El procedimiento de inserción coloca en y en orden ordenado y luego elimina uno de los valores extremos en y :xn+1yy

  • Si , entonces elimine x ( n ) [ k + 1 ] de y e incremente k ;k+m/2<nqx[k+1](n)yk

  • De lo contrario, elimine de y .x[k+m](n)y

Siempre que sea ​​suficientemente grande, este procedimiento incluirá el verdadero cuantil de la distribución con alta probabilidad. En cualquier etapa n se puede estimar de la manera habitual en términos de x ( n ) [ q n] y x ( n ) [ q n] , que probablemente se encuentre en y . (Creo que m solo tiene que escalar como la raíz cuadrada de la cantidad máxima de datos ( Nmnx[qn](n)x[qn](n)ymN), Pero no he llevado a cabo un análisis riguroso para demostrar que.) En cualquier caso, el algoritmo detectará si se ha tenido éxito (mediante la comparación de y ( k + m ) / n a q ).k/n(k+m)/nq

Prueba con hasta 100,000 valores, usando yq=.5(el caso más difícil) indica que este algoritmo tiene una tasa de éxito del 99.5% para obtener el valor correcto de x ( n ) [ q n] . Para una secuencia deN=10 12 valores, eso requeriría un búfer de solo dos millones (pero tres o cuatro millones sería una mejor opción). El uso de una lista ordenada doblemente vinculada para el búfer requiereO(log(m=2Nq=.5x[qn](n)N=1012=O(log(N))esfuerzo al identificar y eliminar el máximo o mínimo sonoperacionesO(1). La inserción relativamente costosa generalmente debe hacerse soloO(O(log(N))O(log(N))O(1)veces. Por lo tanto, los costos computacionales de este algoritmo sonO(N+O(N)en el tiempo yO(O(N+Nlog(N))=O(N)en almacenamiento.O(N)

whuber
fuente
Este es un trabajo extendido del algoritmo P2. [enlace] sim.sagepub.com/content/49/4/159.abstract . El almacenamiento aún es demasiado para mi aplicación, que se ejecuta en sensores pequeños con un total de 10K RAM. Puedo consumir unos cientos de bytes como máximo solo para la estimación cuantil.
sinoTrinity
@whuber En realidad, implemento el P2 extendido y lo pruebo con muestras generadas de varias distribuciones, como uniforme y exponencial, donde funciona muy bien. Pero cuando lo aplico contra los datos de mi aplicación, cuya distribución es desconocida, a veces no converge y produce un error relativo (abs (estimación - real) / real) de hasta el 300%.
sinoTrinity
2
@sino La calidad del algoritmo en comparación con el uso de todos los datos no debería depender del peso de las colas. Una forma más justa de medir el error es esta: dejemos que sea ​​el cdf empírico. Para una estimación q de la q percentil, ¿cuál es la diferencia entre F ( q ) y F ( q ) ? Si está en el orden de 1 / n, lo estás haciendo muy bien. En otras palabras, ¿qué percentil devuelve el algoritmo P2 para sus datos? Fq^qF(q^)F(q)1/n
whuber
Tienes razón. Acabo de medir la F (qˆ) y la F (q) para el caso que mencioné con un error relativo de hasta el 300%. Para q de 0.7, qˆ es casi 0.7, resultando en un error insignificante. Sin embargo, para q de 0.9, qˆ parece estar alrededor de 0.95. Supongo que es por eso que tengo un gran error de hasta 300%. ¿Alguna idea de por qué es 0.95, no 0.9? Por cierto, ¿puedo publicar una figura aquí y cómo puedo publicar una fórmula matemática como lo hiciste?
sinoTrinity
2
@whuber Estoy bastante seguro de que mi implementación se ajusta a P2 extendido. 0.9 todavía va a 0.95 o incluso más grande cuando estimé simultáneamente 0.8, 0.85, 0.9, 0.95 cuantiles. Sin embargo, 0.9 se acerca mucho a 0.9 si se siguen al mismo tiempo los cuantiles 0.8, 0.85, 0.9, 0.95 y 1.0 .
sinoTrinity
5

Creo que la sugerencia de Whuber es genial y lo intentaría primero. Sin embargo, si encuentra que realmente no puede acomodar el almacenamiento o no funciona por alguna otra razón, aquí hay una idea para una generalización diferente de P2. No es tan detallado como lo sugiere Whuber, más como una idea de investigación en lugar de una solución.O(N)

Instead of tracking the quantiles at 0, p/2, p, (1+p)/2, and 1, as the original P2 algorithm suggests, you could simply keep track of more quantiles (but still a constant number). It looks like the algorithm allows for that in a very straightforward manner; all you need to do is compute the correct "bucket" for incoming points, and the right way to update the quantiles (quadratically using adjacent numbers).

250p/12p11/12pp+(1p)/12p+11(1p)/1210pp122 p/2(1+cos(2i1)π22)p+(1p)/2(1+cos(2i1)π22). If p is close to 0 or 1, you could try putting fewer points on the side where there is less probability mass and more on the other side.

If you decide to pursue this, I (and possibly others on this site) would be interested in knowing if it works...

Erik P.
fuente
+1 I think this is a great idea given the OP's constraints. All one can hope for is an approximation, so the trick is to pick bins that have a high likelihood of being narrow and containing the desired quantile.
whuber
3

Press et al., Numerical Recipes 8.5.2 "Single-pass estimation of arbitrary quantiles" p. 435, give a c++ class IQAgent which updates a piecewise-linear approximate cdf.

denis
fuente
books.google.com/… for a version that doesn't require Flash.
ZachB
2

This can be adapted from algorithms that determine the median of a dataset online. For more information, see this stackoverflow post - /programming/1387497/find-median-value-from-a-growing-set

benhamner
fuente
The computational resources required of the algorithm you link to are unnecessarily large and do not meet the requirements of this question.
whuber
2

I'd look at quantile regression. You can use it to determine a parametric estimate of whichever quantiles you want to look at. It make no assumption regarding normality, so it handles heteroskedasticity pretty well and can be used one a rolling window basis. It's basically an L1-Norm penalized regression, so it's not too numerically intensive and there's a pretty full featured R, SAS, and SPSS packages plus a few matlab implementations out there. Here's the main and the R package wikis for more info.

Edited:

Check out the math stack exchange crosslink: Someone sited a couple of papers that essentially lay out the very simple idea of just using a rolling window of order statistics to estimate quantiles. Literally all you have to do is sort the values from smallest to largest, select which quantile you want, and select the highest value within that quantile. You can obviously give more weight to the most recent observations if you believe they are more representative of actual current conditions. This will probably give rough estimates, but it's fairly simple to do and you don't have to go through the motions of quantitative heavy lifting. Just a thought.

Marc
fuente
1

It is possible to estimate (and track) quantiles on an on-line basis (the same applies to the parameters of a quantile regression). In essence, this boils down to stochastic gradient descent on the check-loss function which defines quantile-regression (quantiles being represented by a model containing only an intercept), e.g. updating the unknown parameters as and when observations arrive.

See the Bell Labs paper "Incremental Quantile Estimation for Massive Tracking" ( ftp://ftp.cse.buffalo.edu/users/azhang/disc/disc01/cd1/out/papers/kdd/p516-chen.pdf)

Ludo
fuente