Mostrando entradas con la etiqueta calidad de datos. Mostrar todas las entradas
Mostrando entradas con la etiqueta calidad de datos. Mostrar todas las entradas

30 de septiembre de 2011

Capacitacion en openEHR: estándar libre de HCE

Disculpen la introducción tan personal, quiero dar el contexto completo del tema principal de este artículo: diseñar cursos sobre openEHR.

Un poco de contexto: haciendo un balance personal

Desde 2006 formo parte de la comunidad de openEHR internacional. Primero estudiando el estándar, luego probando distintas partes de la implementación. En 2010 terminé mi tesis de grado con un proyecto 100% basado en openEHR: el estándar libre para el desarrollo de historias clínicas electrónicas. Y en 2011 escribí junto a la Dra. Selene Indarte una publicación para CEPAL sobre interoperabilidad y estándares en Informática Médica (IM) (espero se publique antes de fin de año, igual pronto haré un artículo con los principales puntos de la publicación).

Hoy ya soy Ingeniero en Computación (título en trámite), sigo especializándome en estándares en IM (openEHR sobre todo), dirijo un proyecto de código abierto basado en openEHR, y he dictado capacitación y he dado charlas sobre distintos estándares (openEHR, HL7 CDA, CCR/CCD, DICOM, ...).

El perfil que estoy tratando de construir no está basado en el desarrollo de aplicaciones (en realidad programo por necesidad), lo que más me gusta es la gestión de proyectos, diseño y arquitectura de sistemas, la docencia, y la asesoría de proyectos en temas de estándares en IM e interoperabilidad.

Desde hace un tiempo, todo lo que leo y todo lo que aprendo trato de compartirlo con la comunidad, porque estoy convencido de que el conocimiento que no se comparte, no tiene razón de ser. Este blog es prueba de eso. También otros blogs y grupos de discusión que he creado. Hoy estoy tratando de formalizar un poco esa tarea de compartir conocimiento, y me encuentro armando un curso dirigido a openEHR, aunque rozando otros estándares importantes.


¿Porqué un curso de openEHR?

Hoy en día, openEHR es el único estándar orientado a la creación de sistemas de Historia Clínica Electrónica (HCE), de forma que sea interoperable desde el registro de la información clínica. Mi visión personal es que openEHR plantea una guía de cómo construir una buena HCE, mientras que otros estándares se centran en comunicar información clínica sin importar mucho si la HCE es buena o mala, es decir, si al comunicar la información que esta contiene, el resultado será consistente con el propósito de la información cuando esta fue registrada.

En mi artículo de introducción a openEHR puedes encontrar más información.

Además, consideremos el contexto actual en América Latina y el Caribe: existen numerosos proyectos de HCE en curso, se está comenzando a masificar el dictado de capacitación formal en IM tanto a informáticos como a médicos, y hay múltiples eventos cada mes que tocan el tema de la HCE. En este contexto ¿importa más crear una buena HCE o la comunicación entre sistemas? Mi respuesta es la primera, ya que la comunicación no puede existir si una buena HCE.

Otro argumento fuerte es que múltiples instituciones se encuentran en proyectos de reingeniería, cambiando sus HCEs anteriores por nuevas. Y esto no es un recambio tecnológico, es una adecuación de la HCE a la realidad, es decir que las HCEs anteriores no eran del todo buenas. ¿Qué hubiera pasado con buenas HCEs? Una buena HCE es flexible y adaptable por diseño, y si consideramos los costos de reingeniería, tal vez nos salga más barato invertir más tiempo en crear buenas HCEs.


El curso de openEHR que estoy diseñando

La idea central del curso es brindar una visión global del estándar, que se concentra en partes clave como el modelo de información y el modelo de arquetipos. Pero como no me gusta quedarme en lo conceptual, voy a mostrar cómo se integran esos conceptos con sistemas informáticos reales.

El núcleo del curso está basado en un taller que dicté el año pasado en el Congreso Argentino de Informática y Salud: http://www.slideshare.net/pablitox/taller-open-ehr-cais-2010-pablopazos
Este taller fue un verdadero desafío. Fueron 4 horas de taller y vinieron unas 14 personas (era más de lo que esperaba porque nadie me conocía y al lado había una charla de HL7 con gente super conocida). Igual la gente vino (y se quedó!), el 80% eran médicos, y la verdad se engancharon mucho con la temática. Luego me dio un poco de lástima que no pudieran profundizar más en el tema, y desde entonces me quedé con "la espina" de hacer algo más. Interés hay.

Este es un ejemplo de temario simplificado del curso:
  • Conceptos básicos: ¿qué es openEHR? ¿qué es un arquetipo? ¿qué es un template?
  • Analizando la realidad: conceptos clínicos, registros, procesos, estandarización, especificación.
  • Modelado: conceptos clínicos, información, interfaz de usuario, reglas de negocio.
  • Herramientas disponibles: gestor de conocimiento, editor de arquetipos, implementaciones de referencia.
  • Casos de estudio: creando una HCE para distintos dominios (emergencia, ambulatorio, internación, distintas especialidades)
  • Integración con estándares de contenido: Snomed, CIE 9, CIE 10, CIAP-2, Mesh, ATC.
  • Relación con otros estándares: ISO 13606, HL7 CDA, DICOM.
  • Comunicación con sistemas externos: interoperabilidad sintáctica, semántica y de negocio/proceso.

