Cuando tu clasificador parpadea: histéresis para señales que oscilan
Tienes una señal que a cada observación te dice en qué estado estás: un monitor de salud que dice OK o CAÍDO , un detector de conectividad, un clasificador de modo. Y cerca del umbral oscila : OK, CAÍDO, OK, CAÍDO, OK . Cada cambio dispara algo —una alerta, un failover, entrar o salir de una posición— y de repente tu sistema está temblando por ruido, no por una transición real. Es el mismo problema que resuelve el termostato de tu casa desde hace un siglo, y la solución tiene nombre: histéresis . No cambies de estado hasta que el nuevo se haya sostenido. La regla, en una frase Un estado nuevo solo se confirma tras repetirse N observaciones consecutivas. Si el candidato cambia o revierte antes de llegar a N , la cuenta se reinicia. El estado vigente se mantiene estable; los parpadeos se ignoran. Lo empaqueté como librería — hysteresis-state , Python puro, sin dependencias— porque lo reescribía una y otra vez: from hysteresis_state import HysteresisState estado = HysteresisState ( " OK " , confirmations = 3 ) for lectura in stream : # "OK" / "CAIDO" actual = estado . update ( lectura ) # solo cambia tras 3 lecturas seguidas if estado . changed : # ¿esta lectura provocó la transición? alertar ( actual ) Aliméntalo con OK, CAÍDO, OK, CAÍDO, OK y no pasa nada: ningún candidato se sostuvo. Hacen falta tres CAÍDO seguidos para que el cambio se confirme. El detalle que casi siempre falta: histéresis asimétrica Un umbral único tiene un problema sutil. Si exiges 3 confirmaciones para entrar en fallo, también tardas 3 en salir — y a veces quieres justo lo contrario: caer rápido a lo seguro, volver despacio a lo arriesgado . Es el comportamiento de un disyuntor eléctrico: salta a la primera, se rearma con cautela. Se resuelve dejando que el umbral dependa de la transición: # 1 confirmación para caer a "CAIDO", 5 para volver a "OK" conf = lambda desde , hacia : 1 if hacia == " CAIDO " else 5 estado = HysteresisState ( " OK " , confirmations = conf ) estado . update ( " CAIDO " )