intive Argentina Blog

Extracción de secciones de texto

La sintáctica y semántica dentro de un texto define estructuras cuya complejidad puede escapar a los algoritmos tradicionales. Caracterizar un documento nos permite hacer un análisis particular para cada parte del mismo. En esta charla vamos a explorar el planteo del problema, algunas soluciones y formas de encarar problemas comunes.

Los textos, su estructura y estandarización

Todos los textos tienen una estructura sintáctica y semántica por ejemplo los cuentos sencillos tienen introducción, nudo y desenlace. Hay algunas estructuras que están más estandarizadas que otras, como podrían ser las cartas de recomendación, los documentos comerciales, algunos documentos legales, manuales, libros, entre otros.

Un ejemplo de texto altamente estructurado es el de las leyes, cuya jerarquía va de títulos a capítulos y estos también están subdividido en sus propias secciones. Si este artículo estuviera en texto plano sería sencillo identificar en dónde empieza un artículo y termina el otro, porque existen palabras claves como “ARTÍCULO 1°, ARTÍCULO 2°…”.

El problema del cliente surge porque, a menor estandarización y mayor dependencia semántica, se vuelve más costoso y menos viable usar expresiones regulares para hacer chunking de textos (seccionar el texto y partirlo etiquetando cada parte con alguna categoría).

Se cuenta con cientos de miles de documentos en distintos formatos (txt, pdf y html), sin ninguna metadata asociada a su estructura. El objetivo es presentarlos al usuario de forma legible, para que pudiera explorar y encontrar la información de acuerdo a sus necesidades. Seccionar texto permitiría construir un índice logrando que texto crudo sea más navegable. Luego, además, se podría clasificar, indexar o procesar de forma especial cualquiera de las secciones de interés por separado, y asociarlas a sus secciones contiguas.

Se comienza el análisis entonces, caracterizando a los documentos:

  • Hay una cantidad finita de secciones de un documento.
  • Las secciones del documento dependen de la sintaxis, de la semántica y de su contexto.
  • Todos los documentos tienen los mismos tipos de secciones.
  • Hay “diálogos” entre tipos de secciones.
  • No hay “keywords” que nos indiquen de qué tipo es cada parte del texto o, si las hay, son distintas para varios documentos.
  • Una línea no puede ser de dos secciones.

El desarrollo y modelado del problema se basa en Named-Entity Recognition (NER), si bien no es el mismo problema su similaridad permite desarrollar la solución final.

NER tagging y formas de etiquetado

NER tagging es un problema de procesamiento de lenguaje natural en el que se tratan de identificar entidades conocidas en el texto. Por ejemplo, nombres de personas, ciudades o empresas, direcciones, fechas, categorías custom (nombres de proyectos o de formularios) y categorías compuestas. La principal diferencia con el problema del cliente es que las entidades de NER suelen ser de unas pocas palabras, mientras que las secciones a identificar están conformadas por varias oraciones.

La forma más común de plantear de NER tagging es como un problema de clasificación de secuencias. El modelo tiene que poder clasificar cada palabra de manera que indique si forma parte de alguna entidad o no, recibiendo una lista de palabras y devolviendo una lista de etiquetas asociadas a cada una.

¿Cómo se pueden etiquetar las secuencias?

Una forma de etiquetado es BIO tagging, se denomina así por las siglas en inglés: Begin, Inside, Outside. Estas etiquetas marcan si una palabra es el principio de una entidad, si forma parte de una entidad o si no pertenece a ninguna.

Por ejemplo, si se quiere extraer entidades de la siguiente frase:

«¿Hay salas disponibles el jueves 21 en alguna de las sucursales de Palermo para ver El cisne negro entre las 18 y las 23:30?»

Suponiendo que las entidades a extraer son: Fecha, Horario, Película, Barrio. Entonces se utilizarán las etiquetas O para outside, BX para el comienzo de la entidad X e IX para indicar que está dentro de la entidad X. Los signos de puntuación e interrogación se consideran como una palabra. Entonces cada palabra quedaría etiquetada de la siguiente manera:

«¿(O) Hay(O) salas(O) disponibles(O) el(O) jueves(BF) 21(IF) en(O) alguna(O) de(O) las(O) sucursales(O) de(O) Palermo(BB) para(O) ver(O) El(BP) cisne(IP) negro(IP) entre(O) las(O) 18(BH) y(O) las(O) 23(BH) :(IH) 30(IH) ?(O)»

Una vez que el modelo realizó el etiquetado, se pueden juntar las palabras que pertenecen a la misma entidad recorriendo las etiquetas. Esto produce el resultado final:

(Fecha: «jueves 21»), (Barrio: «Palermo»), (Película: «El cisne negro»), (Horario: «18»), (Horario: «23:30»)