También estoy jugando con la idea de hacer algo especialmente para médicos con orientación informática, orientado a el modelado de información clínica, que podría ser un subconjunto del temario anterior. El objetivo de este cursillo sería promover métodos, herramientas, buenas prácticas y modelos de información clínica, para que los médicos que se encarguen de diseñar los registros clínicos, tanto electrónicos como en papel, puedan hacerlo lo mejor posible.

Algunos puntos que se podrían incluir son:
  • Conceptos básicos: ¿qué es un ...? (modelo, dato/información/conocimiento, proceso, registro, historia clínica, estructura de información, protocolo, estándar, concepto, ...).
  • Análisis de un caso de estudio: diseñar el registro clínico para el mismo.
  • Entre la libertad de registro y el registro estructurado: ventajas y desventajas.
  • Estructurando el registro: desde el dato a la historia clínica
  • Modelos de información clínica: identificando conceptos de la HC con openEHR, HL7 CDA, ASTM CCR e ISO 13606.
  • El registro contextualizado al proceso de atención: ¿quién? ¿para quién? ¿cuándo? ¿cómo? ¿dónde?
  • Análisis de caso de estudio: revisitando el caso de estudio y volviendo a diseñar el registro clínico.
  • Puesta a punto evaluando las diferencias entre los dos casos de estudio.


Planificación para el futuro

Uno de los objetivos de este artículo es medir el nivel de interés en la temática que planteo. El otro es saber su opinión sobre la temática, sobre lo que podría ser más interesante para incluir, o sobre lo que se podría hacer más hincapié.

También me gustaría ponerme en contacto con instituciones afines con la temática donde pueda dictar el curso, ya que mi idea para los próximos meses es vivir de la docencia. Además que voy a comenzar con mis estudios de maestría y podría hacer algún curso en la misma institución (para matar dos pájaros de un tiro).


Espero sus comentarios, y si saben de alguna institución que se pueda interesar, me avisan. Se agradece la difusión!


Un abrazo a todos.


PD: en mi cuenta de SlideShare hay más recursos.

13 de julio de 2011

Optimizacion de datos demograficos: buscando la herramienta perfecta

Muchos de los colegas que siguen este blog ya saben que le he dedicado más de un post al tema de los datos demográficos. Creo que muchos de los que nos hemos topado con proyectos de informatización de cierta embergadura en instituciones sanitarias, sabemos que aunque los proyectos apunten a la "capa clínica", debemos prestar mucha atención a la "capa demográfica", porque es ahí donde estará la información para indizar correctamente los registros clínicos.

Hoy estuve pensando en los problemas que pueden causar los datos demográficos incorrectos o incompletos, y en las funcionalidades que debería tener un sistema informático de auditoría para resolver esos problemas. Si bien el sistema perfecto no existe, es bueno de vez en cuando parar un segundo y pensar en cómo sería la herramienta perfecta para nuestra organización. Aunque no se pueda construir la herramienta de forma inmediata, creo que esta es la única forma de saber hacia dónde se debe ir.

Aquí están algunas notas mentales de lo que para mí debería hacer el sistema perfecto:
  1. Ejecución de algoritmos:
    1. Detección de datos faltantes
    2. Detección de datos incorrectos
    3. Detección de duplicados
  2. Presentación de informes para el auditor
    1. Muestra problemas detectados
    2. Muestra primero los casos con más prioridad a resolver
    3. Permite acceder a las funcionalidades de resolución de problemas y optimización de datos
      1. Completar datos faltantes
      2. Corregir datos erróneos
      3. Resolución de duplicados (unificación de identidades)
      4. Agregar relaciones familiares (p.e. padre-hijo) 
  3. Registrar información de feedback

1. Toda herramienta para gestión y auditoría de datos demográficos debería contar con al menos estos 3 grupos de algoritmos. Los algoritmos para detección de datos faltantes, por ejemplo se fijan si el registro de una persona carece de un medio de contacto telefónico, o si falta registrar el segundo apellido. Los algoritmos para detección de datos incorrectos, pueden por ejemplo verificar el sexo a partir del nombre de la persona, un caso de error podría ser si para el nombre Carlos se tiene registrado sexo Femenino. Y los algoritmos para detección de duplicados, ya los he cubierto en artículos anteriores [1, 2].

2. Los problemas detectados deben ser revisados por una persona que pueda auditar los registros. Muchas veces se cae en el error de querer crear el sistema perfecto que detecte y resuelva todos los problemas, pero en este caso lo mejor es tener un sistema con la inteligencia suficiente para detectar problemas y mostrarlos, y que una persona sea la que los resuelva. Para resolver los problemas, muchas veces esta persona va a tener que ponerse en contacto con la persona a la cual pertenecen los registros con errores, para obtener la información correcta desde la fuente. También se pueden aprovechar las instancias en que la persona viene a atenderse, para solicitar que verifique su información. Una parte importante en este proceso es la de resolución de registros duplicados, porque puede implicar que se deban unificar también registros clínicos. La otra parte importante es la de registrar las relaciones familiares entre pacientes, porque esto permite asociar historias clínicas familiares, y es útil para detectar problemas hereditarios a tiempo. ¡Los datos demográficos también sirven para mejorar la salud de las personas!

3. Cuando los problemas detectados, no son realmente problemas (las computadoras son tontas), se debe dar información al sistema para que éste sepa que esos no son problemas. Entonces, el sistema va "aprendiendo", y en la próxima detección de problemas, no los vuelve a marcar como tales. De esta forma, se va tendiendo hacia el óptimo del cero problema. Pero, como sabemos, este tipo de sistema gestiona datos que están en constante modificación: hay nuevos pacientes, se dan de baja otros, se corrigen datos, se ingresan nuevos duplicados, etc., por lo que este es un proceso que nunca termina, y se debe volver al punto 1 con una frecuencia que cada organización debería estimar.


