22. Detección de anomalías no supervisada
¿Cómo encontrar condiciones raras sin depender de etiquetas?
Detección de anomalías no supervisada
Buscamos observaciones que se alejan del comportamiento normal usando distancia e Isolation Forest.
1. Pregunta de planta
En no supervisado, detección de anomalías busca condiciones raras sin depender necesariamente de una etiqueta de evento.
Idea central: si una hora de planta se aleja mucho de la nube normal de datos, merece revisión aunque no tenga etiqueta de falla.
Normal = zona densa de datos
Anomalía = punto aislado o condición poco frecuente
2. Matemática simple
Un enfoque simple es medir distancia frente a la operación promedio.
distancia = || x_actual - x_normal ||
Modelos no supervisados como Isolation Forest buscan observaciones fáciles de aislar: puntos raros.
3. Aplicación en flotación
| Tipo de anomalía | Ejemplo | Acción |
|---|---|---|
| Proceso | Nivel y espumante muy altos. | Revisar espuma y control. |
| Sensor | Señal plana o salto brusco. | Validar instrumentación. |
| Metalúrgica | Recuperación baja sin explicación evidente. | Revisar mineral, laboratorio y reactivos. |
| Riesgo | Score alto aunque aún no hay evento. | Vigilar tendencia. |
4. Excel: anomalía por distancia
Estandarizar variables
z_aire=(I2-PROMEDIO(I:I))/DESVEST.M(I:I)
z_nivel=(J2-PROMEDIO(J:J))/DESVEST.M(J:J)
z_esp=(L2-PROMEDIO(L:L))/DESVEST.M(L:L)
Distancia
=RAIZ(z_aire^2+z_nivel^2+z_esp^2+z_score^2)
Bandera
=SI(distancia>PERCENTIL.INC(rango_distancia,0.95),"Anomalía","Normal")
5. Python: Isolation Forest
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import IsolationForest
archivo = "flotacion_cobre.xlsx"
df = pd.read_excel(archivo)
features = [
"recuperacion_cu", "flujo_aire", "nivel_celda", "ph",
"dosificacion_espumante", "p80", "densidad_pulpa", "score_riesgo"
]
X = df[features]
X_scaled = StandardScaler().fit_transform(X)
modelo = IsolationForest(contamination=0.10, random_state=42)
df["anomalia_iforest"] = modelo.fit_predict(X_scaled)
# IsolationForest devuelve -1 para anomalía y 1 para normal
df["anomalia"] = (df["anomalia_iforest"] == -1).astype(int)
resumen = df.groupby("anomalia")[["recuperacion_cu", "score_riesgo", "evento_sobre_espumacion"]].mean()
print(resumen)6. Diferencia frente a anomalías supervisadas
| Supervisado | No supervisado |
|---|---|
| Aprende con etiquetas de evento. | Busca rarezas sin etiqueta obligatoria. |
| Bueno si hay historial confiable. | Útil para explorar condiciones nuevas. |
| Predice una clase conocida. | Marca puntos que se alejan del patrón. |
Advertencia: anomalía no significa causa confirmada. Significa: revisar.
Mensaje final: la detección no supervisada de anomalías ayuda a descubrir condiciones raras incluso cuando todavía no tenemos una etiqueta clara del problema.
