Abriendo y analizando los
Diarios de Sesiones del
Parlamento uruguayo con R
Daniela Vázquez
@d4tagirl
Daniela
Uruguaya
Daniela
Economista
Daniela
Data Scientist (pasado: Idatha, Equifax)
Daniela
R-Ladies
Daniela
NASA Datanaut
Daniela
Pinto :)
Contacto
Twitter: @d4tagirl
Slack:
Blog: dv.uy
Obtención de datos
R for Data Science
Obtención de datos
Situación en Uruguay: Avanzando con las iniciativas de datos abiertos, pero falta.
Problemas resueltos:
: robotstxt, rvest
: pdftools
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
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=")
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:
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
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 string� purrr::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
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.
Extracción de textos: pdftools
Análisis de datos
R for Data Science
Análisis de datos
: tidyverse (esp. ggplot2)
: tidytext
: tidytext, ggplot2
Frecuencia mensual de sesiones
zoo::as_yearmon() devuelve mes y año de cada fecha
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)
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.
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:
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)
Análisis de sentimiento: tidytext + lexicon
Sentimiento por mes:
Renuncia del Vice Presidente Raúl Sendic
Diputados
Senadores
Sesiones más extremas:
Diputados:
Más positivas
Más negativas
Senadores:
Más positivas
Más negativas
¿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
¿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)
¿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.
¿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.
Fin!
Artículos detallados y lectura adicional:
Análisis completo:
Contacto
Twitter: @d4tagirl
Slack:
Blog: dv.uy
Gracias!