¿Qué les parece? ¿Qué agregarían?

1 de diciembre de 2010

Los 10 mandamientos de la HCE

Luego de leer varias "biblias" de lo que se debe y no debe hacer en la implementación de la Historia Clínica Electrónica (HCE) en una institución sanitaria, y considerando de algunas experiencias de campo, creo que puede ser útil hacer una propuesta de los 10 puntos más importantes que son necesarios considerar en la creación e implementación de una HCE (a modo de "mandamientos", solo para hacerlo entretenido).


Los invito a hacer el mismo ejercicio y pensar para ustedes ¿cuáles serían los 10 temas más importantes en la creación e implantación de la HCE en una institución sanitaria?. Debajo del artículo pueden agregar sus comentarios.

1. Identificarás a tus personas

Todas las personas, que participan en cada acto médico y proceso asistencial, deben estar correctamente identificadas: pacientes, médicos, enfermeras, técnicos, administrativos, estudiantes, etc.

La identificación de los pacientes es la más complicada de resolver, ya que no depende de la asignación de un código o número identificador, si no, que depende de los procesos de asignación, verificación y auditoría.
  • Asignación: proceso de registro de información demográfica, y asignación de uno o más identificadores.
  • Verificación: obtención de la información suficiente para realizar una búsqueda y encontrar uno o más identificadores asignados a esa persona.
  • Auditoría: proceso que implica la certificación de que la información demográfica de la persona está completa y es correcta.

2. Identificarás a tus proveedores e insumos

Todas las empresas que provean algún tipo de insumo a una institución sanitaria, debe ser correctamente identificada, se deben tener medios de contacto de las personas que serán contraparte. También se deberá identificar cada insumo provisto por cada proveedor, y saber con certeza cuanto de cada insumo hay disponible en un momento dado (stock).


3. Identificarás a tus productos y servicios

Toda institución sanitaria debe saber con certeza qué productos y servicios provee, cual es el costo que insume brindarlos, por quién o quienes se brindan estos servicios (credenciales), desde donde se pueden brindar (lugares físicos) y para quién o quienes se brindan (clientes).


4. Sabrás quienes son tus pacientes, donde están y qué tienen

Aparte de que todo paciente deba estar unívoca e inequívocamente identificados en una institución sanitaria, los médicos de cabecera o médicos de familia deben saber cuáles pacientes tienen asignados, dónde viven y trabajan, y qué enfermedades, problemas de salud o condiciones tiene cada uno.
En este punto, la información geográfica y la identificación de problemas de salud es crucial. Este punto resume la base de la gestión clínica y de la epidemiología.


5. Especificarás tus procesos

Antes de poder comenzar con la informatización de los proceso asistenciales, es necesario saber cuáles son, quienes son responsables de estos procesos, quiénes participan, cuáles son los resultados esperados, y las precondiciones y restricciones que se dan.
Informatizar procesos indefinidos o caóticos es un error costoso.


6. El ADT es la primer aproximación a la HCE

El ADT (Admisión-Alta-Transferencia en inglés) puede implementarse como un sistema informático que sirva para saber:
  • por dónde, cuándo y con qué motivo ingresan los pacientes.
  • cuándo, a dónde, con qué motivo y a qué especialidad son transferidos los pacientes.
  • cuándo y a qué especialidades se realizan interconsultas.
  • a dónde, cuándo y con qué motivo se realizan las altas.
http://informatica-medica.blogspot.com/2009/11/primer-aproximacion-la-historia-clinica.html


7. La HCE permitirá registrar toda la información clínica

Ningún sistema informático puede establecer trabas a la libertad del registro del médico. La HCE mínima debe, por lo menos, contener al registro análogo en soporte papel.
En etapas tempranas, los registros con cuadros de texto libre son más aconsejables que los registros estructurados.
Estas HCEs mínimas se deberían implantar sobre los sistemas de ADT, ya que los eventos administrativos en el ADT desencadenan procesos de atención médica, con el respectivo registro en la HCE. Luego, los datos de ambos sistemas serán insumos fundamentales para la gestión.


8. Debes proveer trazabilidad en los sistemas informáticos

Debe quedar un registro de todas las acciones que realiza cada usuario del sistema informático. Para una correcta trazabilidad es necesario:
  • Identificar a los usuarios del sistema informático.
  • Registrar qué información ven, qué información agregan, qué información modifican.
  • Desde dónde acceden al sistema (lugar físico, terminal).
  • Cuándo acceden, durante cuánto tiempo (duración de la sesión, momento de cada acción).
  • Saber si intentan realizar acciones para las que no están autorizados (verificación de credenciales).

9. Debes crear un sistema usable

El sistema debe responder rápida y correctamente a los pedidos de los usuarios. Debe estar disponible cuando un usuario lo desea usar. Debe tener una interfaz gráfica amigable, simple, ordenada y fácil de entender. Se debe diseñar la interacción del usuario con el sistema (ejemplo: minimizar la cantidad de clics para que el usuario obtenga lo que desea del sistema). Los médicos deben acceder a la información de sus pacientes cuándo la necesiten y desde dónde la necesiten.


10. Aplicarás estándares

Para crear sistemas informáticos de calidad, debes basar tus sistemas en estándares probados y aceptados por una comunidad. Reutilizando y adaptándolos a la realidad de un país o una institución en particular. No reinventarás la rueda, y reutilizarás las herramientas existentes y disponibles.
La estandarización simplifica la informatización y el desarrollo de nuevos componentes y funcionalidades que extiendan y adapten el sistema informático a nuevos requerimientos.
La estandarización es la base de la interoperabilidad.


