Saturday, December 24, 2016

Media Móvil De Filtro De Código 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 golpes en 2 segundos, estaríamos estimando 1200 por 2 minutos, lo cual con toda probabilidad es muy lejos. Tengo esencialmente una matriz de valores como este: La matriz anterior es simplificada, estoy coleccionando 1 Valor por milisegundo en mi código real y necesito procesar la salida en un algoritmo que escribí para encontrar el pico más cercano antes de un punto en el tiempo. Mi lógica falla porque en mi ejemplo anterior, 0.36 es el pico real, pero mi algoritmo miraría hacia atrás y vería el último número 0.25 como el pico, pues hay una disminución a 0.24 antes de él. El objetivo es tomar estos valores y aplicarles un algoritmo que los suavice un poco para que tenga valores más lineales. (Es decir: la identificación como mis resultados para ser curvy, no jaggedy) se me ha dicho que aplique un filtro de media móvil exponencial a mis valores. Cómo puedo hacer esto? Es realmente difícil para mí para leer las ecuaciones matemáticas, trato mucho mejor con el código. Cómo proceso los valores en mi matriz, aplicando un cálculo de promedio móvil exponencial para igualarlos? Preguntó Feb 8 12 at 20:27 Para calcular una media móvil exponencial. Usted necesita mantener un poco de estado alrededor y usted necesita un parámetro de ajuste. Esto requiere una pequeña clase (asumiendo que está usando Java 5 o posterior): Instantiate con el parámetro de decadencia que desea (puede tomar la afinación debe estar entre 0 y 1) y luego use average () para filtrar. Al leer una página sobre alguna recurrencia matemática, todo lo que realmente necesita saber al convertirlo en código es que a los matemáticos les gusta escribir índices en matrices y secuencias con subíndices. Sin embargo, la EMA es bastante simple, ya que sólo es necesario recordar un valor antiguo sin arrays de estado complicado requerido. Respondió 8 Feb a las 20:42 TKKocheran: Bastante. No es bueno cuando las cosas pueden ser simples (si comienza con una nueva secuencia, obtenga un nuevo averager). Observe que los primeros términos de la secuencia promedio saltarán alrededor de un bit debido a efectos de límite, pero obtendrá aquellos con otras medias móviles también. Sin embargo, una buena ventaja es que usted puede envolver la lógica del promedio móvil en el averager y experimentar sin molestar el resto de su programa demasiado. Ndash Donal Fellows Feb 9 12 en 0:06 Estoy teniendo un rato difícil entender sus preguntas, pero intentaré contestar de todos modos. 1) Si su algoritmo encontró 0.25 en lugar de 0.36, entonces es incorrecto. Está mal porque asume un aumento o una disminución monotónica (que siempre sube o baja siempre). A menos que usted promedio TODOS sus datos, sus puntos de datos --- como usted los presenta --- son no lineales. Si realmente desea encontrar el valor máximo entre dos puntos en el tiempo, corte su matriz de tmin a tmax y busque el máximo de ese subarray. 2) Ahora, el concepto de promedios móviles es muy simple: imagina que tengo la siguiente lista: 1.4, 1.5, 1.4, 1.5, 1.5. Puedo suavizarlo tomando el promedio de dos números: 1.45, 1.45, 1.45, 1.5. Observe que el primer número es el promedio de 1,5 y 1,4 (segundo y primeros números), la segunda (nueva lista) es el promedio de 1,4 y 1,5 (tercera y segunda lista antigua) la tercera (nueva lista) el promedio de 1,5 y 1,4 (Cuarto y tercero), y así sucesivamente. Podría haberlo hecho el período tres o cuatro, o n. Observe cómo los datos son mucho más suaves. Una buena manera de ver los promedios móviles en el trabajo es ir a Google Finance, seleccionar una acción (probar Tesla Motors bastante volátil (TSLA)) y hacer clic en technicals en la parte inferior de la tabla. Seleccione Promedio móvil con un período determinado y Promedio móvil exponencial para comparar sus diferencias. La media móvil exponencial es sólo otra elaboración de esto, pero los pesos de los datos más antiguos menos de los nuevos datos de esta es una manera de sesgar el alisamiento hacia la parte posterior. Por favor, lea la entrada de Wikipedia. Por lo tanto, esto es más un comentario que una respuesta, pero el pequeño cuadro de comentarios era sólo a pequeño. Buena suerte. Si usted está teniendo apuro con la matemáticas, usted podría ir con una media móvil simple en vez de exponencial. Así que la salida que obtendrías serían los últimos x términos divididos por x. Pseudocódigo no comprobado: Tenga en cuenta que tendrá que manejar las partes inicial y final de los datos, ya que claramente no puede medirse los últimos 5 términos cuando está en su segundo punto de datos. Además, hay maneras más eficientes de calcular este promedio móvil (suma suma - más reciente más reciente), pero esto es para obtener el concepto de lo que está sucediendo a través de. Respondió el 8 de febrero a las 20:41 Código fuente avanzado. Com. Haga click aquí para descargar. Un filtro de media móvil promedia un número de muestras de entrada y produce una única muestra de salida. Esta acción de promedio elimina los componentes de alta frecuencia presentes en la señal. Los filtros de media móvil se utilizan normalmente como filtros de paso bajo. En el algoritmo de filtrado recursivo, las muestras de salida anteriores también se toman para promediar. Esta es la razón por la que su respuesta al impulso se extiende hasta el infinito. Hemos desarrollado un enfoque computacional bajo para el reconocimiento del iris basado en el filtro de media móvil 1D. El promedio simple se utiliza para reducir los efectos del ruido y una mejora significativa en la eficiencia computacional se puede lograr si realizamos el cálculo de la media de una manera recursiva. Este código utiliza una versión optimizada de las rutinas de Libor Maseks para la segmentación del iris disponible aquí. Libor Masek y Peter Kovesi. MATLAB Código fuente para un sistema de identificación biométrico basado en patrones de iris. La Escuela de Ciencias de la Computación y la Ingeniería de Software, la Universidad de Western Australia, 2003. Términos de Index: Matlab, fuente, código, iris, reconocimiento, movimiento, promedio, filtro, bajo, computacional.

No comments:

Post a Comment