1 of 37

Abriendo y analizando los

Diarios de Sesiones del

Parlamento uruguayo con R

Daniela Vázquez

@d4tagirl

2 of 37

Daniela

Uruguaya

3 of 37

Daniela

Economista

4 of 37

Daniela

Data Scientist (pasado: Idatha, Equifax)

5 of 37

Daniela

R-Ladies

6 of 37

Daniela

NASA Datanaut

7 of 37

Daniela

Pinto :)

8 of 37

Contacto

Twitter: @d4tagirl

Slack:

  • R-Ladies Santa Fé (~ 1 mes)
  • All the R-Ladies (en inglés, pero con canales en español)

Blog: dv.uy

9 of 37

10 of 37

Obtención de datos

R for Data Science

11 of 37

Obtención de datos

Situación en Uruguay: Avanzando con las iniciativas de datos abiertos, pero falta.

Problemas resueltos:

  • Descargar los archivos de las Sesiones de forma sistemática: web scraping.
  • Extraer el texto contenido en los archivos en formato pdf.

: robotstxt, rvest

: pdftools

12 of 37

13 of 37

Scraping: robotstxt

Paquete de rOpenSci.

Normas de etiqueta que es recomendable seguir.

Archivo robots.txt: establece para cada sección del sitio si este uso es adecuado.

robotstxt::get_robotstxt("https://parlamento.gub.uy")

robotstxt::paths_allowed("https://parlamento.gub.uy/documentosyleyes/documentos/diarios-de-sesion")

## [1] TRUE

14 of 37

Scraping: filtros de fecha

date_init <- "01-01-2017"

date_end <- "31-03-2018"

url_diputados <-

paste0("https://parlamento.gub.uy/documentosyleyes/documentos/diarios-de-sesion?Cpo_Codigo_2=D&Lgl_Nro=48&DS_Fecha%5Bmin%5D%5Bdate%5D=",Date_init,

"&DS_Fecha%5Bmax%5D%5Bdate%5D=",

Date_end,

"&Ssn_Nro=&TS_Diario=&tipoBusqueda=T&Texto=")

15 of 37

Scraping: selección del contenido

Las páginas web son archivos html que el navegador interpreta y lo transforma en lo que nosotros vemos.

Forma más intuitiva que encontré para seleccionar el contenido del html al que quiero acceder:

16 of 37

17 of 37

Scraping: rvest

pdfs <- url %>%

rvest::read_html() %>% # lee html

rvest::html_nodes(".views-field-DS-File-IMG a") %>%

# extrae nodo, el que encontré antes! La “a” indica que es hipervínculo

rvest::html_attr("href") %>%

# selecciona el atributo href, que es el link (relativo) al pdf

purrr::map(~ paste0("https://parlamento.gub.uy", .))

# Completa el link para que sea absoluto

18 of 37

Extracción de textos: pdftools

pdfs <- pdfs %>%

purrr::map(~ paste0(pdftools::pdf_text(.), collapse = ' ')) %>%

# extrae texto del pdf y colapsa todas las páginas en un stringpurrr::map(~ stringr::stri_trans_general(

tolower(.), id = "latin-ascii")) %>%purrr::map(~ stringr::stri_replace_all(

., replacement = "", regex = "\\\n")) %>%purrr::map_df(function(pdf) {tibble::tibble(pdf)})

# transformo la lista en un dataframe

19 of 37

Extracción de textos: pdftools

Advertencia!

pdftools::pdf_text() lee los renglones de izquierda a derecha. Relevante para evaluar qué tipo de análisis puedo hacer.

20 of 37

Extracción de textos: pdftools

21 of 37

Análisis de datos

R for Data Science

22 of 37

Análisis de datos

  • Llevar los datos a formato tidy.

  • Exploración de datos:
  • Análisis de texto y sentimiento:

: tidyverse (esp. ggplot2)

: tidytext

: tidytext, ggplot2

23 of 37

Frecuencia mensual de sesiones

zoo::as_yearmon() devuelve mes y año de cada fecha

24 of 37

Extensión de las sesiones: tidytext

# calculo las palabras por mes

sesion_diputados_words_mes <- diputados %>%

tidytext::unnest_tokens(word, pdf) %>%