Si bien la idea no es crear una religión al rededor de estos mandamientos, tal vez sirvan como guía para quienes empiezan con desarrollos de HCE en sus instituciones (digamos que estamos evangelizando) a la comunidad de informáticos y médicos involucrados en desarrollos de HCE.

¡Espero sus comentarios!

2 de noviembre de 2010

Espacio para compartir, discutir y aprender

OpenEHR-ES intenta ser la génesis de un grupo de discusión en español (el primero en este idioma), en donde se planteen temas relacionados con OpenEHR y su enfoque para la creación de sistemas de información en salud.

No obstante, también es un espacio para charlar de otros estándares como HL7, CDA, ISO/CEN 13606, DICOM, terminologías y clasificaciones internacionales, etc, etc, etc. Esto es porque quienes creamos sistemas de información en salud, necesitamos distintos estándares para resolver distintos aspectos de nuestros sistemas.

Para ser parte del grupo, lo único que debes hacer es suscribirte aquí: http://groups.google.com/group/openehr-es

No es necesario que seas un experto, ni tampoco es excluyente para ningún rol o país. El grupo está formado por informáticos, médicos, veterinarios, y gente curiosa. También tenemos gente de Argentina, Chile, Colombia, Brazil, USA, España, Uruguay y más.

El primer objetivo del grupo es conocernos, saber quienes están interesados en trabajar con OpenEHR o ya están trabajando, intercambiar opiniones y experiencias, y ser un nexo entre profesionales para la colaboración en proyectos. En el futuro el grupo buscará agregar un área de capacitación, con cursos y materiales, de forma de simplificar la adopción y difusión de la norma, ya que muchos no tienen el tiempo suficiente de estudiar las especificaciones (¡y vaya que son largas!). También buscaremos eventos para poder compartir las experiencias, objetivos y para fortalecer la comunidad OpenEHR de habla hispana.

¡Son todos bienvenid@s!

12 de septiembre de 2010

Aumento en la calidad de datos patronimicos 2: heuristicas

Introducción

En un artículo previo, he definido un algoritmo para detectar el Índice de Coincidencia (IC) entre dos identidades de personas. Estas identidades están formadas por un conjunto de datos arbitrario, como nombres, apellidos, sexo fecha de nacimiento, etc. En el artículo previo, no se especificó cómo eran seleccionadas las idendidades a ser comparadas. En este artículo la idea es definir los conceptos que permitan entender las distintas formas de pre-selección de identidades de forma que las comparaciones no tarden años en ejecutarse, y a la vez permita detectar la mayor cantidad de registros duplicados en una base de datos.


Objetivo

El objetivo final del cálculo del IC entre dos identidades es poder encontrar posibles duplicados en los registros de las personas (sobre todo entre los pacientes). Una vez que se encuentran dos o más registros duplicados, se procede a la unión de esos registros. Esto es esencial para garantizar que los procesos de identificación de personas (en el ámbito de la salud) funcionen correctamente, y para garantizar que el registro clínico se realiza para la persona correcta, y que todos los registros clínicos de esa persona están asignados a una única identidad (si la persona tiene más de una identidad, por tener registros de identidades duplicadas, su información sanitaria estará fragmentada, o sea siempre será incompleta).

Entonces, es necesario ejecutar el algoritmo que detecta coincidencias tomando y comparando de a 2 los registros de las personas en la base de datos de pacientes de una o múltiples instituciones sanitarias. El problema es que si en una base de datos con 1000 pacientes se hacen comparaciones de a 2, se terminan haciendo 1.000.000 (1M) comparaciones. Tal vez 1M comparaciones no sea un gran problema, pero ¿qué pasaría si la base de datos tuviera 1M registros de pacientes?, ¡las comparaciones se disparan a un millón de millones!. En este caso, si cada comparación tarda unos 3 segundos, el total de las comparaciones tardarían unos 95129 años aproximadamente.

El objetivo es claramente bajar ese tiempo de ejecución, pero a la vez garantizar que se encontrarán todos los duplicados en las identidades persentes en la base de datos.

Para lograr esto es necesario disminuir la cantidad de registros a comparar de 2 en 2, por lo que previamente a ejecutar la comparación entre 2 identidades, ejecutaremos una heurística que permita preseleccionar todas las identidades que deben compararse, siendo esta cantidad mucho menor a la cantidad de identidades de personas guardadas en la base de datos.

Debe quedar claro que el único método que garantiza que se encuentran todos los duplicados en una base de datos es comparar 2 a 2 todos los registros de la base, cosa que, como ya mencionamos, es impracticable en bases de datos con muchos registros.

La heurística con la que se consigan encontrar todos los duplicados, será la heurística óptima, pero ninguna heurística puede garantizar esto para cualquier base de datos con identidades de personas. O sea, que la los resultados de aplicar la heurística para preselección de registros, depende de la base de datos. Profundizaré sobre este concepto más adelante.


Metodología

El objetivo de las heurísticas es obtener conjuntos de registros de identidades que "se parecen en algo", pero sin necesidad de ejecutar el Algoritmo de Verificación de Identidades (AVI) para calcular el Índice de Coincidencia entre las identidades. A estos conjuntos de identidades "parecidas" les llamaremos "Clases de Preselección" o solo "CP". De este modo, las compararciones de a 2 identidades usando el AVI, se hacen solo sobre las identidades de cada CP, no sobre todos los registros de identidades.

