Media Móvil En Java


Una implementación simple de media móvil en Java En varias ocasiones he querido calcular métricas simples en mis aplicaciones Java, por ejemplo el número de visitas por hora, o errores a lo largo de un período de tiempo. Mientras que el cálculo de métricas simples no es terriblemente difícil, su solo trabajo extra e Id pasan bastante tiempo en el dominio del problema. Me sorprendió no encontrar soluciones ampliamente aceptadas para métricas en Java. Encontré Metrics, pero parecía un poco complicado y no estaba bien documentado. Lo único que quería era calcular un promedio móvil. Pensé en el problema un poco más y decidí que no era un problema difícil. Heres my solution Esto funciona creando una matriz de tamaño de ventana / actualización de frecuencia, a continuación, un hilo fija el recuento al siguiente índice en la matriz en la frecuencia de actualización. El recuento para el intervalo es simplemente arrayi - arrayi1, que es el recuento más reciente menos el recuento más antiguo. Para un intervalo de 10 minutos, el recuento más antiguo (i1) tiene exactamente 10 minutos. Para agregar una media móvil a nuestro código primero necesitamos un contador, usando AtomicLong. Este contador se debe incrementar en función de los eventos que esté interesado en el cálculo (por ejemplo, solicitudes POST para un servicio REST). Tenemos que proporcionar la implementación con acceso al contador y que se logra a través de la interfaz GetCount. Aquí Ill crear un promedio móvil con una ventana de 5 minutos que se actualiza cada segundo. Y para obtener el promedio actual simplemente llamamos al método getAverage: Un detalle clave de la implementación es cómo se determina el tamaño del array: dividiendo la ventana por la frecuencia de actualización. Así que una ventana grande con una frecuente frecuencia de actualización puede consumir una cantidad significativa de memoria. En este ejemplo, el tamaño de la matriz es razonable 300. Sin embargo, si creamos una media móvil de 24 horas con un intervalo de 1 segundo, el tamaño sería 86400. Una frecuencia de actualización más razonable para un período de 24 horas podría ser cada 5 minutos (tamaño de la matriz de 288 ). Otra consideración de elegir la ventana y la frecuencia de actualización es que la ventana debe ser divisible por la frecuencia. Por ejemplo una ventana de 2 minutos con una frecuencia de actualización de 6 segundos está bien, pero una frecuencia de actualización de 7 segundos no es, ya que no es divisible por 120. Una IllegalArgumentException se lanza si la frecuencia de actualización del módulo de ventana no es cero. Esta implementación requiere un hilo por promedio móvil, que no es muy eficiente. Una mejor solución sería compartir un hilo entre muchos promedios. Actualización. He actualizado el código para compartir un hilo aquí. Por último, theres un problema de estado inicial: no tenemos datos todavía para toda la ventana. Por ejemplo, si tiene una ventana de 5 minutos y sólo 15 segundos de datos. Esta implementación devuelve null hasta que tengamos 5 minutos de datos. Otro enfoque es estimar el promedio. Supongamos que tenemos un recuento de 10 en 30 segundos, entonces podemos estimar el promedio como 40 en 2 minutos. Sin embargo, existe el riesgo de error significativo al extrapolar los datos incompletos. Por ejemplo, si tuviéramos una ráfaga de 20 visitas en 2 segundos, estaremos calculando 1200 por 2 minutos, lo que con toda probabilidad está muy lejos. Método de media móvil de Java Si está buscando una EMA que esté optimizada para la transmisión de datos, Desde un archivo o servicio de cotización, la siguiente clase de ejemplo lo hará bien, en contraposición a los cálculos de fuerza bruta. Este enfoque es particularmente útil si está procesando datos en tiempo real. Los EMAs, un caso especial de promedios móviles ponderados, tienen el beneficio de que la ponderación relativa para cada período sucesivo disminuye con un factor constante f2 / (N1), donde N es el número de periodos sobre los cuales se aplica la EMA. En la siguiente clase de ejemplo se implementa esta naturaleza iterativa de EMA y se minimizan los requerimientos de computación sobre los valores de brute - Métodos de fuerza o métodos de post-procesamiento. Private int numPeriods 0 privado int totalPeriodos 0 privado double runningEMA 0.0 privado doble factor 0.0 público EMA (int numPeriods) this. numPeriods numPeriods factor 2.0 / (numPeriods 1.0) / Restablecer los cálculos para generar EMA para el período dado. / Public void reset (int numPeriods) / Devuelve EMA para el periodo define durante el constructor. Si los períodos procesados ​​son menores que el rango EMA, se devuelve cero. / Public double calcular (doble precio) runningEMA factorprice (1 factor) runningEMA if (totalPeriods lt numPeriods) Desde donde se obtienen los datos de precios y lo que se hace con los resultados de EMA depende de usted. Por ejemplo, si tiene los datos de precio en una matriz y desea calcular una EMA en otra matriz, el siguiente fragmento funcionará: dos precios. (50) // 50 periodo EMA para (int idx0 iltprices. length idx) emaidx ema (pricesidx) Buena suerte, y los mejores deseos para su proyecto . Promedios / Media móvil simple Promedios / Promedio móvil simple Se le anima a que resuelva esta tarea de acuerdo con la descripción de la tarea, utilizando cualquier idioma que conozca. Calculando el promedio móvil simple de una serie de números. Crear una función / clase / instancia con estado que toma un punto y devuelve una rutina que toma un número como argumento y devuelve una media móvil simple de sus argumentos hasta ahora. Un promedio móvil simple es un método para calcular un promedio de una corriente de números haciendo sólo el promedio de los últimos 160 P 160 números de la corriente 160, donde 160 P 160 se conoce como el período. Se puede implementar llamando a una rutina de iniciación con 160 P 160 como su argumento, 160 I (P), 160 que debe devolver una rutina que cuando se llama con miembros individuales sucesivos de un flujo de números, calcula la media de (arriba A), los últimos 160 P 160 de ellos, permite llamar a este 160 SMA (). La palabra 160 estado 160 en la descripción de la tarea se refiere a la necesidad de 160 SMA () 160 para recordar cierta información entre las llamadas a ella: 160 El período 160 P 160 Un contenedor ordenado de al menos los últimos 160 P 160 números de cada uno de Sus llamadas individuales. El estado 160 también significa que las llamadas sucesivas a 160 I (), 160 el inicializador, 160 deben devolver rutinas separadas que no 160 comparten el estado guardado para que puedan ser utilizadas en dos flujos independientes de datos. El pseudo-código para una implementación de 160 SMA 160 es: Esta versión utiliza una cola persistente para contener los valores p más recientes. Cada función devuelta desde init-moving-average tiene su estado en un átomo que contiene un valor de cola. Esta implementación utiliza una lista circular para almacenar los números dentro de la ventana al principio de cada indicador de iteración se refiere a la celda de lista que contiene el valor que acaba de salir de la ventana y que se reemplazará con el valor simplemente añadido. Uso de un cierre En la actualidad, este sma no puede ser nogc porque asigna un cierre en el montón. Algún análisis de escape podría eliminar la asignación de montón. Uso de una edición de estructura Esta versión evita la asignación de montón del cierre manteniendo los datos en el marco de pila de la función principal. La misma salida: Para evitar que las aproximaciones de punto flotante sigan acumulándose y creciendo, el código podría realizar una suma periódica en toda la matriz de cola circular. Esta implementación produce dos objetos (de función) compartiendo estado. Es idiomático en E separar la entrada de la salida (leer de la escritura) en lugar de combinarlos en un objeto. La estructura es la misma que la implementación de la Desviación EstándarE. El programa de elixir a continuación genera una función anónima con un período incrustado p, que se utiliza como el período de la media móvil simple. La función run lee la entrada numérica y la pasa a la función anónima recién creada, y luego inspecciona el resultado a STDOUT. La salida se muestra a continuación, con el promedio, seguido por la entrada agrupada, formando la base de cada promedio móvil. Erlang tiene clausuras, pero variables inmutables. Una solución entonces es utilizar procesos y un mensaje simple que pasa la API basada. Los lenguajes de matriz tienen rutinas para calcular los avarages de deslizamiento para una secuencia dada de ítems. Es menos eficiente realizar bucle como en los siguientes comandos. Pide continuamente una entrada I. Que se añade al final de una lista L1. L1 se puede encontrar pulsando 2ND / 1, y la media se puede encontrar en List / OPS Pulse ON para terminar el programa. Función que devuelve una lista que contiene los datos promediados del argumento suministrado Programa que devuelve un valor simple en cada invocación: list es la lista que se promedia: p es el período: 5 devuelve la lista promedio: Ejemplo 2: Utilizando el programa movinav2 , 5) - Inicializando el cálculo del promedio móvil, y definir el período de 5 movinav2 (3, x): x - nuevos datos en la lista (valor 3), y el resultado se almacenará en la variable x, y se muestra movinav2 (4, : X - nuevos datos (valor 4), y el nuevo resultado se almacenará en la variable x, y se mostrará (43) / 2. Descripción de la función movinavg: variable r - es el resultado (la lista de promedios) que se devolverá variable i - es la variable de índice, y apunta al final de la sub-lista de la lista de promediar. Variable z - una variable auxiliar La función utiliza la variable i para determinar qué valores de la lista serán considerados en el siguiente cálculo promedio. En cada iteración, la variable i apunta al último valor de la lista que se utilizará en el cálculo promedio. Así que sólo tenemos que averiguar cuál será el primer valor en la lista. Por lo general, hay que tener en cuenta los elementos p, por lo que el primer elemento será el indexado por (i-p1). Sin embargo, en las primeras iteraciones, el cálculo será normalmente negativo, por lo que la siguiente ecuación evitará los índices negativos: max (i-p1,1) o, ordenando la ecuación, max (i-p, 0) 1. Pero el número de elementos en las primeras iteraciones también será menor, el valor correcto será (índice final - comenzar índice 1) o, ordenando la ecuación, (i - (max (ip, 0) 1), y luego , (I - max (ip, 0)). La variable z tiene el valor común (max (ip), 0) así que el beginindex será (z1) y los numberofelements serán (iz) mid (list, z1, iz) devolverá la lista de valor que será la suma promedio .) Los sumará sum (.) / (Iz) ri los medirá y almacenará el resultado en el lugar apropiado en la lista de resultados Usando un cierre y creando una función

Comments

Popular Posts