Isolation Forest: el algoritmo estrella para detección de anomalías

keepler.io
5 min readJun 27, 2019
Fuente: unsplash | rishi deep

En el mundo de los datos, y sobre todo en aquellos entornos en los que queremos sacarle valor a los mismos, suele aparecer el término “anomalía”. Una anomalía no es más que un dato dentro de nuestro conjunto de datos que no sigue el comportamiento esperado. Hoy venimos a hablar de esto.

La detección de anomalías tiene muchísimos casos de uso. Desde ciberseguridad (intrusión) hasta medicina (procesamiento de imagen), pasando por mantenimiento industrial, detección de fraude e incluso Internet of Things (monitorización). Un buen sistema de detección de anomalías puede hacer decrecer costes provenientes de áreas del negocio de muchas industrias, pero muchas veces nos encontramos con preguntas del tipo:

¿Qué algoritmo elijo para detectar anomalías?
¿Cómo disponibilizo mi modelo al resto de unidades de negocio?

Hoy venimos a hablar de una de las soluciones más potentes de los últimos años en cuanto a precisión de detección de anomalías se refiere. No sólo potente, sino eficaz y de fácil implementación, el Isolation Forest es uno de los últimos algoritmos estrella de detección de anomalías más aceptados dentro de la comunidad Data Science.

¿Será capaz el algoritmo de realizar el trabajo de numerosas personas de estar monitorizando un flujo de procesos y/o datos con el fin de encontrar registros extraños o atípicos? Claramente, ¡la respuesta es sí! Lo cierto es que, siempre y cuando se tenga un mínimo de calidad en los datos, estamos ante un clásico caso de robot-reemplaza-a-humano. Comencemos.

UN BOSQUE DE SOLEDADES

Para entender cómo funciona el Isolation Forest, tenemos que ver cómo un árbol de decisión es capaz de llegar a la conclusión de que un punto es anómalo. Los pasos que realiza un árbol consisten en:

  1. Escoger un registro dentro de mi conjunto de datos y sus variables.
  2. Escoger un valor aleatorio dentro del mínimo y el máximo de cada variable.
  3. Crear un nodo o ramificación: si el valor del registro al que estamos mirando es mayor o menor que el valor aleatorio anterior, repetiremos el ejercicio de evaluar nuestro punto con el mínimo y máximo de nuestro intervalo, esta vez más acotado, siendo el nuevo máximo o el mínimo el punto de corte de la rama creada.
  4. Ejecutar el tercer paso hasta que no podamos ramificar más y el punto a evaluar esté aislado.

Así, cuantas menos ramas haya necesitado el árbol para aislar al punto, más anómalo será. Y si hacemos, por ejemplo, 100 árboles y calculamos la media del número de ramas por cada valor, tendremos una aproximación bastante robusta del grado de anomalía de cada observación o registro de nuestro conjunto de datos… Así es, sin entrar en términos ni formulaciones matemáticas, cómo funciona el Isolation Forest. Una gran ventaja de este algoritmo en comparación a otros métodos es que no utiliza medidas de distancia, similitud o densidad del conjunto de datos, que suele ser computacionalmente muy costoso. El Isolation Forest tiene una complejidad que crece linealmente gracias a las bondades del sub-muestreo: computa árboles por subpartes del conjunto de datos. Así, tiene la capacidad de escalar en datasets grandes y con muchas variables irrelevantes.

Por otro lado, podemos usarlo de modo supervisado como de modo no supervisado. En este último caso tendríamos que verificar con nuestro Product Owner o con algún responsable de negocio, el tanto por ciento de observaciones en nuestros datos aproximado que se consideran anomalía.

PONIENDO EL BOSQUE A FUNCIONAR

Muchas veces, los dolores de cabeza más severos de los Data Scientist no vienen de fórmulas extensas o de selecciones del mejor hiperparámetro, sino de cómo podemos productivizar un modelo. Vamos al lío.

Con la correcta combinación de frameworks de Python como Flask y el fantástico Docker, podemos hacer maravillas. En este caso vamos a crear una simple aplicación, un API a la cual vamos a preguntarle si los datos que le estamos enviando son anómalos o no. Para ello, nos vamos a valer de un famoso dataset de datos de patologías cardiológicas de este repositorio y del genial framework PyOD.

El proyecto está creado en este enlace. En primer lugar, debemos tener principalmente dos scripts dentro de nuestro programa: uno que se encargue del entrenamiento y otro que se encargue de la predicción y del servicio API. En este caso, usaremos Flask como librería, que permite crear aplicaciones sencillas que disponibilizan endpoints al mundo. En este caso, estaremos creando esta aplicación en nuestro local, pero como decíamos, nos podemos valer de Docker y un despliegue sencillo en alguna de las nubes públicas (Amazon Web Services, Microsoft Azure y Google Cloud) para poder abrir de verdad nuestra aplicación a la unidad de negocio correspondiente, o simplemente al resto del mundo.

Por otro lado, creamos una estructura de carpetas que nos permita almacenar los datos. Una vez más, sirve de estructura plantilla, pero lo ideal es alojar los datos en una base de datos apropiada. En este caso tendríamos simplemente que crear un fichero de configuración con las cadenas de conexión. Lo mismo sucede con el modelo que entrenemos: convendría almacenarlo en un sistema de ficheros en binario, pero lo alojamos dentro de la estructura de carpetas para poder mostrar la funcionalidad completa de Flask. Sin más dilaciones, el script de train tiene esta forma.

Vemos que tenemos un lugar del cual cogemos los hiperparámetros. Este json puede ser extrapolable al lugar de donde podamos almacenar las cadenas de conexión a nuestras bases de datos, así como también las rutas donde se alojan nuestro modelo y más configuraciones de ejecución del entrenamiento. Vemos que entrenamos el modelo con los datos de test y simplemente lo guardamos. Este modelo será luego el que cargue la aplicación en memoria para poder hacer la inferencia. Puedes verlo aquí.

La clase Scoring Service es la que se encarga de realizar la carga del modelo y de hacer la inferencia. Por otro lado, el resto de funciones indican la naturaleza de los endpoints que hemos creado. Tenemos la función principal que crea el Home de la aplicación, por lo que si ejecutamos el programa, ¡la aplicación ya estará levantada! Si vamos a http://0.0.0.0:5000/ estaremos en la Home de la aplicación. Si seguimos viendo el script, veremos que la función api_predict no es más que un método POST. Recibe datos, invoca la clase Scoring Service y realiza la inferencia, devolviendo la predicción apropiada para los datos recibidos. Sencillo, ¿verdad?

Una vez veamos que nuestra aplicación está ejecutándose, podemos probar la misma ejecutando el siguiente script de test (¡que no test del modelo!).

EL BOSQUE EN LA NUBE

Prácticamente todas las nubes públicas te proveen de servicios similares autoescalables para volumetrías de datos absurdas. Existen muchos ejemplos de implementación de algoritmos similares. En AWS por ejemplo, el servicio Sagemaker autogestionado de Machine Learning, posee una variante del Isolation Forest. También Azure posee un API interesante para detectar anomalías en series temporales. Las posibilidades son infinitas! El cambio a la nube es realmente un cambio de paradigma y es que poseemos toda la capacidad computacional que deseemos, o bien los mínimos para realizar aplicaciones sin servidores que nos proporcionen acceso a nuestras API sin coste.

Autor: Nicolás Forteza, Data Scientist en Keepler.

--

--

keepler.io

Hablamos de #Data #AI #MachineLeargning y #CloudComputing.