A continuación voy a mostrar el camino lógico que seguí para ir de una comparación de 2 en 2 sobre todos los registros de una base, hasta la solución final encontrando algunas heurísticas por "sentido común", que luego fueron probadas y funcionaron correctamente.

El peor caso empieza teniendo que comparar todas las identidades de la base, de 2 en 2. Esto se puede representar en un cuadro de doble entrada, donde cada par de entradas señalan una comparación a realizar. En la fig. 1 se puede apreciar este cuadro, y como se realizan todas las comparaciones de 2 en 2, aparece todo pintado de verde (este color indica las comparaciones a realizar).

 Fig. 1: cuadro de comparaciones inicial


La primer optimización es que si se compara la identidad A con la identidad B, no es necesario hacer la comparación de B con A, por lo que se reducen las comparaciones a algo menos que la mitad, ya que también se evitan las comparaciones de A con A, B con B, etc. En la fig. 2, las comparaciones se hacen solo sobre la mitad de los registros.

Fig. 2: se comparan solo la mitad de las identidades


Esta primer optimización reduce la cantidad total de comparaciones pero no cambia el orden o la magnitud de comparaciones a realizar, es decir, si antes había que hacer millones de comparaciones, ahora hay que hacer millones/2. Por lo que si antes tardábamos más de 95000 años en hacer las comparaciones de 1M registros, ahora tardaremos más de 47000 años, cosa que sigue siendo impracticable.

Bien, ahora ¿qué pasaría si tuviéramos algo que nos dijera que comparaciones hacer antes de hacerlas?, podríamos bajar el número total de comparaciones y llevar el tiempo total de ejecución a algo razonable. Hacer esto implica que debemos agrupar identidades "parecidas" pero sin calcular el IC, ya que eso nos llevaría de nuevo al problema inicial. La idea es que el algoritmo que agrupe entidades parecidas en Clases de Preselección, también sea un algoritmo rápido. O sea que el tiempo total de hacer la preselección, más el tiempo total de calcular el IC entre 2 identidades, para todas las identidades de cada CP, sea muchísimo menor al tiempo total de ejecución de la primer optimización que se muestra en la fig. 2.

La idea es bien fácil, primero hay que definir el criterio por el cual se agrupan las identidades en las Clases de Preselección. Los criterios que he utilizado en mis pruebas son:
  1. Agrupar por primer letra del primer nombre
  2. Agrupar por primer letra del primer apellido
  3. Agrupar por fecha de nacimiento:
    1. Total: día, mes y año (no sirve si las fechas tienen errores en alguno de sus 3 campos)
    2. Parcial: solo día y mes, o solo mes y año (es más fuerte ante errores en algún campo de la fecha)

Para el criterio 1, lo que se hace es ordenar todas las identidades por primer nombre y tomar de a X identidades con X arbitrario, tomando como CPs por los registros 1..X, X+1..2X, etc., de esta forma cada CP tendrá solo X registros, siendo X mucho menor a N, con N la cantidad total de registros. Con N=1M y X=200, las comparaciones totales serían 5000 x 200^2 / 2 = 100M (en lugar de 1M de millones!). Igualmente este ejemplo, con cada comparación hecha en 3 segundos, tardaría unos 9 años. Si varía X, se podrá variar la cantidad total de comparaciones necesarias. Obviamente el tiempo de comparación de 2 registros dependerá de la velocidad del hardware y de lo complicado que sea el algoritmo de comparación entre 2 identidades.

En la fig. 3 se visualizan las comparaciones a realizar usando Clases de Preselección. Las flechas indican que hubo un ordenamiento de los registros según algún criterio. Se puede ver claramente que la cantidad total de comparaciones disminuye de forma considerable.

Fig. 3: primer aproximación para encontrar Clases de Preselección


De forma análoga se pueden aplicar otros criterios y obtener CPs alternativas. Un potencial problema es que los registros tengan errores y esos errores repercutan en el criterio que se use para crear las CPs. Por ejemplo, si se usa el criterio de tomar de a X identidades, tal que estén ordenadas por la primer letra del primer nombre, si existen muchos primeros nombres con error de registro en la primer letra, un potencial duplicado puede no ser detectado, ya que las identidades con error en la primer letra del primer nombre van a parar a otra CP. Con esto fundamentamos una afirmación hecha previamente: la heurística o criterio que se utilice para crear las CPs depende de cada base de datos, porque depende de los errores que haya en el registro.

Para conseguir una heurística fuerte ante los errores más comunes en nuestros registros, se pueden optar por dos estrategias:
  1. Hacer un estudio estadístico de los errores más comunes en el registro
  2. Utilizar más de una heurística para calcular los ICs entre las identidades

En mi caso opté por la segunda estrategia. Lo que hice fue calcular el IC para los registros de cada CP creada a partir del criterio de "primer letra del primer nombre", pero luego calculé de nuevo el IC para los CPs creados a partir del criterio "primer letra del primer apellido", de esa forma las comparaciones que se me escaparon en la primer vuelta, por tener errores en el primer nombre, en la segunda vuelta, utilizando el criterio por primer apellido, logro que se comparen. Obviamente, un registro puede tener errores en el primer nombre y en el primer apellido, pero la probabilidad de que esto suceda es menor de que un registro tenga error en el primer nombre o en el primer apellido.