Existen otros tipos de etiquetados, algunos más simples que solamente consideran si la palabra está dentro de una entidad o fuera y más complejos que agregan etiquetas para indicar el final de las entidades, o etiquetas que indican cuál es la etiqueta que las precedía. Durante el desarrollo de la solución se probaron diferentes tipos de etiquetado y BIO fue el que dio mejores resultados.

Representación de palabras

El modelo que se va a encargar de etiquetar o clasificar cada una de las posibles entradas, para lograr esto se debe definir primero la forma de estas entradas y una representación para cada palabra.

Una alternativa podría ser asociar cada palabra a un identificador otra opción es representar cada palabra con un vector de numero reales (de dimensión mucho menor al vocabulario). Estos últimos se llaman word embeddings, para construirlos se toman muchos textos (del dominio del conocimiento sobre el que luego se van a usar) y se busca mantener cerca la representación de las palabras que aparecen en contextos similares (hipótesis distribucional), capturando su semántica en las diferentes dimensiones.

Modelo simple

Un primer modelo sencillo podría simplemente tomar el word embedding de cada palabra como entrada y buscar predecir una etiqueta. En principio eso podría dar buenos resultados, pero tiene grandes limitaciones,  , ni cual es la estructura de la secuencia que debería resultar. Lo más grave es que cada palabra siempre estaría asociada a un único tag, independientemente de su posición, el modelo siempre devolvería la misma predicción.

Modelo con contexto

Para incorporar el contexto al modelo podemos utilizar una LSTM (Long Short-Term Memory). Este modelo permite recibir una secuencia de largo variable como entrada y obtener una etiqueta por cada entrada. A medida que va procesando cada palabra, va guardando en una memoria interna relaciones entre las palabras. Se puede incorporar una segunda LSTM que lea la oración en sentido inverso para tener las relaciones en ambas direcciones, una biLSTM.

Con este modelo estamos incorporando información del contexto de las palabras a nuestras predicciones, pero ignora la estructura que tienen las etiquetas, como el hecho de que, por ejemplo, una etiqueta Inside siempre tiene que venir desde una etiqueta Inside o una Begin, pero no podría venir de una etiqueta Outside. Tampoco modela cuál es la probabilidad de transicionar entre las diferentes categorías.

Modelo con estructura

Los CRF (Conditional Random Fields) buscan parametrizar las relaciones entre las palabras y las etiquetas, y la forma en que se transiciona entre las diferentes etiquetas. Es un modelo enfocado en la estructura de lo que queremos predecir. Sin embargo, no utiliza información del contexto de las palabras para realizar sus predicciones.

La solución que adoptamos

Finalmente, decidimos obtener el beneficio que brindan los modelos con contexto y con estructura, una solución llamada biLSTM-CRF [https://arxiv.org/pdf/1508.01991v1.pdf]. Para eso, se usó una primera capa de bi-LSTM, con la cual, en vez de buscar predecir las etiquetas, se obtenía una representación de las palabras teniendo en cuenta su contexto. Eso se tomaba como entrada para la CRF que finalmente predecía las etiquetas.

Como decíamos al principio, nuestras secciones eran largas, y teníamos la restricción de que una línea no podía pertenecer a dos secciones diferentes. Entonces, después de clasificar cada una de las palabras se usaba una heurística para determinar a qué categoría pertenecía cada línea. Para mejorar esto último, se usó nuevamente una LSTM por cada línea del texto, pero, en vez de obtener una representación por cada palabra, se buscaba una representación de toda la línea. Luego, con la representación de cada línea se alimentaba la biLSTM-CRF que devolvía una etiqueta por cada línea. Este fue uno de los cambios que tuvo mayor impacto en la mejora de las métricas.

Queremos destacar la importancia del tratar de encontrar problemas similares para poder orientarnos hacia las posibles soluciones. Tratar de incorporar en el modelo la mayor cantidad de aspectos posibles del problema que elijamos e integrar la estructura particular del problema en el modelo fue lo que en este caso, nos ayudó a poder encontrar la mejor solución.

Francisco Lopez Destain

Francisco López Destain es Data Scientist en intive desde abril 2015. Estudiante de Ingeniería Informática de la Universidad de Buenos Aires, es colaborador en la materia «Introducción a los sistemas distribuidos».

Practicante de acrobacia de piso, Francisco tiene por hobbies hacer ejercicio al aire libre, cocinar, jugar ajedrez y participar en juegos de rol grupales.

 

Gianmarco Cafferata

Gianmarco Cafferata fue Data Scientist en intive desde agosto de 2018 hasta abril 2020. Estudiante de Ingeniería en Informática en la Universidad de Buenos Aires (UBA), además se desempeña como ayudante en la materia Algoritmos II en la misma facultad de dicha casa de estudios. Amante del bandoneón, en su tiempo libre Gian se dedica a investigar sobre Data Science y cocinar, sobre todo cosas dulces. Interesado por la economía, la filosofía y la política, lo que más le gusta es salir y charlar con amigos.

Deja un comentario