Cuando tu clasificador parpadea: histéresis para señales que oscilan

작성자

카테고리:

← 피드로
DEV Community · Juan Carlos Isaza · 2026-08-09 개발(SW)

Juan Carlos Isaza

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)

Enter fullscreen mode Exit fullscreen mode

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")   # cae al instante
# ...ahora hacen falta 5 "OK" seguidos para volver

Enter fullscreen mode Exit fullscreen mode

Por qué no basta con “promediar”

La tentación es suavizar con una media móvil y umbralizar. Funciona para señales numéricas, pero se rompe con estados discretos (no promedias OK y CAÍDO), introduce retardo en todas las transiciones por igual, y no te da la asimetría de arriba. La histéresis por confirmación es la herramienta correcta cuando lo que oscila es una etiqueta, no un número.

De dónde salió

Esto nació dentro de un bot de trading. Su cerebro de régimen clasificaba el mercado en tendencia / rango / caos, y cerca de los umbrales parpadeaba: cada parpadeo congelaba o reactivaba la operativa, que es exactamente lo que no quieres que pase por ruido. La histéresis lo calmó. Pero el mecanismo no sabe nada de mercados —es anti-flapping para cualquier señal discreta—, así que lo liberé.

pip install hysteresis-state

Enter fullscreen mode Exit fullscreen mode

Código y tests (con los casos límite del conteo y la asimetría, verificados por mutación): github.com/isazajuancarlos/hysteresis-state.

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다