Existe una optimización a este tercer paso, debido a un problema que presenta en los límites de las CPs. Ya que si se ordenan los registros y se toman 2 CPs contiguas, es problable que los últimos registros de la primer CP se parezcan a los primeros registros de la segunda CP, y al no considerar esto, estamos perdiendo duplicados potenciales. Para cubrir esto, lo que se hace es solapar un poco las CPs, así la primer CP calcula el IC entre sus identidades, pero también incluye a las primeras identidades de la segunda CP. En la fig. 4 se muestran las CPs solapadas para evitar que se escapen duplicados en los límites de las CPs.

Fig. 4: Clases de Preselección solapadas para incluir comparaciones de casos límite


Otras heurísticas pueden crearse en base a los datos disponibles, y usarse de forma coplementaria para no dejar registros parecidos afuera de las comparaciones.


Conclusiones

Es necesario crear alguna heurística que permita preseleccionar los registros que luego se van a comparar de 2 en 2, para así bajar los tiempos totales de ejecución.

Vimos que el éxito las heurísticas depende de los errores que se tengan en los registros de datos personales, por este motivo, antes de aplicar una heurística cualquiera para encontrar las CPs, es útil estudiar la base de datos para determinar cuáles son los errores más frecuentes y en cuáles datos. De este modo, podemos encontrar heurísticas que sean fuertes ante esos errores, permitiendo encontrar la mayor cantidad de duplicados posible.

Acompañando a las heurísticas se pueden usar otros métodos para acelerar las comparaciones entre las identidades de cada Clase de Preselección. Por ejemplo, el uso de programación paralela, donde distintos CPs puedan ser procesados en simultáneo, permite acelerar un poco las comparaciones totales, aunque no disminuye el orden de las comparaciones. Por ejemplo, si cada CP tiene 250 identidades, y cada comparación tarda 3 seg., las comparaciones para cada CP serán unas 250*250/2 = 31250 y tardarán unas 26 horas. Si se tienen 4 procesadores en paralelo, el tiempo total de ejecución bajará a unas 6,5 horas.


Espero que se haya entendido la idea, si no, comentan abajo y lo explicamos mejor.

26 de marzo de 2010

Aumento de calidad de datos patronimicos

En el 2009 estuve trabajando sobre un algoritmo para realizar búsquedas de pacientes en un base de datos. Si bien esto es una tarea más que resuelta en muchas instituciones, el objetivo del algoritmo era no solo obtener una lista de datos de personas que se correspondieran con un criterio dado, si no detectar en cuanto se corresponden, de forma de encontrar los registros que más se parezcan a lo que buscamos.

Si bien se logró un algoritmo junto al Subcomité Técnico de Identificación de Personas (STID) de SUEIIDISS (HL7 Uruguay), del que participé en el 2009, yo me concentré en otro problema, el de la calidad de los datos. Si bien podemos pensar en cómo resolver las búsquedas de la mejor forma, si la calidad de los datos en nuestra base de datos es pobre, el resultado de la búsqueda será de poca utilidad, y si se llevara la calidad a niveles óptimos, cualquier mecanismo simple de búsqueda nos ayudaría a encontrar lo que necesitamos, por eso el cambio de enfoque. Dicho sea de paso, aquí se puede obtener una copia del documento logrado en el STID.

El resultado de mi investigación fue un algoritmo que sirve para comparar dos identidades, formadas por los atributos: nombres, apellidos, fecha de nacimiento y sexo de una persona. Cualquier tipo de identificador de la persona no forma parte de su identidad, por eso no se consideran números de documentos nacionales ni otros tipos de identificadores en las identidades. El resultado del algoritmo es un número entre 0 y 1 donde 0 indica coincidencia nula y 1 coincidencia total. Un resultado de 0.85 indica que las identidades coinciden en un 85%.

Este algoritmo fue probado en bases de datos con miles de registros, y los resultados obtenidos son óptimos. Según estos experimentos, las identidades cuya coincidencia supera el 95% corresponden a la misma persona, y la diferencia se debe a que hay errores en los datos, por ejemplo un nombre mal escrito, que en base a mis experimentos, es uno de los casos más frecuentes en los de fuentes de error, por ejemplo una letra faltante o la transposición de letras son de los errores más comunes.

Detrás del algoritmo hay tres ideas muy intuitivas:
  • Distintos datos de la identidad de una persona pesan distinto en la identificación de la misma. Nuestra identidad es lo que nos diferencia de las demás personas, pero distintas partes de esta identidad puede diferenciarnos en mayor o menor medida. No es lo mismo diferenciarse por los nombres que por la fecha de nacimiento, seguramente hayan muchas más personas que nacieron el mismo día que uno, que personas que se llaman igual. Entonces cada atributo de la identidad tiene un peso asociado.
  • No solo pasa que cada atributo pesa distinto en la identificación de la persona, si no que este peso en realidad debería variar dependiendo del valor de los atributos. Por ejemplo, si un apellido es muy común, el peso debería ser menor, y si es un apellido poco usual, su peso debería ser mayor. El algoritmo que considera esta afirmación se llamará "Algoritmo de Verificación de Identidades Avanzado" o "AVI-a", y no será descrito en este artículo.
  • El algoritmo debe comportarse bien ante casos de errores en los datos, es decir que si se comparan dos identidades, y una tiene errores en los datos, el algoritmo debería igualmente detectar la similitud entre las identidades. Es por esto que condiciones de igualdad o igualdad parcial no son útiles para el cálculo del índice de coincidencia porque consideran a los datos como un todo o lo divide en grandes partes, es necesario llegar a un nivel de comparación con granularidad suficiente para que los errores no afecten tanto a las comparaciones.

Descripción del Algoritmo de Verificación de Identidades Básico (AVI-b):

Aquí voy a bajar a un nivel muy técnico, igualmente voy a ir explicando los detalles para que nadie pierda el hilo.

