Cálculo de probabilidades de transición usando Dataframe en Julia

Para este artículo he decidido que escribiré en Español. Quisiera hacer un ejercicio sencillo de generar unos datos sintéticos, colocarlos en un Dataframe en Julia, y calcular algunas probabilidades de transición.

Josh Ram

--

Tengo varias semanas usando Julia y hay algunas características que me gustan un poco más comparadas con Python. Julia parece estar agarrando algo de momentum, y aunque la curva de aprendizaje no es precisamente plana, vale la pena tenerlo presente para cuando haya una explosión de su popularidad ya haber ganado algo de terreno.

Lo primero que debes hacer si quieres usar Julia en tus análisis de datos es bajar e instalar:

En mi caso me bajé la versión para Mac. Ahora eres capaz de correr el REPL (read-eval-print loop) de julia. Al entrar recomiendo usar Pluto, que es el ambiente de notebook de julia (está genial por cierto):

julia>using Pluto
julia>Pluto.run()

Con Pluto abierto y creando un nuevo notebook importa (using) algunas de la librerías que vamos a usar:

vamos a generar unas 5000 filas con algunos datos sintéticos. El comando sample() con o sin reemplazo sirve muy bien para ese propósito:

Vale la pena mencionar la similitud de las celdas de Pluto con las celdas de Jupyter (Python). Aunque hay importantes diferencias en el manejo de memoria y mecánismos en las corridas entre Python y julia, las interfaces con las celdas comparten ciertas caracteristicas. (1) Las puedes correr individualmente, (2) borrar, (3) mover,… En muchas circunstancias quisieras escribir más de una línea de código en una celda, por lo que tendras que usar, a diferencia de en Jupyter, el bloque beginend.

Imaginemos que estamos lidiando con un problema de Alzheimer, que hemos obtenido de una base de datos de pacientes de diferentes edades y que son diagnosticados con diferente niveles de gravedad de la enfermedad: inicial, nivel-I, nivel-II y “severo”. También ligado a esta base de datos tenemos una historia clínica de tratamientos: trata-I, trata-II, trata-III. En ambos casos podemos o no tener datos de los pacientes, y es por eso que incluimos missing como posible valor del sample!

Que curioso que cuando corremos una celda en Pluto, el resultado se muestra en la porción de arriba de la celda (Jupyter abajo!):

Nuestro Dataframe es creado con una línea de comando y su presentación en el notebook es muy elegante (la interface y sus fonts son únicas!)

Algo interesante que haremos será crear todos los estados posibles de nivel de severidad con historias clínicas. Para ello representaremos las historias clínicas como arreglos binarios de 0 o 1 para cada uno de los tratamientos aplicados:

Este comando “<allcombinations>” realiza todas esas combinaciones por nosotros:

De esta manera nos preparamos para crear una matriz 32x32 para cada edad de nuestros datos simulados. Recomiendo que tengamos una versión matricial para los cálculos del futuro:

En el momento de construir dos vectores con todos los posibles estados combinados podemos calcular (con frecuencia de eventos) probabilidades de transición (para nuestros datos sintéticos):

Y entonces podemos realizar conteo de transiciones de un estado al otro:

Con el comando <transform> podemos realizar el conteo y añadir nuevas columnas al Dataframe:

Creamos una matriz con el número de ocurrencias normalizadas con respecto a los estados 1 o 2 de nuestra base de datos:

Y finalmente tenemos nuestras probabilidades:

Y concluimos con el “Computo” de nuestra matriz 32x32 de probabilidades (como lo prometimos en el título del artículo):

Nuestro plan es luego usar alguna formulación de problemas como Markov Desicion Process (MDP) y computar políticas a partir de esos datos sintéticos.

Muchas gracias por leer,

hasta la próxima,

--

--