mutate(mes = as.yearmon(fecha)) %>%

count(mes, sort = TRUE) %>%

ungroup()

# calculo la cantidad de sesiones por mes

cant_sesiones_diputados_mes <- diputados %>%

group_by(mes = as.yearmon(fecha)) %>%

summarise(cant_sesiones = n()) %>%

ungroup()

# los junto

sesion_diputados_words_mes <-

left_join(sesion_diputados_words_mes, cant_sesiones_diputados_mes) %>%

mutate(palabras_prom_sesion = n/cant_sesiones)

25 of 37

Extensión de las sesiones

Más de 15 hs. de sesión:

Interpelación al Ministro del Interior, por situación de extrema violencia en el fútbol.

26 of 37

Análisis de sentimiento: lexicon

Una forma de analizar el sentimiento de un texto es como la suma de los sentimientos asociados a las palabras individualmente consideradas.

Lexicón usado: Veronica Perez-Rosas, Carmen Banea and Rada Mihalcea (2012)

Limitaciones:

  • tiene muy pocos términos (476 palabras positivas de 871 en total);
  • la mayoría (si no todos) los adjetivos que considera son masculinos.

27 of 37

Análisis de sentimiento: tidytext + lexicon

stopwords <- corpora("words/stopwords/es")$stopWords

stopwords_personalizadas <- c(stopwords, "negro", "discusion", "atento",

"consideracion", "especial", "dicha",

"facultades", "atencion", "asunto")

tidy_diputados <- diputados %>%

tidytext::unnest_tokens(word, pdf) %>%

filter(!word %in% stopwords_personalizadas)

tidy_diputados %>%

inner_join(lexicon, by = c("word" = "palabra")) %>%

count(word, sentimiento, sort = TRUE)

28 of 37

Análisis de sentimiento: tidytext + lexicon

29 of 37

Sentimiento por mes:

Renuncia del Vice Presidente Raúl Sendic

Diputados

Senadores

30 of 37

Sesiones más extremas:

Diputados:

Más positivas

Más negativas

Senadores:

Más positivas

Más negativas

31 of 37

¿De qué se habló en las más negativas? tf-idf

term frequency (tf) (frecuencia del término):

qué tan frecuentemente aparece una palabra en la sesión.

inverse document frequency (idf) (inverso de la frecuencia del documento):

reduce el peso a las palabras comúnmente usadas en el total de las sesiones y aumenta el de las que no son muy usadas.

tf-idf = tf * idf:

frecuencia del término, ajustada por qué tan raramente es usado.

Qué tan importante es una palabra para una sesión, en el conjunto de sesiones que estoy analizando.

-“Text mining with R: a tidy approach”, Julia Silge y David Robinson

32 of 37

¿De qué se habló en las más negativas? tf-idf

sesion_diputados_words <- diputados %>%

unnest_tokens(word, pdf) %>%

count(fecha, sesion, fecha_sesion, word, sort = TRUE) %>%

ungroup()

diputados_words <- sesion_diputados_words %>%

group_by(fecha_sesion) %>%

summarize(total = sum(n))

sesion_diputados_tfidf <-

left_join(sesion_diputados_words, diputados_words) %>%

tidytext::bind_tf_idf(word, fecha_sesion, n)

33 of 37

¿De qué se habló en esas sesiones? tf-idf

Interpelación al canciller Nin Novoa por la posición a adoptar ante la crisis venezolana.

interpelación al Ministro del Interior Eduardo Bonomi por extrema violencia en el fútbol.

34 of 37

¿De qué se habló en esas sesiones? tf-idf

Rendición de Cuentas

Derogación de un artículo del Código Penal referido al Abuso de Funciones en casos no previstos especialmente por la ley.

35 of 37

Fin!

Artículos detallados y lectura adicional:

  • dv.uy/text-parlam
  • dv.uy/parlamento

Análisis completo:

  • https://github.com/d4tagirl/uruguayan_parliamentary_session_diary

36 of 37

Contacto

Twitter: @d4tagirl

Slack:

  • R-Ladies Santa Fé (~ 1 mes)
  • All the R-Ladies (en inglés, pero con canales en español)

Blog: dv.uy

37 of 37

Gracias!