La identidad mínima de una persona, como mencioné antes, está formada por los atributos: nombres, apellidos, sexo y fecha de nacimiento. Vamos a tomar dos identidades id1 e id2 para compararlas según el AVI-b.

// Tipo que define la Identidad
Identidad {
  String nom1
  String nom2
  String ap1
  String ap2
  CodigoSexo sexo
  Fecha fecha_nac
}

// Tipo que define la el código para el sexo según la
// codificación utilizada en HL7 que se puede ver aquí:
CodigoSexo {
  const String MASCULINO = "M"
  const String FEMENINO = "F"
  const String IDENFINIDO = "UN"

  // Debe ser alguna de las constantes definidas previamente
  String codigo

}

// Identidades a comparar, con respectivos sus valores para cada atributo
Identidad id1 = { nom11, nom12, ap11, ap12, sexo1, fecha_nac1 }
Identidad id2 = { nom21, nom22, ap21, ap22, sexo2, fecha_nac2 }


Como se mencionó, una de las ideas detrás del algoritmo es que, cada atributo de la identidad tiene un peso distinto en cuanto a la identificación de la persona. A continuación se especifica el peso de cada atributo en la identificación, donde la regla que deben cumplir estos valores es que deben sumar 1, porque si se tienen todos los atributos de la identidad, estos sirven para identificar a la persona en un 100%. Esto se traduce a que si el peso del primer nombre es 0.175, quiere decir que el primer nombre identifica a una persona en un 17,5%. Los valores aquí propuestos son valores encontrados empíricamente, para los cuales se obtuvo un buen funcionamiento del algoritmo (AVI-b).

// Los pesos deben sumar 1
pesos[nom1] = 0.175
pesos[nom2] = 0.175
pesos[ap1]  = 0.175
pesos[ap2]  = 0.175
pesos[sexo] = 0.1
pesos[fecha_nac] = 0.2



No está de más comentar que si bien los pesos planteados para el algoritmo básico (AVI-b) son constantes, por lo expresado en las ideas que están detrás del algoritmo, para el algoritmo avanzado (AVI-a), estos pesos serían funciones que dependen del valor de cada atributo.

A continuación se especifican los algoritmos de comparación de atributos simples que se utilizan para calcular el índice de coincidencia, que es el resultado del AVI-b. Se plantean dos algoritmos distintos para la comparación de nombres y apellidos, uno para el sexo y otro para la fecha de nacimiento. El primer algoritmo para comparar nombres hace la cuenta de cuantos caracteres coinciden en valor y posición y retorna esta cantidad dividida el largo de la palabra más larga, por lo que se obtiene un resultado en el rango 0..1, con valor 1 cuando los nombres y apellidos coinciden completamente. El segundo algoritmo de comparación de nombres está basado en la distancia de Levenshtein, que calcula cuantos caracteres se le deben agregar a una palabra para hacerla coincidir con otra, por lo tanto si el resultado de Levenshtein es 0 las palabras son la misma. La el índice basado en Levenshtein va a dar resultados más altos cuando haya errores de transposición u omisión de caracteres en alguno de los nombres que se están comparando, mientras que el primer algoritmo va a dar más bajo cuando uno de los nombres que se compara tiene alguna letra de menos. Luego voy a mostrar un ejemplo de esto, así que si no se entendió, luego lo retomaremos.

// Case Insensitive Char by Char:
// comparacion de palabras utilizando indice basado en
// comparacion caracter a caracter.
coin_ci_cbc( String a, String b)
{
   // Se pasa todo a minusculas para comparar
   a = pasar_a_minusculas( a )
   b = pasar_a_minusculas( b )
   int max_len = maxLargo(a, b) // Largo del string mas largo
   int min_len = minLargo(a, b) // Largo de string mas corto
   int coincidencias = 0

   for (i = 0..min_len)
   {
      if ( a[i] == b[i] ) coincidencias ++
   }

   return coincidencias / max_len
}


// Case Insensitive Levenshtein:
// comparacion de palabras utilizando indice basado en distancia de Levenshtein
// Mas info>
// - http://www.levenshtein.net/
// - http://es.wikipedia.org/wiki/Distancia_de_Levenshtein
coin_ci_levens( String a, String b)
{
   // Se pasa todo a minusculas para comparar
   a = pasar_a_minusculas( a )
   b = pasar_a_minusculas( b )

   // Largo del string mas largo
   int max_len = maxLargo(a, b)

   // Calcula el indice basado en la distancia de levenshtein

   return 1 - ( levenshtein(a, b) / max_len )
}

coinSEXO(CodigoSexo s1, CodigoSexo s2)
{
   if (s1.codigo == s2.codigo) return 1
   return 0
}

coinFECHA (Fecha f1, Fecha f2)
{
   if (f1 == f2) return 1
   return 0
}


Por último, el cálculo del Índice de Coincidencia que será resultado del AVI-b, como vemos usamos los pesos y los algoritmos para calcular la comparación de atributos simples. En el ejemplo se utiliza coin_ci_cbc como comparador de nombres, éste se podría cambiar por coin_ci_levens.

IC( id1, id2 ) = pesos[nom1] * coin_ci_cbc(id1.nom1, id2.nom1) +
          pesos[nom2] * coin_ci_cbc(id1.nom2, id2.nom2) +
          pesos[ap1]  * coin_ci_cbc(id1.ap1,  id2.ap1) +
          pesos[ap2]  * coin_ci_cbc(id1.ap2,  id2.ap2) +
          pesos[sezo] * coinSEXO(id1.sexo, id2.sexo) +
          pesos[fecha_nac] * coinFECHA(id1.fecha_nac, id2.fecha_nac)

