Main Content

Esta página es para la versión anterior. La página correspondiente en inglés ha sido eliminada en la versión actual.

Detección de brotes y cambios significativos en las señales

Este ejemplo muestra cómo determinar los cambios o las rupturas en las señales vía las sumas acumulativas y la detección del punto de cambio.

Detectar brotes a través de sumas acumuladas

Hay muchas aplicaciones prácticas en las que está supervisando los datos y desea recibir alertas cuando el proceso subyacente ha cambiado lo más rápido posible. Una técnica muy popular para lograr esto es mediante un gráfico de control de suma acumulada (CUSUM).

Para ilustrar cómo funciona el CUSUM, examine en primer lugar el total de los casos notificados del brote de ébola en el africa occidental de 2014.

Fuente:Centros para el Control y la Prevención de Enfermedades

load WestAfricanEbolaOutbreak2014 plot(WHOreportdate, [TotalCasesGuinea TotalCasesLiberia TotalCasesSierraLeone],'.-') legend('Guinea','Liberia','Sierra Leone'); title('Total suspected, probable and confirmed cases of Ebola virus disease');

Si nos fijamos en la vanguardia del primer brote en Guinea, se puede ver que los primeros cien casos se notificaron alrededor del 25 de marzo de 2014, y aumentar significativamente después de esa fecha. Lo que es interesante notar es que, si bien Liberia también tuvo algunos casos sospechosos en marzo, el número de casos se mantuvo relativamente en control hasta unos treinta días después.

Para hacerse una idea de la tasa de ingresos de los nuevos pacientes, trazar los cambios relativos en el día a día en el número total de casos, comenzando a partir del inicio del 25 de marzo de 2015.

daysSinceOutbreak = datetime(2014, 3, 24+(0:400)); cases = interp1(WHOreportdate, TotalCasesLiberia, daysSinceOutbreak); dayOverDayCases = diff(cases);  plot(dayOverDayCases) title('Rate of new cases (per diem) in Liberia since March 25, 2014'); ylabel('Change in number of reported cases per diem'); xlabel('Number of days since outbreak began');

Si hace zoom en los primeros cien días de datos, puede ver que, si bien hubo una afluencia inicial de casos, muchos de ellos se descartaron después del día 30, donde la tasa de cambios cayó por debajo de cero temporalmente. También se ve una tendencia significativa al alza entre los días 95 y 100, donde se alcanzó una tasa de siete nuevos casos por día.

xlim([1 101])

Realizar una prueba CUSUM en los datos de entrada puede ser una forma rápida de determinar cuándo se produce un brote. CUSUM realiza un seguimiento de dos sumas acumuladas: una suma superior que detecta cuándo la media local se desplaza hacia arriba, y una suma más baja que detecta cuando la media cambia hacia abajo. La técnica de integración proporciona a CUSUM la capacidad de ignorar un pico grande (transitorio) en la velocidad entrante, pero todavía tiene sensibilidad a pequeños cambios más estables en la velocidad.

Llamar a CUSUM con argumentos predeterminados inspeccionará los datos de las primeras veinticinco muestras y alarmacuando cuando encuentre un cambio en la media más de cinco desviaciones estándar de dentro de los datos iniciales.

cusum(dayOverDayCases(1:101)) legend('Upper sum','Lower sum')

Tenga en cuenta que CUSUM detectó los casos falsos notificados en el día 30 (en el día 33) y recogió el inicio inicial del brote a partir del día 80 (en el día 90). Si compara estos resultados cuidadosamente con la trama anterior, puede ver que CUSUM fue capaz de ignorar el repunte espurio en el día 29, pero aún así activar una alarma cinco días antes de la gran tendencia al alza a partir del día 95.

Si ajusta CUSUM para que tenga una media objetivo de cero casos/día con un objetivo de más o menos tres casos/día, puede ignorar la falsa alarma en el día 30 y recoger el brote en el día 92:

climit = 5; mshift = 1; tmean = 0; tdev = 3; cusum(dayOverDayCases(1:100),climit,mshift,tmean,tdev)

Encontrar un cambio significativo en la varianza

Otro método para detectar cambios bruscos en las estadísticas es a través de la detección de puntos de cambio, que divide una señal en segmentos adyacentes donde una estadística (por ejemplo, media, varianza, pendiente, etc.) es constante dentro de cada segmento.

