Artículo
· 31 jul, 2024 Lectura de 4 min

d[IA]gnosis: vectorizando diagnósticos con Embedded Python y modelos LLM

En el artículo anterior presentábamos la aplicación d[IA]gnosis desarrollada para el soporte a la codificación de diagnósticos en CIE-10. En este veremos como InterSystems IRIS for Health nos proporciona las herramientas necesarias para la generación de vectores a partir de la lista de códigos CIE-10 mediante un modelo pre-entrenado de lenguaje, su almacenamiento y la posterior búsqueda de similitudes sobre todos estos vectores generados.

Introducción

Una de las principales funcionalidades que han surgido con el desarrollo de modelos de IA es lo que conocemos como RAG (Retrieval-Augmented Generation) que nos permite mejorar los resultados de modelos LLM mediante la incorporación de un contexto sobre el modelo. Pues bien, en nuestro ejemplo el contexto nos viene dado por el conjunto de diagnósticos CIE-10 y para utilizarlos primeramente deberemos vectorizarlos.

¿Cómo vectorizar nuestra lista de diagnósticos? 

SentenceTransformers con Embedded Python

Para la generación de vectores hemos utilizado la librería de Python SentenceTransformers que nos facilita de sobremanera la vectorización de textos libres a partir de modelos pre-entrenados. De su propia página web:

Sentence Transformers (a.k.a. SBERT) is the go-to Python module for accessing, using, and training state-of-the-art text and image embedding models. It can be used to compute embeddings using Sentence Transformer models (quickstart) or to calculate similarity scores using Cross-Encoder models (quickstart). This unlocks a wide range of applications, including semantic searchsemantic textual similarity, and paraphrase mining.

Dentro de todos los modelos desarrollados por la comunidad de SentenceTransformers hemos encontrado BioLORD-2023-M, un modelo preentrenado que nos generará vectores de 786 dimensiones.

This model was trained using BioLORD, a new pre-training strategy for producing meaningful representations for clinical sentences and biomedical concepts.

State-of-the-art methodologies operate by maximizing the similarity in representation of names referring to the same concept, and preventing collapse through contrastive learning. However, because biomedical names are not always self-explanatory, it sometimes results in non-semantic representations.

BioLORD overcomes this issue by grounding its concept representations using definitions, as well as short descriptions derived from a multi-relational knowledge graph consisting of biomedical ontologies. Thanks to this grounding, our model produces more semantic concept representations that match more closely the hierarchical structure of ontologies. BioLORD-2023 establishes a new state of the art for text similarity on both clinical sentences (MedSTS) and biomedical concepts (EHR-Rel-B).

Como podéis ver en su propia definición, este modelo está preentrenado con conceptos médicos que nos resultará útil a la hora de vectorizar tanto nuestros códigos CIE-10 y el texto libre.

Para nuestro proyecto nos descargaremos dicho modelo para poder agilizar la creación de los vectores:

if not os.path.isdir('/shared/model/'):
    model = sentence_transformers.SentenceTransformer('FremyCompany/BioLORD-2023-M')            
    model.save('/shared/model/')

Una vez en nuestro equipo, podremos introducir los textos a vectorizar en listas para acelerar el proceso, veamos como vectorizamos los códigos CIE-10 que hemos grabado previamente en nuestra clase ENCODER.Object.Codes

st = iris.sql.prepare("SELECT TOP 50 CodeId, Description FROM ENCODER_Object.Codes WHERE VectorDescription is null ORDER BY ID ASC ")
resultSet = st.execute()
df = resultSet.dataframe()

if (df.size > 0):
    model = sentence_transformers.SentenceTransformer("/shared/model/")
    embeddings = model.encode(df['description'].tolist(), normalize_embeddings=True)

    df['vectordescription'] = embeddings.tolist()

    stmt = iris.sql.prepare("UPDATE ENCODER_Object.Codes SET VectorDescription = TO_VECTOR(?,DECIMAL) WHERE CodeId = ?")
    for index, row in df.iterrows():
        rs = stmt.execute(str(row['vectordescription']), row['codeid'])
else:
    flagLoop = False

Como véis, primeramente extraemos los códigos almacenados en nuestra tabla de códigos CIE-10 que aún no hemos vectorizado pero que hemos registrado en un paso anterior tras extraerlo del archivo CSV, a continuación extraemos la lista de descripciones a vectorizar y mediante la librería de Python sentence_transformers recuperaremos nuestro modelo y generaremos los embeddings asociados.

Finalmente actualizaremos el código CIE-10 con la descripción vectorizada ejecutando el UPDATE, como véis, el comando para vectorizar el resultado devuelto por el modelo es el comando TO_VECTOR de SQL en IRIS.

Incluyéndolo en IRIS

Muy bien, ya tenemos nuestro código Python, así que sólo necesitamos incluirlo en una clase que extienda Ens.BusinessProcess e incluirlo en nuestra producción, a continuación lo conectamos con el Business Service encargado de recuperar el archivo CSV y ¡listo!

Echemos un vistazo a la forma que tomará este código en nuestra producción:

Como véis, tenemos nuestro Business Service con el adaptador EnsLib.File.InboundAdapter que nos permitirá recoger el fichero de códigos y redirigirlo a nuestro Business Process en el cual realizaremos toda la operativa de vectorización y almacenamiento de los mismos, dándonos como resultado un conjunto de registros como el siguiente:

¡Pues ya estaría lista nuestra aplicación para empezar a buscar posibles coincidencias con los textos que le vayamos pasando!

En el próximo artículo...

En la próxima entrega vamos a mostrar como se integra el front-end de la aplicación desarrollado en Angular 17 con nuestra producción en IRIS for Health y cómo IRIS recibe los textos a analizar, los vectoriza y busca similitudes en la tabla de códigos CIE-10.

¡No os lo perdáis!

Comentarios (0)1
Inicie sesión o regístrese para continuar