-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.Rmd
173 lines (143 loc) · 5.54 KB
/
index.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
---
title: "Text Mining Ejercicio"
author: "Alejandro Valladares Vaquero"
date: "`r Sys.Date()`"
output:
html_document:
theme: paper
highlight: tango
number_sections: TRUE
toc: TRUE
toc_float: TRUE
code_folding: "show"
pdf_document: default
word_document: default
urlcolor: blue
---
# Librerías necesarias
```{r message=FALSE}
library(wordcloud)
library(RColorBrewer)
library(tidyverse)
library(stringr)
library(gridExtra)
library(wordcloud)
library(lubridate)
library(tidytext)
library(tm)
library(reshape2)
```
***
# Introducción
Este ejercicio se ha realizado utilizando el paquete tidytext, que es un paquete de Text Mining que sigue los principios de Tidy Data (H. Wickham).
Descargamos los datos de Kaggle, puesto que aún no hay una Kaggle oficial para R, el archivo se puede descargar del siguiente enlace https://www.kaggle.com/aaron7sun/stocknews/downloads/stocknews.zip
Y leemos en una estructura tipo tibble.
***
## Carga de los datos
```{r eval=FALSE, message=FALSE, warning=FALSE, include=FALSE}
zipped_data <- paste0(getwd(), "/data/stocknews.zip")
news <- read_csv(unz(zipped_data, "Combined_News_DJIA.csv"), col_types = cols(
Label = col_skip()
))
saveRDS(news, paste0(getwd(), "/data/news.rds"))
```
O también podemos guardar el archivocomo un archivo serializado Rds, para que no haga falta abrir el zip cada vez. Abajo vemos un ejemplo de la distribución de los datos. Vemos que tenemos una primera columna con la fecha del día y las siguientes 25 columnas son los 25 titulares más destacados en el Reddit **r/worldnews** en el periodo entre Agosto de 2008 y Julio de 2017.
```{r}
news <- readRDS("data/news.rds")
head(news[,1:2],10)
```
***
## Limpieza de los titulares
```{r}
news_text <- as_tibble(lapply(news[, 2:26], function(y)gsub("^b'", "", y)))
news_text <- as_tibble(lapply(news_text, function(y)gsub("^b\"", "", y)))
news_text <- as_tibble(lapply(news_text, function(y)gsub("[[:punct:]]", "", y)))
news_text <- as_tibble(lapply(news_text, function(y)tolower(y)))
news_text <- as_tibble(lapply(news_text, function(y)gsub("[ \t]{2,}", "", y)))
news_text <- as_tibble(lapply(news_text, function(y)gsub("^\\s+|\\s+$", "", y)))
news_text <- as_tibble(cbind(news[, 1],news_text))
head(news_text[,1:2],10)
```
Una vez tenemos algo más ordenado y limpio el texto, se abre un gran abanico de posibilidades de trabajo como veremos a continuación.
***
# Análisis del texto
Al tener las noticias separadas por orden de popularidad en r/worldnews, una posibilidad sería la de mantener este ranking e intentar analizar la temática o el sentimiento de las noticias más populares y ver como evolucionan con el tiempo.
Por ejemplo sería muy útil ver si el factor que tienen sobre las noticias más populares grandes sucesos a nivel mundial (elecciones generales, crisis financieras, guerras, desastres naturales, grandes eventos deportivos, temáticas de primer orden mundial como el cambio climático, etc)
***
## Análisis de sentimiento *estático*
Para esta entrega me voy a centrar en un **análisis estático**, es decir, voy a prescindir de las variable temporal y de la popularidad en el análisis. El objetivo es un simple análisis de contenido y sentimiento a lo largo de todos los años de titulares. Así podremos ver que es lo que más ha preocupado al mundo durante estos años (o lo que más ha preocupado a los usuarios de **r/worldnews**).
### Ordenando el dataframe
Lo primero que vamos a hacer, es unir todos los titulares en una sóla columna.
```{r}
news_text_day <- news_text %>%
unite("headlines", c(Top1:Top25), sep=" ")
head(news_text_day,10)
```
```{r}
tidy_news <- news_text_day %>%
unnest_tokens(word, headlines)
head(tidy_news,10)
```
### Limpieza de stop-words
Una vez que tenemos el el texto en formato *tidytext*, podemos quitar las stopwrods directamente haciendo un anti-join.
```{r message=FALSE}
tidy_news <- tidy_news %>%
anti_join(stop_words)
tidy_news %>%
count(word, sort = TRUE)
```
### Palabras más importantes
Una vez eliminadas las stop-words, vamos a pintar el histograma con las palabras más aparecidas a lo largo de los años.
```{r echo=TRUE}
tidy_news %>%
count(word, sort = TRUE) %>%
filter(n > 650) %>%
mutate(word = reorder(word, n)) %>%
ggplot(aes(word, n)) +
geom_col() +
xlab("n") +
coord_flip() +
scale_x_discrete()
```
### Nube de palabras
```{r message=FALSE, warning=FALSE}
tidy_news %>%
anti_join(stop_words) %>%
count(word) %>%
with(wordcloud(word, n, max.words = 150))
```
***
# Análisis de sentimiento
Vamos a utilizar el lexicón ***bing*** que hay en el paquete *tidytext*.
```{r message=FALSE}
bing_word_counts <- tidy_news %>%
inner_join(get_sentiments("bing")) %>%
count(word, sentiment, sort = TRUE) %>%
ungroup()
head(bing_word_counts, 10)
```
## Histograma con las palabras más utilizadas por sentimiento
```{r message=FALSE}
bing_word_counts %>%
group_by(sentiment) %>%
top_n(10) %>%
ungroup() %>%
mutate(word = reorder(word, n)) %>%
ggplot(aes(word, n, fill = sentiment)) +
geom_col(show.legend = FALSE) +
facet_wrap(~sentiment, scales = "free_y") +
labs(y = "Análisis de sentimiento",
x = NULL) +
coord_flip()
```
<br><br>
Vemos claramente como los titulares tienden a ser más negativos que positivos.
## Nube de palabras con *sentimiento*
```{r message=FALSE, warning=FALSE}
tidy_news %>%
inner_join(get_sentiments("bing")) %>%
count(word, sentiment, sort = TRUE) %>%
acast(word ~ sentiment, value.var = "n", fill = 0) %>%
comparison.cloud(colors = c("red", "blue"),
max.words = 100)
```