En la siguiente tabla se puede ver el comportamiento del algoritmo básico (AVI-b) probando con algunos casos donde se toma una identidad y se varía algún dato para verificar cómo esta modificación afecta al Índice de Coincidencia (IC) que obtengo como resultado. Algunas aclaraciones para poder interpretar correctamente los resultados:
  • La identidad ID1 es siempre la misma, la que varía es ID2 en algunos valores.
  • Se hicieron 3 casos de comparación, probando con los dos algoritmos distintos para la comparación de nombres y apellidos.
  • Las filas de igual color corresponden a comparaciones de las mismas identidades pero utilizando algoritmos distintos para la comparación de nombres, es decir: ci_cbc o ci_levens.
  • En las filas 1 y 4, la variación de ID2 con respecto a ID1 es que en el segundo nombre se sacó una letra, la C.
  • En las filas 2 y 5, la variación de ID2 con respecto a ID1 es en la fecha de nacimiento.
  • En las filas 3 y 6, la variación de ID2 con respecto a ID1 es el primer nombre completo, manteniendo todos los otros datos. Este caso se podría dar en hermanos gemelos o mellizos, y el algoritmo debería ayudar a diferenciar entre ellos, si no es así, se debería utilizar la identidad extendida mediante los datos de "indicador de nacimiento múltiple" y "orden de nacimiento" que se describen en el documento del STID.

# IC Algor. ID1 ID1 fecha ID2 ID2 fecha
1
0.86
ci_cbc
Ana Jacqueline
Gomez Rodriguez
1983-11-22 F Ana Jaqueline
Gomez Rodriguez
1983-11-22 F
2
0.8
ci_cbc
Ana Jacqueline
Gomez Rodriguez
1983-11-22 F Ana Jacqueline
Gomez Rodriguez
1983-11-12 F
3
0.825
ci_cbc
Ana Jacqueline
Gomez Rodriguez
1983-11-22 F Carla Jacqueline
Gomez Rodriguez
1983-11-22 F
4
0.9825
ci_levens
Ana Jacqueline
Gomez Rodriguez
1983-11-22 F Ana Jaqueline
Gomez Rodriguez
1983-11-22 F
5
0.8
ci_levens
Ana Jacqueline
Gomez Rodriguez
1983-11-22 F Ana Jacqueline
Gomez Rodriguez
1983-11-12 F
6
0.895
ci_levens
Ana Jacqueline
Gomez Rodriguez
1983-11-22 F Carla Jacqueline
Gomez Rodriguez
1983-11-22 F
Tabla de resultados


Trabajo futuro:

Si bien se probó empíricamente el buen funcionamiento del Algoritmo de Verificación de Identidades Básico (AVI-b) creo que se podría ajustar aún más el resultado utilizando el algoritmo avanzado, donde los pesos se ajustan según los valores de los atributos de las identidades. Esto sería fácil de hacer si se tienen calculadas las frecuencias de nombres y apellidos de las identidades que se tienen en la base de datos donde están registradas las identidades a verificar, esto quiere decir, calcular cuántas personas tienen cada nombre (Pablo, Pedro, Juan, etc) y dividir cada una de esas cantidades entre el número total de identidades en la base. Luego esa frecuencia sería utilizada para aumentar el peso de un atributo (si es que hay poca frecuencia de ese nombre o apellido), o disminuir el peso de un atributo (si es que hay muchas personas que se llaman igual). Esta técnica ajustaría los valores resultantes de las comparaciones a un porcentaje más ajustado a la realidad. Como puede resultar obvio, los valores de frecuencias se deberían actualizar cada tanto, y con esto logramos un resultado que puede estar oculto a primera vista: el algoritmo se ajusta a las distintas frecuencias de nombres que se dan en distintos momentos. Es sabido que hay épocas donde un nombre se hace muy popular, y en algunos años el nombre más popular cambia, cambiando la frecuencia de personas que podemos encontrar con esos nombres en nuestras bases de datos. Con esto logramos un algoritmo que se adapta automáticamente (algoritmo adaptable) a cambios que se dan en la cultura de la sociedad. ¿Interesante no?


Conclusiones:

Cómo se puede apreciar en las filas 1 y 4 de la tabla de resultados, al cambiar una sola letra de un nombre o un apellido, el IC es mucho más alto usando el algoritmo ci_levens que el ci_cbc para comparar nombres, esto se debe a que el índice que se calcula en base a Levenshtein es más fuerte o se comporta mejor ante pequeños cambios. Este cambio se puede deber a un error humano en el registro, y es bueno tener un algoritmo que lo pueda detectar. Es decir que la detección de duplicados también ayuda a la detección de errores en el registro, y por lo tanto a mejorar la calidad del mismo, que es el objetivo planteado al inicio.

En las filas 2 y 5 no vemos cambio en el resultado del CI porque lo que es distinto entre las identidades es la fecha de nacimiento.

Por último, en las filas 3 y 6 vemos una pequeña diferencia en el CI, esto se debe a que el primer nombre es tan distinto entre ID1 e ID2 que tanto el índice basado en Levenshtein como el índice basado en la cuenta carácter a carácter detectan que ambos nombres son distintos, bajando el valor del CI en cantidades similares.

Espero que se hayan entendido las ideas detrás del algoritmo, cuáles eran los objetivos y que hayan quedado claras las conclusiones. Por cualquier consulta o comentario no duden en agregar un comentario.