POS Tagging, WSD y NER

Objetivos

  • Comprender y aplicar el etiquetado gramatical (POS Tagging) en español.

  • Introducir la Desambiguación Semántica de Palabras (WSD).

  • Identificar y extraer Entidades Nombradas (NER).

POS Tagging (Etiquetado de Partes del Discurso)

Asigna etiquetas gramaticales (sustantivo , verbo , artículo , adjetivo , preposición , pronombre , adverbio , etc.) a cada palabra basándose tanto en su definición como en su contexto

Fundamental para análisis sintáctico y semántico posterior.

Catergorías

Open class words Closed class words Other
ADJ ADP PUNCT
ADV AUX SYM
INTJ CCONJ X
NOUN DET  
PROPN NUM  
VERB PART  
  PRON  
  SCONJ  

Más información en este link

¿Cómo funciona?

¿Para qué sirve?

  • Recuperación de información
  • Extracción de información
  • Sistemas de conversión de texto en voz
  • Reconocimiento de entidades nombradas
  • Desambiguación del sentido de las palabras

POS Tagging en R

Vamos a aplicar el etiquetado de partes del discurso (POS Tagging) utilizando un corpus real en español.

Trabajaremos con un dataset que posee las descripciones de proyectos de gobierno abierto llevadas adelante por organismos estatales y sociedad civil.

ejemplo.R

library(readr)
df <- read_csv("https://infra.datos.gob.ar/catalog/jgm/dataset/25/distribution/25.1/download/comunidad-abierta-iniciativas.csv", 
    locale = locale(encoding = "ISO-8859-1"))

Estructura del csv del debate

POS Tagging en R

library(udpipe)
library(tidyverse)

# "spanish-ancora", "spanish-gsd"
modelo_es <- udpipe_download_model(language = "spanish")
modelo <- udpipe_load_model(modelo_es$file_model)

# Anotación
anotado <- udpipe_annotate(modelo, x = df$descripcion)
anotado_df <- as.data.frame(anotado)

Resultado

En feats se pueden ver rasgos morfosintácticos que acompañan al pos

Etiquetas generadas

anotado_df %>%
  drop_na(upos) |> 
  count(upos, sort = TRUE) %>%
  mutate(upos = reorder(upos, n)) %>%
  ggplot(aes(x = upos, y = n)) +
  geom_col(fill = "#6366F1") +
  coord_flip() +
  labs(
    title = "Frecuencia de categorías gramaticales (POS)",
    x = "Categoría gramatical (upos)",
    y = "Frecuencia"
  ) +
  theme_minimal(base_size = 14)

Word sense disambiguation (WSD)

La desambiguación del sentido de las palabras es la capacidad de identificar el significado de las palabras en contexto de forma computacional. En las personas, este proceso parece ser en gran medida inconsciente. En udpipe ya hay una forma básica de WSD basada en lematización y contexto

Word sense disambiguation (WSD)

observo <- anotado_df %>%
  filter(lemma %in% c("abierto")) %>%
  mutate(caracteres = nchar(sentence)) |> 
  arrange(caracteres) |> 
  distinct(upos,.keep_all =T) |> 
  select(token, lemma, upos, sentence)
reactable::reactable(observo)

Named-Entity Recognition (NER)

Es una herramienta del NLP que busca localizar y clasificar las entidades presentes dentro de un texto en un conjunto de categorías predefinidas.

Ayudan a entender el qué, quién y dónde de una serie de documentos.

Tres etiquetas básicas: Personas, Organizaciones y Localizaciones

{spacyr}

Uno de los frameworks más robustos para NLP es spacy, originalmente en Python, tiene su integración en R con {spacyr}.

Modelos en español: paquetes entrenados con corpus lingüísticos

es_core_news_sm → liviano, rápido, buena cobertura general

es_dep_news_trf → basado en Transformers, más preciso pero más pesado

Los modelos se pueden observar en este link

¿Qué es un embedding?

Es forma de representar palabras (o frases) como vectores numéricos en un espacio matemático. Los embeddings ubican las palabras en un espacio multidimensional donde la distancia y dirección entre las palabras tienen significado.

Cada palabra es un vector (una lista de números), por ejemplo: "perro" → [0.21, -1.34, 0.05, ...]

Los vectores son similares para las palabras que se utilizan en contextos similares. Esto significa que los vectores de embeddings pueden utilizarse para determinar la similitud semántica entre las palabras: "perro" estará cerca de "gato" pero lejos de "astronauta"

NER en R

library(spacyr)

# Descargar el modelo
spacy_download_langmodel("es_dep_news_trf")

# Iniciar spacy
spacy_initialize(model = "es_dep_news_trf")

ner <- spacy_extract_entity(df$descripcion)

reactable::reactable(ner)

Recursos