El siguiente ejemplo analiza el nivel mínimo anual de agua del río Nilo para los años 622 a 1281 d.C. medido en el medidor Dea cerca de El Cairo.

load nilometer years = 622:1284; plot(years,nileriverminima) title('Yearly Minimum level of Nile River') xlabel('Year') ylabel('Level (m)')

La construcción comenzó en un dispositivo de medición más nuevo y preciso alrededor del 715 d.C. No se sabe mucho antes de este tiempo, pero en un examen posterior, se puede ver que hay considerablemente menos variabilidad después de alrededor de 722. Para encontrar el período de tiempo en el que el nuevo dispositivo entró en funcionamiento, puede buscar el mejor cambio en el nivel de agua de raíz media cuadrada después de realizar la diferenciación en el elemento para eliminar cualquier tendencia que varía lentamente.

i = findchangepts(diff(nileriverminima),'Statistic','rms');  ax = gca; xp = [years(i) ax.XLim([2 2]) years(i)]; yp = ax.YLim([1 1 2 2]); patch(datenum(xp),yp,[.5 .5 .5],'facealpha',0.1);

Si bien la diferenciación en cuanto a la muestra es un método sencillo para eliminar tendencias, existen otros métodos más sofisticados para examinar la varianza en escalas más grandes. Para obtener un ejemplo de cómo realizar la detección de puntos de cambio a través de wavelets mediante este conjunto de datos, consulte .Wavelet Changepoint Detection (Wavelet Toolbox)

Detección de múltiples cambios en una señal de entrada

El siguiente ejemplo se refiere a una simulación de 45 segundos de un bloque de transmisión CR-CR de 4 velocidades, muestreado a intervalos de 1 ms. Los datos de simulación de las RPM y el par del motor del coche se muestran a continuación.

load simcarsig  subplot(2,1,2); plot(carTorqueNM); xlabel('Samples'); ylabel('Torque (N m)'); title('Torque');  subplot(2,1,1); plot(carEngineRPM); xlabel('Samples'); ylabel('Speed (RPM)'); title('Engine Speed');

Aquí el coche acelera, cambia de marcha tres veces, cambia a neutro, y luego aplica el freno.

Dado que la velocidad del motor se puede modelar naturalmente como una serie de segmentos lineales, puede utilizar para encontrar las muestras donde el coche cambia de marcha.findchangepts

figure findchangepts(carEngineRPM,'Statistic','linear','MaxNumChanges',4) xlabel('Samples'); ylabel('Engine speed (RPM)');

Aquí puede ver cuatro cambios (entre cinco segmentos lineales) y que se produjeron alrededor de la marca de muestra 10.000, 20.000, 30.000 y 40.000. Zoom en la parte inactiva de la forma de onda:

xlim([18000 22000])

Tenga en cuenta que el ajuste en línea recta realiza un seguimiento estrecho de la forma de onda de entrada, sin embargo, se puede mejorar.

Observación de los cambios de un evento multietapa compartido entre señales

Para ver la mejora, aumente el número de puntos de cambio a 20, y observe los cambios dentro de las proximidades del cambio de marchas en el número de muestra 19000

findchangepts(carEngineRPM,'Statistic','linear','MaxNumChanges',20) xlim([18000 22000])

Observe que la velocidad del motor comenzó disminuyendo en la muestra 19035 y tomó 510 muestras antes de que se estableciera en la muestra 19550. Puesto que el intervalo de muestreo es de 1 ms, se trata de un retardo de 0,51 s y es una cantidad típica de tiempo después de cambiar de marcha.

Ahora mire los puntos de cambio del par motor dentro de la misma región:

findchangepts(carTorqueNM,'Statistic','Linear','MaxNumChanges',20) xlim([19000 20000])

Observe que el par motor se entregó completamente al eje en la muestra 19605, 55 milisegundos después de que la velocidad del motor terminó de sedimentar. Este tiempo está relacionado con el retraso entre la carrera de admisión del motor y la producción de par.

Para encontrar cuando el embrague se enganchó se puede acercar aún más en la señal.

xlim([19000 19050])

El embrague fue deprimido en la muestra 19011 y tomó alrededor de 30 muestras (milisegundos) para desengancharse por completo.