El siguiente documento es un análisis exploratorio realizado sobre un corpus de noticias extraído de medios digitales por Tomás Maguire para su tesina de grado “Aprendizaje automático y modelización de tópicos: un estudio de caso sobre la agenda mediática en contexto de las elecciones Argentina 2015”. El mismo consta de una muestra aleatoria de noticias de los diarios Clarín, La Nación, Perfil, Minuto Uno, Télam, Infobae y Página12 entre enero de 2015 y diciembre de 2016. Los objetivos del análisis serán ver el comportamiento general de cada medio, en función de las palabras más utilizadas o con mayor relevancia para cada uno, la cantidad de noticias producidas en el período y tono general de las noticias. Además se intentará determinar tópicos que desarrollan los medios, las palabras más importantes para cada uno de éstos y la evolución en el tiempo de los mismos. Por último, teniendo en cuenta que el corpus de noticas corresponde al período de elecciones presidenciales de 2015, se intentará extraer las noticias que mencionan a los precandidatos presidenciales y analizar la cobertura mediática que tuvieron. Para cada uno de estos objetivos, se utilizarán diversas técnicas de procesamiento de datos englobadas en lo que se conoce como text mining o minería de texto.
Primero cargo las librerías que voy a utilizar.
library(tidyverse)
library(lubridate)
library(tidytext)
library(stm)
## Warning: package 'stm' was built under R version 4.1.3
library(tictoc)
library(stringi)
Levanto la base de datos, hago un poco de exploración y la dejo lista para usar.
#1 Cargo data y seteo colores####
colores_positividad<-c("Positivo"="green",
"Neutral"="grey",
"Negativo"="red")
base<-read.csv("./data/o2_corpus_noticias_editado.csv", encoding = "UTF-8")
#exploro el dataset
glimpse(base)
## Rows: 7,000
## Columns: 9
## $ id <int> 32736, 204945, 480563, 124569, 364645, 217227, 405041, 33681, 3~
## $ url <chr> "http://www.infobae.com/2016/02/28/1793290-sigue-abandonado-el-~
## $ fecha <chr> "2016-02-28", "2016-01-15", "2016-05-05", "2015-08-19", "2016-0~
## $ ano <int> 2016, 2016, 2016, 2015, 2016, 2016, 2015, 2016, 2015, 2016, 201~
## $ mes <int> 2, 1, 5, 8, 8, 6, 4, 2, 12, 1, 1, 4, 12, 9, 6, 3, 9, 11, 9, 7, ~
## $ dia <int> 28, 15, 5, 19, 14, 17, 16, 27, 11, 20, 24, 12, 9, 10, 15, 7, 11~
## $ medio <chr> "Infobae", "Clarín", "MinutoUno", "Infobae", "La Nación", "Clar~
## $ titulo <chr> "Sigue abandonado el sitio histórico de tango que la Ciudad pro~
## $ texto <chr> "Este chalet, ubicado en los bosques de Palermo, a escasos metr~
max(base$fecha)
## [1] "2016-12-31"
min(base$fecha)
## [1] "2015-02-19"
length(unique(base$titulo)) #para ver si hay noticias repetidas, puede tardar algo de tiempo
## [1] 6624
#quito noticias duplicadas según título y agrego un nuevo id en serie
base<-base%>%filter(!duplicated(titulo))%>%
mutate(id=row_number())
#acomodo variables
base_limpia<-base%>%mutate(fecha=ymd(fecha),
medio=as.factor(medio),
mes_ano=round_date(fecha,unit="month"))
Primero vamos a normalizar las variables que contengan texto.
base_limpia<-base_limpia%>% #limpio la base
mutate(titulo= str_to_lower(titulo), #llevo todo a minúsculas
titulo= stri_trans_general(titulo, "Latin-ASCII"),#una forma rápida de quitar acentos y ñ
titulo= str_replace_all(titulo, "[[:punct:]]", ""), #reemplazo puntuaciones
titulo= str_replace_all(titulo, "[[:digit:]]+", ""))%>%#reemplazo dígitos
mutate(texto= str_to_lower(texto), #llevo todo a minúsculas
texto= stri_trans_general(texto, "Latin-ASCII"),#una forma rápida de quitar acentos y ñ
texto= str_replace_all(texto, "[[:punct:]]", ""), #reemplazo puntuaciones
texto= str_replace_all(texto, "[[:digit:]]+", ""))#reemplazo dígitos
Segundo vamos a ver si hay frases repetidas que puedan “ensuciar” los posteriores análisis.
# frases_para_eliminar<-base_limpia%>%
# unnest_tokens(word, texto, token = "ngrams", n=7)%>%
# group_by(id, medio,word)%>%
# summarise(n=n())%>%
# arrange(desc(n))
#podemos ir modificando el n para generar ngrams más largos o más cortos y ver las frases repetidas, luego las guardamos como un vector
frase_repe_ln<-c("comentar me gusta me gusta compartir email twitter facebook whatsapp guardar")
# base_limpia$texto[5]
frase_repe_clarin<-c("camino a las elecciones lo que tenes que saber hoy del oficialismo y la oposicion de lunes a viernes recibir newsletter")
# base_limpia$texto[57]
frase_repe_clarin2<-c("newsletters clarin que paso hoy | te contamos las noticias mas importantes del dia y que pasara manana cuando te levantes de lunes a viernes por la tarde recibir newsletter")
# base_limpia$texto[10]
frase_repe_clarin3<-c("newsletters clarin lo que tenes que saber hoy | las noticias mas importantes del dia para leer en diez minutos de lunes a viernes por la manana recibir newsletter")
# base_limpia$texto[2] #para chequear si se borró
frase_repe_perfil<-c("por redaccion perfil")
# base_limpia$texto[11] #para chequear si se borró
Una vez que encontramos estas frases, las borramos del texto del corpus
base_limpia<-base_limpia%>%
mutate(texto=str_replace_all(texto,frase_repe_ln,""),
texto=str_replace_all(texto,frase_repe_perfil, ""),
texto=str_replace_all(texto, frase_repe_clarin, ""),
texto=str_replace_all(texto,frase_repe_clarin2, ""),
texto=str_replace_all(texto,frase_repe_clarin3, ""))
Veamos la producción de noticias por medio.
plot_1_actividad<-ggplot(base_limpia%>%
group_by(medio,mes_ano)%>%
summarise(cantidad=n())%>%
ungroup(),
aes(x=mes_ano, y=cantidad, color=medio))+
geom_line(size=1)+
theme_minimal()+
labs(x="", y="Cantidad",title = "Cantidad de noticias por medio", subtitle = "Gráfico 1")
plot_1_actividad
Como se observa en el Gráfico 1, la muestra de noticias indica que el medio con mayor producción de noticias digitales es Clarín, sólo superado en algunos meses por La Nación, mientras que el medio con menor producción de noticias es Minuto Uno. Por otro lado, los meses con más cantidad de noticias fueron mayo y junio de 2016 (339 y 333 respectivamente).
base_limpia%>%
group_by(medio)%>%
summarise(cantidad=n())
## # A tibble: 7 x 2
## medio cantidad
## <fct> <int>
## 1 Clarín 1438
## 2 Infobae 878
## 3 La Nación 1284
## 4 MinutoUno 594
## 5 Página 12 705
## 6 Perfil 782
## 7 Télam 943
Vamos a tratar de ver las palabras más representativas para cada medio. Lo primero que necesitamos hacer es filtrar del corpus las palabras más comunes. Para esto cargamos un diccionario de palabras comunes en español y además agregamos algunas que sabemos que están muy repetidas en el corpus.
stop_words <- read_csv('https://raw.githubusercontent.com/Alir3z4/stop-words/master/spanish.txt', col_names=FALSE) %>%
rename(word = X1) %>%
mutate(word = stringi::stri_trans_general(word, "Latin-ASCII"))%>%
bind_rows(tibble(word=c('ano', 'anos',"embed", "minutounocom", "minutouno", "perfilcom","newsletter","newsletters", "ratingcerocom", "quey", "jpg", "infobaetv")))
Ahora vamos a ordenar en formato tidy (una fila por palabra) la base de noticias y ya eliminaremos las palabras poco interesantes.
base_limpia_tidy<-base_limpia%>%
unnest_tokens(input = texto, output = word)%>%
anti_join(stop_words)
Para ver las palabras más representativas de cada medio usaremos el indicador tf_idf. Este indicador es la combinación de otros dos indicadores. El primero se utiliza para medir la frecuencia de cada término, el “tf” (term frequency por sus siglas en inglés). Si bien la frecuencia en la que se utiliza un término es una variable interesante, puede no mostrar la relevancia de las palabras para cada medio, por ejemplo la palabra “información” podría utilizarse muy frecuentemente y de esta manera tener un “tf” alto, pero nada nos indicaría de la importancia del término para cada medio. Aquí es cuando entra en juego el segundo indicador, que mide la importancia de cada término en cada documento (noticia) o, en otras palabras, mide la informatividad de los términos, y se denomina el “idf” (inverse document frecuency por sus siglas en inglés). Al combinar estos dos indicadores obtenemos el “tf_idf”, que ajusta la frecuencia de cada término por su importancia en cada medio.
base_limpia_tfidf<-base_limpia_tidy%>%
group_by(medio, word)%>%
summarise(cantidad=n())%>%
bind_tf_idf(word,medio,cantidad)
plot_2_palabras_tfidf<-ggplot(base_limpia_tfidf%>%
group_by(medio)%>%
slice_max(n = 15, order_by = tf_idf)%>%
ungroup(),
aes(x=reorder(word, tf_idf), y=tf_idf, fill=medio))+
geom_col()+
coord_flip()+
facet_wrap(~medio, scales = "free")+
theme_minimal()+
theme(legend.position = "none")+
labs(x="", title = "Palabras más representativas de cada medio", subtitle = "Gráfico 2")
plot_2_palabras_tfidf
Para quedarnos tranquilos, veamos las palabras más utilizadas por cada medio, sin utilizar ningún indicador.
base_limpia_tidy_conteo<-base_limpia_tidy%>%
group_by(medio, word)%>%
summarise(cantidad=n())%>%
slice_max(n=15, order_by = cantidad)
plot_2_palabras_conteo<-ggplot(base_limpia_tidy_conteo,
aes(reorder(word, cantidad), cantidad, color=medio))+
geom_pointrange(aes(ymin=0, ymax=cantidad))+
coord_flip()+
theme_minimal()+
facet_wrap(~medio, scales = "free")+
labs(x="", title = "Cantidad de palabras por diario")
plot_2_palabras_conteo
Veamos el tono general de las noticias. Este tipo de análisis se conoce como “sentiment análisis” y consiste en comparar los términos utilizados en cada noticia contra un lexicón de términos preclasificados (en este caso según su positividad). De esta manera se obtiene la cantidad de palabras de cada noticia que se corresponden con tonos positivos, neutros o negativos. Para la presente clasificación se utilizó un lexicón creado por Agustín Gravano del Laboratorio de Inteligencia Artificial Aplicada de la UBA. Como podemos observar, el tono de los medios varía poco entre sí.
#cargamos el lexicón y recodificamos variables
sentiment_words_liia <- read_csv('./data/sentiment_lexicon_liia.csv')%>%
mutate(sentiment = case_when(
round(mean_likeness) == 1 ~ 'Negativo',
round(mean_likeness) == 2 ~ 'Neutral',
round(mean_likeness) == 3 ~ 'Positivo'))
#juntamos el lexicón con la base de datos y nos quedamos sólo con las palabras que tienen valoración
base_limpia_tidy_sentiment<-base_limpia_tidy%>%
inner_join(sentiment_words_liia)%>%
group_by(medio, sentiment)%>%
summarise(cantidad=n())%>%
mutate(total=sum(cantidad),
porcentaje=cantidad/total*100)
plot_3_sentiment_general<-ggplot(base_limpia_tidy_sentiment,
aes(medio, porcentaje, fill=sentiment))+
geom_bar(stat="identity", position = "stack")+
theme_minimal()+
scale_fill_manual(values = colores_positividad)+
scale_y_continuous(labels=scales::percent_format(scale = 1))+
coord_flip()+
labs(x="",
y="",
title = "Positividad de las noticias",
subtitle = "Gráfico 3")
plot_3_sentiment_general
Una de las aplicaciones más interesantes en text mining consiste en el modelado de tópicos. El objetivo de esta técnica es encontrar temas en los textos, sin necesidad de tener que leerlos todos previamente, para de esta manera poder agruparlos (entre otras operaciones). Esto es especialmente útil para clasificar grandes volúmenes de textos y poder trabajar con porciones menores que sean relevantes para lo que estamos investigando o analizando. Hay varios métodos para generar modelos de tópicos, en el presente trabajo se utilizó el STM (Structural Topic Modeling por sus siglas en inglés). Este método es útil en función de que toma en cuenta covariables a la hora de definir tópicos, en el presente trabajo se incluyó como covariable el medio al que pertenece la noticia.
#primero vamos a armar un dataframe con las palabras más repetidas
word_counts<-base_limpia_tidy%>%
group_by(id,word)%>%
summarise(n=n())%>%
ungroup()
#segundo vamos a generar el df al cual le vamos a pasar el modelado, algo así como el segundo nivel de análisis
metadata<-base_limpia%>%
select(id, medio)%>%
distinct() %>%
left_join(base %>% select(id, texto))
#tercero vamos a pasar la base general sobre la que vamos a modelar, pero en un formato particular
base_limpia_dfm<-word_counts%>%
cast_dfm(id, word, n)
Una vez que tenemos los elementos necesarios para crear el modelo, procedemos de la siguiente manera. Este paso puede tardar algo de tiempo, por lo que una vez ejecutado es conveniente guardar el modelo
# tic()
# stm_10_b <- stm(documents = base_limpia_dfm,
# K = 15,
# prevalence = ~ medio,
# max.em.its = 50,
# data = metadata,
# init.type = "Spectral")
# write_rds(stm_10_b, './models/stm_10_b_cont.rds')
# toc()
stm_10_b<-read_rds("./models/stm_10_b_cont.rds")
Una vez creado el modelo, vamos a generar dos dataframes que nos servirán para empezar a indagar los temas de las noticias. En el primer objeto voy a traer las palabras de las noticias, y el valor de importancia de esa palabra para cada tópico, asignado por el modelo. Esto quiere decir que el valor “beta”, indica la relevancia de esa palabra para el tópico en cuestión. Cada palabra pertenece a cada tópico pero con una valoración diferente, por ejemplo la palabra “gobierno” podría tener un valor beta alto para un tópico referido a “Política” pero un valor beta bajo para un tópico referido a “Cocina”.
betas_stm <- tidy(stm_10_b, matrix='beta')
En el segundo objeto, voy a traer las noticias (identificadas por la variable “document”) y el valor de cada tópico para cada noticia. Cada noticia puede pertenecer a cada tópico, pero en valores diferentes. Por ejemplo, una noticia que hable sobre la conformación del gabinete nacional, es pobable que tenga un valor “theta” alto para el tópico “Política” y un valor theta bajo para el tópico “Cocina”.
doc_2_topics_stm <- tidy(stm_10_b, matrix='theta')
Ahora viene la parte interesante del modelado de tópicos: la interpretación. Hay varias formas de interpretar la información que nos dio el modelado. Primero vamos a ver las palabras más importantes para cada tópico.
betas_stm_grup<-betas_stm %>%
group_by(topic) %>%
slice_max(beta, n = 15) %>%
ungroup() %>%
arrange(topic, -beta)%>%
mutate(term = reorder_within(term, beta, topic))
plot_4_topicos_palabras<-ggplot(betas_stm_grup,
aes(beta, term, fill = factor(topic)))+
geom_col(show.legend = FALSE) +
facet_wrap(~ topic, scales='free_y') +
scale_y_reordered() +
theme_minimal()+
labs(y="",
title = "Téminos más utilizados por tópico",
subtitle = "Gráfico 4")
plot_4_topicos_palabras
Con este primer paso, algunos tópicos son fáciles de etiquetar: 1= ????????? 2= economia y produccion 3= arte y cultura 4= relaciones internacionales 5= familia 6= elecciones presidenciales 7= ???????? 8= tecnologia y redes sociales 9= poder judicial 10= deportes 11= economia y trabajo 12= seguridad 13= arte y cultura 14= elecciones USA 15= obra publica o ?????????
Veamos si podemos definir los topics que no estamos seguros a que refieren o que son parecidos a otros
labelTopics(stm_10_b)
## Topic 1 Top Words:
## Highest Prob: clarin, mira, mundo, recibir, dia, newsletter, newsletters
## FREX: runa, sbase, ninh, thuan, xian, organices, taxistas
## Lift: abarcarla, abascal, abatida, abera, aberdeen, abisales, aborrecible
## Score: runa, uber, organices, finde, taxistas, newsletter, newsletters
## Topic 2 Top Words:
## Highest Prob: millones, ciento, mercado, dolares, precios, sector, argentina
## FREX: interanual, precios, exportaciones, trimestre, indec, us, merval
## Lift: abecebcom, acabio, acara, aceros, agrodindustria, amaggi, analytica
## Score: inflacion, precios, dolar, monetaria, tasas, interanual, trimestre
## Topic 3 Top Words:
## Highest Prob: arte, museo, ciudad, artistas, artista, musica, san
## FREX: escultura, museo, museos, emmy, arte, fuegos, retrato
## Lift: abailartour, abandonadasincluyendo, abango, abaporu, abarrotaron, abatiera, abecassis
## Score: arte, artista, artistas, museo, musica, vestido, museos
## Topic 4 Top Words:
## Highest Prob: presidente, pais, gobierno, paises, unidos, venezuela, politica
## FREX: rousseff, farc, pt, corbyn, dilma, eln, cunha
## Lift: alape, alca, alteridad, antiimperialistas, aterrice, aymara, baduel
## Score: rousseff, dilma, ue, venezuela, maduro, refugiados, farc
## Topic 5 Top Words:
## Highest Prob: vida, dia, familia, gente, mujer, casa, madre
## FREX: bailando, pampita, fidel, dije, fede, ratingcerocom, vos
## Lift: abrazarse, acercarme, agradecerle, alcoberro, aliviada, anteojito, aortica
## Score: pampita, tinelli, amor, fidel, bailando, barbie, lali
## Topic 6 Top Words:
## Highest Prob: macri, gobierno, presidente, frente, scioli, candidato, cristina
## FREX: pj, scioli, randazzo, intendentes, fpv, oficialismo, ucr
## Lift: aceptaria, adversaria, aglutinar, andreis, antikirchnerista, anularia, aritmetico
## Score: macri, scioli, massa, diputados, fpv, electoral, oficialismo
## Topic 7 Top Words:
## Highest Prob: papa, francisco, educacion, argentina, personas, pais, mujeres
## FREX: pontifice, bergoglio, obispos, educativa, arzobispo, vaticano, alumnos
## Lift: bergoglio, aadeja, aalmiron, abajarse, abalanzaron, abandonolos, abboud
## Score: vaticano, papa, pontifice, bergoglio, iglesia, obispos, misa
## Topic 8 Top Words:
## Highest Prob: informacion, datos, sistema, internet, mundo, seguridad, tecnologia
## FREX: pasibles, usuario, google, comentar, comentario, software, windows
## Lift: bielorruso, cifrados, clean, cofundadores, cortana, discover, easa
## Score: apple, windows, usuario, violatorio, pasibles, reglamento, google
## Topic 9 Top Words:
## Highest Prob: justicia, juez, fiscal, causa, federal, caso, judicial
## FREX: baez, bonadio, casanello, casacion, corradi, hotesur, ercolini
## Lift: camaristas, casacion, ercolini, aassa, abalanzarse, abarcaban, abbona
## Score: juez, baez, fiscal, bonadio, nisman, casanello, tribunal
## Topic 10 Top Words:
## Highest Prob: carrera, final, equipo, partido, m, minutos, argentina
## FREX: rosberg, hinchas, bull, octavos, masters, djokovic, pella
## Lift: activ, adelantandose, alario, alcanzapelotas, amonestacion, andorra, aprevide
## Score: haz, rosberg, afa, gol, clic, arquero, campeon
## Topic 11 Top Words:
## Highest Prob: gobierno, argentina, trabajadores, pais, millones, ley, ministro
## FREX: griesa, schmid, micheli, gremios, tarifas, tarifa, cgt
## Lift: aamopba, abaclat, abandonarlo, abappra, abaratados, abarcadoras, abarcativa
## Score: inflacion, cgt, griesa, tarifas, bonos, holdouts, salarial
## Topic 12 Top Words:
## Highest Prob: policia, seguridad, personas, ciudad, casa, zona, victima
## FREX: efectivos, heridos, policia, delincuentes, comisaria, policias, policiales
## Lift: abaaoud, abrini, akar, alcayaga, alepo, alertados, alexandrov
## Score: policia, ei, detenidos, homicidio, detenido, siria, delincuentes
## Topic 13 Top Words:
## Highest Prob: libro, historia, obra, vida, musica, argentina, libros
## FREX: novela, cervantes, poesia, literatura, malbec, poeta, novelas
## Lift: aae, aalen, ababa, abacai, abadia, abandonarla, abatte
## Score: poesia, literatura, novela, musica, teatro, poeta, escritor
## Topic 14 Top Words:
## Highest Prob: trump, the, personas, clinton, mujeres, vida, salud
## FREX: placebo, glaucoma, clinton, that, hillary, electroshock, hampshire
## Lift: advertising, ahf, ahorcamiento, andrews, antimonio, arya, boss
## Score: trump, clinton, hillary, the, prince, democrata, donald
## Topic 15 Top Words:
## Highest Prob: agua, ciudad, provincia, zona, rio, servicio, nacional
## FREX: nublado, meteorologico, dengue, crecida, smn, zika, hectareas
## Lift: aapresid, abirl, abramovay, abrasiones, abrasiva, abstuviera, abundanciasobre
## Score: nublado, lluvias, dengue, meteorologico, smn, zika, inundaciones
La función labelTopics() nos muestra las palabras más importantes de cada tópico. El primer grupo de palabras correponde a las más frecuentes para ese tópico (son las que vemos en el Gráfico 4). El segundo grupo de palabras correponde a las palabras exclusivas de ese tópico, es decir, aquellas que son específicas para ese tema. De esta manera, podemos ver que el topic2 tiene que ver con economia, finanzas y producción mientras que el topic11 está má relacionado a economía, trabajo y/o gremiales. También podemos ver que el topic3 refiere a arte y música mientras que el topic13 a arte y literatura. Sin embargo hay 3 tópicos que todavía no son muy claros. Tratemos de avanzar un poco más. Usando la función findThoughts() podemos llamar las noticias con mayor theta de cada tópico y evaluar de qué están hablando.
#TOPIC 1
findThoughts(stm_10_b,
texts=metadata%>%
mutate(texto = str_sub(texto, 1, 300))%>%
select(texto) %>%
pull(),
n=10,
topics=1)
##
## Topic 1:
## Aunque el Homo Erectus, hace 2,5 millones de años, estaba protegido por un pelaje particularmente denso, ése ya no fue el caso del Homo Sapiens. Este "mono desnudo" (Desmond Morris) habría perdido la mayor parte de su pelambre al exponerse al calor de la sabana, para ayudar a la piel a respirar... E
## Aunque suene poco profesional, y tal vez lo sea, estamos fascinados como chicos en lo que podríamos llamar, sin ser exagerados, la isla del tesoro. La Biblioteca Nacional entera es un tesoro; imaginen, entonces, la Sala del Tesoro de la Biblioteca, donde están las joyas más antiguas, raras y valiosa
## Las Runas Vikingas -cuyo nombre significa “Secreto”- constituyen una de las formas más antiguas que se conocen del alfabeto escandinavo, y su origen se remonta a la Edad de Bronce y, tal vez incluso, a etapas anteriores. Los pueblos nórdicos (hoy Suecia, Noruega, Dinamarca, Finlandia e Islandia) uti
## Aunque quizás esté de más, pero empecemos por el principio. El sexo oral es la acción de lamer, besar, mordisquear, succionar o chupar los genitales de nuestra pareja sexual. Cuando es el hombre el que lo recibe se llama felación, y si es la mujer que lo recibe es un cunnilingus. Podemos realizarlo
## Aries Signo Cardinal, de Fuego Regente: Marte La mujer de Aries es activa, pasional, emprendedora e independiente, muy trabajadora y con gran capacidad de gestión. Valiente, le gusta luchar por los derechos de otros. Es combativa, entusiasta, incansable y apasionada por su trabajo, pero le falt
## Cuando de belleza se trata, los famosos no tienen límite y pueden llegar a experimentar todo tipo de tratamientos, técnicas o terapias, sin importar que resulten dolorosos, extravagantes o que impliquen vencer un rechazo inicial. El objetivo es lograr a cualquier precio el tan deseado rejuvenecimien
## Lo Más Trendy 1-¿Qué tipo de ropa preferís? a. Piezas separadas, cómodas, que combinen bien y sean fáciles de cuidar Newsletters Clarín Entremujeres | El horóscopo semanal, moda, bienestar, pareja, género y todo lo que te interesa Todos los miércoles. Recibir newsletter b. Piezas atemporales, de
## Los zapatos de tacos altos de tetillas masculinas, parte de la obra de Costantino Human Furriery En Nueva York, la artista rosarina tuvo un insólito intercambio con la mayor exponente del body art, la inefable Louise Bourgeois Loreley Gaffoglio SEGUIR Comentar Me gusta Me gusta Compartir E-mail Tw
## Uno de mis relatos históricos preferidos acerca del beso proviene del libro de 1864, África salvaje. El explorador británico William Winwood Reade describió su enamoramiento de la hermosa hija de un rey africano. Después de buscarla durante muchos meses, se atrevió a robarle un beso. La joven, que n
## Ya no se sabe si lo encontraron tirado en la playa o flotando en medio del mar. Lo cierto es que, hace cincuenta años, el arquitecto más famoso del mundo apareció ahogado en Cap-Martin, un balneario del sur de Francia. This browser does not support the iframe element. Newsletters Clarín ¿Qué hac
Pareciera ser que el topic1 es el tópico mas heterogéneo de todos, le vamos a poner Cultura General/Misceláneas.
#TOPIC 15
findThoughts(stm_10_b,
texts=metadata%>%
mutate(texto = str_sub(texto, 1, 300))%>%
select(texto) %>%
pull(),
n=10,
topics=15)
##
## Topic 15:
## La prevención de las picaduras de animales ponzoñosos y mordeduras de roedores es el eje de la prevención en materia sanitaria y hacia allí se dirigen los refuerzos en antibióticos y sueros antiofídicos que proveen las provincias y la Nación a los más de 20.000 pobladores afectados por las inundacio
## Se trata de un fruto que prefiere las altas temperaturas para desarrollarse de manera óptima. Tips para incluirlo con éxito en la huerta. Ver Galería El cultivo de zapallito redondo de tronco. El zapallito de tronco (Cucurbita maxima var. zapallito) es un cultivo de verano, tropical, muy sensible
## Importante descubrimiento en el planeta rojo "Nuestra misión en Marte ha sido la de 'seguir el agua' en nuestra búsqueda de vida en el universo, y ahora tenemos convencimiento científico que valida lo que hemos sospechado durante mucho tiempo"” John Grunsfeld, administrador asociado de la NASA La
## SOCIEDAD › UN TEMPORAL PROVOCO INCONVENIENTES EN BARILOCHE Y SAN MARTIN DE LOS ANDES La fuerte lluvia ocasionó inundaciones en algunas calles y viviendas de Bariloche. Algunos edificios de la base del cerro Catedral fueron afectados. Un alud provocó el corte de la Ruta 40 hacia El Bolsón. En San Ma
## Las ráfagas podrían alcanzar los 85 kilómetros por hora; se espera baja sensación térmica y hoy dejaría de llover Comentar Me gusta Me gusta Compartir E-mail Twitter Facebook WhatsApp Guardar 14 de septiembre de 2016 • 07:08 Después de dos días con tormentas, la jornada del miércoles llega con poc
## Las lluvias seguirán hasta el miércoles, informó el Servicio Meteorológico Nacional Fuente: LA NACION Se esperan chaparrones durante toda la jornada, con una temperatura estimada entre los 8 y los 12 grados Comentar Me gusta Me gusta Compartir E-mail Twitter Facebook WhatsApp Guardar 5 de septiemb
## Cientos de familias permanecen aisladas por el agua en el sudoeste provincial y las lluvias no cesan; las 3000 hectáreas desmontadas para destinarlas a soja, entre las más perjudicadas por el temporal Fabián López SEGUIR Comentar Me gusta Me gusta Compartir E-mail Twitter Facebook WhatsApp Guardar
## El incendio se inició esta mañana cerca de la zona de arroyo la Cascada, una zona de difícil acceso donde no hay caminos vehiculares y no está permitida la circulación, informó el Ministerio de Ambiente de la Nación en un comunicado.Las condiciones climáticas, indicaron, son "ideales" para que las l
## Las cuatro personas afectadas habían viajado al exterior; en la provincia de Córdoba se confirmaron 34 en lo que va del año José E. Bordón SEGUIR Comentar Me gusta Me gusta Compartir E-mail Twitter Facebook WhatsApp Guardar 9 de abril de 2015 • 18:22 SANTA FE.- El cuarto caso de dengue confirmado
## Las Heras, una de las zonas más afectadas por el zonda Crédito: @lasherasmza Las zonas más comprometidas son Maipú, Las Heras y Guaymallén Comentar Me gusta Me gusta Compartir E-mail Twitter Facebook WhatsApp Guardar 1 de noviembre de 2016 • 11:45 El fuerte viento zonda que afectó a una amplia re
Pareciera que el topic15 está relacionado a temas sobre Clima y Naturaleza y no sobre Obra Pública.
#TOPIC 7
findThoughts(stm_10_b,
texts=metadata%>%
mutate(texto = str_sub(texto, 1, 300))%>%
select(texto) %>%
pull(),
n=10,
topics=7)
##
## Topic 7:
## Más de 800.000 personas asistieron a la ceremonia religiosa, bajo un clima abrasador; en el segundo día de la gira por América latina, pidió mayor asistencia social; luego visitó uno de los santuarios marianos más importantes del país Elisabetta Piqué SEGUIR Comentar Me gusta Me gusta Compartir E-m
## Ante centenares de miles de fieles fervorosos, el Papa Francisco pidió ayer a todos los estamentos de la sociedad que ayuden y potencien a la familia frente a la crisis que atraviesa porque ésta “constituye la gran 'riqueza social' que otras instituciones no pueden sustituir”. Y consideró que esa co
## En una emotiva homilía durante la misa de Gallo, el papa Francisco criticó que "la mundanidad tomó de rehén a la Navidad" y en la víspera de Nochebuena pidió por los niños que deben "escapar de los bombardeos", los que yacen "en el fondo de una barcaza repleta de migrantes" y por aquellos a "los que
## El papa Francisco bendijo hoy el palio a monseñor Eduardo Eliseo Martín, de Rosario, uno de los 46 nuevos arzobispos nombrados este año por el pontífice. "Queridos arzobispos, el palio que hoy recibís es un signo que representa la oveja que el pastor lleva sobre sus hombros como Cristo, Buen Past
## misa jueves santos papa La misa de hoy también rememora "el día de la institución del sacerdocio" y por ello la homilía del Papa, como en anteriores Jueves Santos, estuvo dedicada a los consejos para los sacerdotes y a la "belleza" del cansancio por dedicarse a los fieles.El pontífice argentino Jor
## La iniciativa surgió de la constatación de que muchas integrantes de este colectivo, tras haber perdido a sus hijos, se encuentran en el presente sin contención familiar o social en sus casas o en las instituciones geriátricas donde viven. “Nosotros desde comienzos de año empezamos a trabajar par
## familias reunidas comiendo locro familias reunidas comiendo locro familias reunidas comiendo locro familias reunidas comiendo locro familias reunidas comiendo locro familias reunidas comiendo locro familias reunidas comiendo locro familias reunidas comiendo locro familias reunidas comiendo
## El papa Francisco continuará este viernes con el rito de Semana Santa y celebrará el día de la Pasión en la Basílica de San Pedro del Vaticano. Lo hará algunas horas antes de presidir, desde la colina del Palatino, el Vía Crucis en el Coliseo romano, que fue instaurado en 1741 por el papa Benedicto
## Rompebochos es un evento impulsado por 18 ONG que apuestan a la educación de jóvenes en situación de vulnerabilidad. Con testimonios de chicos que lograron cumplir sueños que parecían imposibles de alcanzar, buscó inspirar a jóvenes para que continúen estudiando y puedan mejorar su calidad de vida.
## El encuentro convoca a mujeres de todo el país Crédito: ENM La manifestación del 31º encuentro termina en el Monumento a la Bandera Comentar Me gusta Me gusta Compartir E-mail Twitter Facebook WhatsApp Guardar 9 de octubre de 2016 • 17:52 Miles de manifestantes marchaban desde las 18 por las call
Por último el topic7 pareciera referirse a cuestiones religiosas y de DDHH. Increíblemente se encuentra una noticia sobre el Encuentro Nacional de la Militancia en el mismo tópico que menciona al Papa.
Ahora, una vez que ya pudimos definir una etiqueta para cada tópico, terminemos de ponerle los labels a cada uno, rearmemos nuestra base de datos y veamos la distribución de los mismos en cada medio.
doc_2_topics_stm_full <- doc_2_topics_stm %>%
rename(id=document) %>%
left_join(base_limpia)%>%
mutate(label_topico= case_when(topic==1 ~ "Misceláneas",
topic==2 ~ "Economáa y Producción",
topic==3 ~ "Musica y Cultura",
topic==4 ~ "Relaciones Internacionales",
topic==5 ~ "Familia",
topic==6 ~ "Elecciones Presidenciales",
topic==7 ~ "Religión",
topic==8 ~ "Tecnología y redes sociales",
topic==9 ~ "Poder Judicial",
topic==10 ~ "Deportes",
topic==11 ~ "Economía y trabajo",
topic==12 ~ "Seguridad",
topic==13 ~ "Arte y literatura",
topic==14 ~ "Elecciones USA",
topic==15 ~ "Clima y Naturaleza"),
topic=as.factor(topic))
topicos_segun_medio<-doc_2_topics_stm_full%>%
group_by(medio,topic, label_topico) %>%
summarise(mean = mean(gamma)) %>%
ungroup()%>%
drop_na()
plot_5_topic_medio<-ggplot(topicos_segun_medio,
aes(x=reorder(topic, mean), y=mean, fill=label_topico)) +
geom_bar(stat="identity", position='dodge') +
facet_wrap(~medio, scales = "free_y") +
theme_minimal()+
theme(axis.text.x = element_blank())+
labs(y="",
title = "Tópicos por medio",
subtitle = "Gráfico 5")
plot_5_topic_medio
Como podemos ver en el Gráfico 5, el tópico “Elecciones presidenciales” tiene alto porcentaje de noticias, siendo el más importante para los diarios Télam, Perfil, Página12, La Nación y Clarín. En el caso del diario Infobae, el tópico más importante es Relaciones Internacionales, seguido por Seguridad, mientras que para el diario Minuto Uno el tópico más importante es Seguridad, seguido por Familia. El tópico Misceláneas tiene algo de importancia para el diario Clarín, mientras que el tópico Poder Judicial aparece en Página12 y en Perfil como tópico importante.
Ahora que tenemos nuestra base de datos con las noticias definidas según tópicos, tratemos de ver la evolución de los mismos a través del tiempo. Para esto nos centraremos en las noticias del año 2015, año de elecciones presidenciales, y seleccionaremos sólo algunos tópicos que pueden ser pertinentes en un año electoral.
topicos_segun_tiempo<-doc_2_topics_stm_full%>%
filter(mes_ano<"2016-01-01",
mes_ano>"2014-12-31")%>% #filtro segun el tiempo
filter(topic%in%c(2, 4, 6, 9, 11, 12))%>% #filtro para tomar los topicos que me interesan
group_by(mes_ano, label_topico, medio)%>% #agrupo
summarise(mean=mean(gamma))%>% #saco el promedio de cada topico en cada mes
mutate(label_topico=as.factor(label_topico)) #factorizo topico
plot_5_topic_tiempo<-ggplot(topicos_segun_tiempo,
aes(mes_ano, mean))+
geom_line(aes(color=label_topico),stat = "identity", size=1)+
theme_minimal()+
facet_wrap(~medio)+
geom_vline(xintercept = ymd("2015-05-01"), linetype="dashed", color="blue")+
geom_vline(xintercept = ymd("2015-10-01"), linetype="dashed", color="blue")+
labs(x="", y="",title = "Evolución de distribucón de tópicos por mes (año 2015)",
subtitle = "Gráfico 6")
plot_5_topic_tiempo
En el Gráfico 6 podemos ver cómo en general, el tópico Elecciones Presidenciales aumenta (es decir, las noticias contienen mayor distribución de este tópico) en los meses de elecciones (mayo, octubre y noviembre). El tópico Seguridad aumenta en para los meses de elecciones en los diarios Clarín (octubre), Infobae (mayo y noviembre), Minuto Uno (mayo y noviembre) y Perfil (octubre).
Por último, seleccionaremos aquellas noticias que mencionaran a por lo menos un precandidato en su título y generamos un pequeño dataframe para aplicar las técnicas vistas hasta el momento.
# Primero necesitamos seleccionar las noticias que mencionen a algun candidato
candidatos<-c("Macri", "Sanz", "Carrió", "Massa",
"De La Sota", "Stolbizer", "Del Caño", "Altamira",
"Rodríguez Saa", "De Gennaro", "Castañeira", "Bodart", "Yattah", "Albarracín")
candidatos_para_buscar<-str_to_lower(candidatos)%>%
stri_trans_general("Latin-ASCII")
candidatos_para_buscar<-paste0('\\b', candidatos_para_buscar, '\\b')
buscar_candidatos<- function(candidato){
base_candidatos<-base_limpia%>%
filter(str_detect(titulo, "\\bscioli\\b",))%>%
mutate(menciona="\\bscioli\\b")
for (candidato in candidatos_para_buscar) {
base_candidatos2<-base_limpia%>%
filter(str_detect(titulo, candidato))%>%
mutate(menciona=candidato)
base_candidatos<-rbind(base_candidatos, base_candidatos2)
}
return(base_candidatos)
}
base_candidatos<-buscar_candidatos(candidatos_para_buscar)
#la columna de menciones me queda con los nombres de cada candidato mal escritos,
#corrijo los nombres
base_candidatos<-base_candidatos%>%
mutate(menciona=gsub("\\\\","", menciona),
menciona=str_sub(menciona,2, -2))
unique(base_candidatos$menciona) #para chequear los cambios
## [1] "scioli" "macri" "sanz" "carrio"
## [5] "massa" "de la sota" "stolbizer" "del cano"
## [9] "altamira" "rodriguez saa"
base_candidatos_agrup<-base_candidatos%>%
group_by(medio, menciona)%>%
summarise(cantidad=n())
plot_6_menciones_por_diario<-ggplot(base_candidatos_agrup,
aes(reorder(menciona, cantidad), cantidad, fill=medio))+
geom_bar(stat = "identity", position = "stack")+
facet_wrap(~medio, scales = "free")+
theme_minimal()+
theme(legend.position = "none")+
coord_flip()+
labs(x="", y="", title= "Cantidad de menciones por medio", subtitle = "Gráfico 7")
plot_6_menciones_por_diario
En el Gráfico 7 se puede observar que el precandidato presidencial más mencionado en el corpus de noticias fue Mauricio Macri, lo cual es lógico ya que el corpus de noticias traía noticias del año 2016 también.
Ahora intentaremos ver el tono que utilizan los medios para referirse a los precandidatos replicando el sentiment analysis anterior.
base_candidatos_tidy_sentiment<-base_candidatos%>%
unnest_tokens(input = texto, output = word)%>%
anti_join(stop_words)%>%
inner_join(sentiment_words_liia)%>%
group_by(medio,menciona, sentiment)%>%
summarise(cantidad=n())%>%
mutate(total=sum(cantidad),
porcentaje=cantidad/total*100)
plot_7_candidatos_sentiment<-ggplot(base_candidatos_tidy_sentiment,
aes(medio, porcentaje, fill=sentiment))+
geom_bar(stat="identity", position = "stack")+
theme_minimal()+
scale_fill_manual(values = colores_positividad)+
scale_y_continuous(labels=scales::percent_format(scale = 1))+
coord_flip()+
facet_wrap(~menciona)+
labs(x="", y="", title="Distribución de positividad según medio", subtitle = "Gráfico 8")
plot_7_candidatos_sentiment
Nuevamente, replicamos el análisis anterior para ver las palabras más importantes para cada candidato.
filtro_candidatos<-unique(base_candidatos$menciona)
base_candidatos_tidy_tfidf<-base_candidatos%>%
unnest_tokens(input = texto, output = word)%>%
anti_join(stop_words)%>%
filter(!word%in%filtro_candidatos)%>%
group_by(menciona, word)%>%
summarise(cantidad=n())%>%
bind_tf_idf(word,menciona,cantidad)
## Joining, by = "word"
## `summarise()` has grouped output by 'menciona'. You can override using the
## `.groups` argument.
plot_8_candidatos_tfidf<-ggplot(base_candidatos_tidy_tfidf%>%
group_by(menciona)%>%
arrange(desc(tf_idf))%>%
slice(1:15)%>%
ungroup(),
aes(x=reorder(word, tf_idf), y=tf_idf, fill=menciona))+
geom_bar(stat = "identity")+
coord_flip()+
facet_wrap(~menciona, scales = "free")+
theme_minimal()+
theme(legend.position = "none")+
labs(x="", title = "Palabras más representativas para cada precandidato",
subtitle = "Gráfico 9")
plot_8_candidatos_tfidf
Cuando vemos las palabras más representativas para cada precandidato, podemos deducir que tuvimos una serie de falsos positivos para el caso de Altamira ya que las palabras más importantes están relacionadas a vitivinicultura. Otra observación destacable es que las palabras más fuertes para el caso de Carrió y Stolbizer están relacionadas a temas de denuncias y poder judicial.
Finalmente, vamos a aplicar el modelo que generamos pero para ver qué tópicos son más representativos para cada candidato según cada medio.
base_candidatos_topic<-base_candidatos%>%
inner_join(doc_2_topics_stm_full)%>%
# filter(!topic%in%c(8,10,14))%>% #filtro para tomar los topicos que me interesan
group_by(label_topico, medio, menciona)%>%
summarise(mean=mean(gamma))
plot_9_topic_candidato<-ggplot(base_candidatos_topic,
aes(medio, mean, fill=label_topico))+
geom_bar(stat= "identity", position = "stack")+
coord_flip()+
theme_minimal()+
theme(legend.position = "bottom")+
facet_wrap(~menciona, scales = "free")+
scale_y_continuous(labels=scales::percent_format(scale = 100))+
labs(x="", y="", title = "Distribución de tópicos para cada candidato según medio",
subtitle = "Gráfico 10")
plot_9_topic_candidato
En el Gráfico 10 se observa la distribución de tópicos en las noticias que mencionan a precandidatos. Algo esperable y que finalmente se confirma, es que el tópico de Elecciones presidenciales es el que mayor relevancia presenta, y que tópicos como Deportes, Misceláneas, Tecnología y Redes Sociales, o Clima y Naturaleza tuvieron poca relevancia. Como se observaba en el Gráfico 9, para el caso de Altamira, los tópicos Clima y Naturaleza y Arte y Literatura tienen mayor representatividad; mientras que el tópico Poder Judicial representa mayormente las noticias de Carrió y Stolbizer, en consonancia con las palabras más representativas.
Por último, tomamos las noticias que mencionaron a los candidatos presidenciales que llegaron al ballotage y que fueron publicadas luego de la elección general y hasta la fecha de ballotage para observar las palabras más utilizadas y comparar el uso de ellas en cada candidato.
base_ballotage<-base_candidatos%>%
filter(fecha>"2015-10-26", fecha<"2015-11-23",
menciona%in%c("macri", "scioli"))
base_ballotage_tidy<-base_ballotage%>%
unnest_tokens(word, texto)%>%
anti_join(stop_words)%>%
group_by(menciona, word)%>%
summarise(cantidad=n())%>%
mutate(
total = sum(cantidad),
prop = cantidad/total*100) %>%
select(menciona, word, prop) %>%
pivot_wider(names_from = menciona, values_from = prop)
## Joining, by = "word"
## `summarise()` has grouped output by 'menciona'. You can override using the
## `.groups` argument.
plot_10_ballotage<-ggplot(base_ballotage_tidy, aes(macri, scioli)) +
geom_jitter(alpha = 0.05, size = 2.5, width = 0.25, height = 0.25) +
geom_text(aes(label = word), check_overlap = TRUE, vjust = 1.5) +
scale_x_log10() +
scale_y_log10() +
geom_abline(color = "red") +
theme_minimal()+
labs(title = "Distribución de palabras en común", subtitle = "Gráfico 11")
plot_10_ballotage
## Warning: Removed 898 rows containing missing values (geom_point).
## Warning: Removed 898 rows containing missing values (geom_text).
En el Gráfico 11 podemos ver palabras importantes y cómo se ubican en cercanía con cada candidato. Términos como FPV o Cristina se ubican cerca del candidato Scioli, mientras que términos como Alfonso, Frigerio, costo y abogados se ubican cerca de Macri.