1 Introducció

En aquest apartat explicarem com analitzar informació textual. En sessions prèvies, hem treballat amb tidyverse, un conjunt de paquets en R pensats per manipular, transformar i visualitzar dades. En aquesta sessió, també farem servir tidytext, un paquet que permet fer anàlisi de textos utilitzant eines com la tokenització o l’eliminació de paraules buides (stopwords). La tokenització és la divisió d’un text en unitats bàsiques que anomenem tokens. Aquests tokens poden ser paraules, frases, síl·labes o fins i tot caràcters, segons l’anàlisi que es vulgui fer.

library("tidyverse")
library("tidytext")

2 Anàlisi de la declaració de l’estat d’alarma pel COVID-19

Comencarem amb una anàlisi del “Real Decreto 463/2020, de 14 de marzo, por el que se declara el estado de alarma para la gestión de la situación de crisis sanitaria ocasionada por el COVID-19”. Trobareu el text de la declaració en format en format .txt al Campus Virtual.

Per fer la càrrega, farem servir el comandament readLines. Indiquem la codificació latin1 per llegir correctament els accents.

discurs <- readLines("declaracion.txt", encoding = "latin1")
discurs
##  [1] "Buenas tardes."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
##  [2] "Estimados compatriotas."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
##  [3] "En el día de hoy, acabo de comunicar al Jefe del Estado la celebración, mañana, de un Consejo de Ministros extraordinario, para decretar el Estado de Alarma en todo nuestro país, en toda España, durante los próximos 15 días."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
##  [4] "El Estado de Alarma es un instrumento de nuestro Estado de Derecho, recogido por nuestra Constitución, para enfrentar crisis tan extraordinarias como la que desgraciadamente está sufriendo el mundo y también nuestro país."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
##  [5] "La emergencia sanitaria y social generada por el coronavirus conocido como COVID 19, crea circunstancias extraordinarias como las que la Ley contempla para dotar al Gobierno de España de recursos legales, también, extraordinarios."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
##  [6] "En la reunión prevista para mañana, el Consejo de Ministros extraordinario adaptará un conjunto de decisiones excepcionales al amparo de la declaración del Estado de Alarma que se va a decretar mañana."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
##  [7] "Estas decisiones estarán orientadas a movilizar todos los recursos del conjunto del Estado para proteger, mejor, la salud de todos los ciudadanos. Recursos económicos, recursos sanitarios, tanto públicos como privados, tanto civiles como también militares, para la protección de todos los ciudadanos, en particular de los que resulten más vulnerables frente al virus por su edad o por otros padecimientos previos. Y también para responder a la emergencia social y económica con la máxima agilidad y contundencia."                                                                                                                                                                                                   
##  [8] "Queremos la máxima coordinación de recursos, eficiente y garantizada del conjunto de las administraciones públicas y su mejor funcionamiento. El Gobierno de España va a proteger a todos los ciudadanos y va a garantizar las condiciones de vida adecuadas para frenar la pandemia con la menor afectación posible."                                                                                                                                                                                                                                                                                                                                                                                                              
##  [9] "Naturalmente, me dispongo a dar cuenta de inmediato al Congreso de los Diputados, ya he informado a la presidenta del Congreso, he trasladado, también, a las principales fuerzas políticas esta decisión. Otro tanto voy a hacer con los presidentes autonómicos con quienes mantendré una conversación telefónica esta misma tarde. A todos ellos y a todas ellas quiero trasladarles por anticipado mi reconocimiento por el trabajo que vienen haciendo, cada uno desde sus instituciones y sus responsabilidades. También mi gratitud por su comprensión ante estas decisiones que se dirigen a combatir una emergencia que amenaza la salud y el bienestar de todos, y que no atiende ni a fronteras ni internas ni externas."
## [10] "Estamos solo en la primera fase de un combate contra el virus que libran todos los países del mundo y en particular nuestro continente, Europa. Nos esperan, como dije al principio de la semana, semanas muy duras. Dijimos que vendrían días difíciles y tomamos medidas a la altura de esa dificultad. Y no cabe descartar que en la próxima semana alcancemos, desgraciadamente, los más de 10 mil afectados."                                                                                                                                                                                                                                                                                                                  
## [11] "Todo el esfuerzo de las autoridades sanitarias tanto internacionales, como nacionales y autonómicas está dirigido a evitar una propagación demasiado rápida del virus, para poder así auxiliar a los pacientes que por su edad o por dolencias previas sean más vulnerables y precisen la necesaria atención hospitalaria."                                                                                                                                                                                                                                                                                                                                                                                                         
## [12] "Todos tenemos una tarea y una misión en los próximos días, en las próximas semanas y no es menor. La primera línea la forman los profesionales de la salud. Nuestro escudo frente al virus. Ellos con su entrega, con su sacrificio nos protegen a todos y merecen el reconocimiento y la gratitud de todos."                                                                                                                                                                                                                                                                                                                                                                                                                       
## [13] "La misión de las autoridades sanitarias nacionales y autonómicas es, también, clara; proporcionar a los profesionales los medios para desarrollar su labor y mantener y reforzar la extraordinaria coordinación que han desarrollado en estas últimas semanas."                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
## [14] "Quiero, también, trasladar un mensaje muy especial a nuestros mayores y a las personas con enfermedades crónicas que, lógicamente, debilitan sus defensa; deben protegerse al máximo frente a la infección. Evitar a toda costa los contactos y la exposición en espacios públicos."                                                                                                                                                                                                                                                                                                                                                                                                                                                
## [15] "También me gustaría dirigirme a los jóvenes, quienes tienen, también, una misión decisiva. Es cierto que por su vitalidad pueden sentirse al abrigo de los efectos más severos del virus, pero pueden actuar como transmisores a otras personas cercanas mucho más vulnerables. Su colaboración, la colaboración de los jóvenes, es decisiva para cortar los contagios y por eso deben limitar los contactos y mantener la distancia social."                                                                                                                                                                                                                                                                                       
## [16] "Y todas, y todos, tenemos, por supuesto, un deber personal; seguir a rajatabla las indicaciones de los expertos y colaborar unidos para vencer al virus con la máxima responsabilidad y absoluta disciplina social."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
## [17] "Lo he venido diciendo a lo largo de esta semana; haremos desde el Gobierno de España lo que haga falta, cuando falta y donde haga falta."                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
## [18] "La declaración del Estado de Alarma permite movilizar, al máximo, los recursos materiales para combatir el virus. Pero, también me vais a permitir que haya un recurso fundamental, que está más allá de cualquier ley o decreto y al que me gustaría apelar directamente a los compatriotas. La victoria depende de cada uno de nosotros, en nuestro hogar, en nuestra familia, en el trabajo, en nuestro vecindario. El heroísmo consiste, también, en lavarse las manos, en quedarse en casa y en protegerse uno mismo, para proteger al conjunto de la ciudadanía."                                                                                                                                                             
## [19] "Tardaremos semanas, va a ser muy duro y difícil, pero vamos a parar al virus. Eso es seguro. Con unidad, responsabilidad y disciplina social. Superaremos esta emergencia amparándonos en el consejo de la ciencia y apoyándonos en todos los recursos del Estado. Pero también es seguro que lo conseguiremos antes y con los menores daños humanos, económicos y sociales posibles si lo hacemos unidos y cumpliendo cada cual con nuestro deber. Este virus lo pararemos unidos. Muchas gracias. Buenas tardes."

2.1 Càlcul de la freqüència dels termes

Estructurarem la informació en un tibble amb dues columnes: una amb el número del paràgraf i una altra amb el text.

discurs <- tibble(num_par = seq_along(discurs),
                  text = discurs)
str(discurs)
## tibble [19 x 2] (S3: tbl_df/tbl/data.frame)
##  $ num_par: int [1:19] 1 2 3 4 5 6 7 8 9 10 ...
##  $ text   : chr [1:19] "Buenas tardes." "Estimados compatriotas." "En el día de hoy, acabo de comunicar al Jefe del Estado la celebración, mañana, de un Consejo de Ministros extr"| __truncated__ "El Estado de Alarma es un instrumento de nuestro Estado de Derecho, recogido por nuestra Constitución, para enf"| __truncated__ ...

El següent pas consisteix a separar individualment les paraules. Amb aquesta finalitat, farem servir la funció unnest_tokens del paquet tidytext. Per defecte, interpreta que les tokens en què volem divir el text són paraules, però també podriem dividir el text en frases, com veurem a continuació. Totes les paraules quedaran en minúscules, la qual cosa facilitarà l’anàlisi.

paraules <- discurs %>%
  tidytext::unnest_tokens(paraula, text)

Com hem comentat, també podriem dividir el text en frases:

frases <- discurs %>%
  tidytext::unnest_tokens(frase, text, token = "sentences")

L’anàlisi més simple consisteix a fer el recompte de la freqüència de les paraules que apareixen en el text. Per defecte, les paraules apareixen alfabèticament, de manera que afegim el paràmetre sort que permet indicar que volem una ordenació per freqüència.

paraules %>%
  count(paraula, sort = TRUE)

Podem observar que les paraules més freqüents són paraules buides (articles, conjuncions, preposicions, etc.) sense valor semàntic. Per tant, abans de proseguir, el millor serà eliminar aquestes paraules buides. El paquet tidytext porta carregats diversos diccionaris de paraules buides en diferents idiomes, inclòs el castellà però no el català. En aquest cas, carreguem el conjunt de paraules buides en castellà en un objecte que anomenem vacias.

vacias <- tidytext::get_stopwords("es")

Podeu observar que hi ha 308 paraules buides. L’encapçalament en el dataframe és word. El canviarem per paraula que és el nom del camp en el dataframe amb el discurs. D’aquesta manera podrem creuar fàcilment els dos dataframes per eliminar les paraules buides.

vacias <- vacias %>%
  rename(paraula = word)
str(vacias)
## tibble [308 x 2] (S3: tbl_df/tbl/data.frame)
##  $ paraula: chr [1:308] "de" "la" "que" "el" ...
##  $ lexicon: chr [1:308] "snowball" "snowball" "snowball" "snowball" ...

Ara ja podem eliminar les paraules buides.

paraules <- paraules %>%
  anti_join(vacias)
## Joining, by = "paraula"

I fem un recompte de les paraules.

freq.paraules <- paraules %>%
  count(paraula, sort = TRUE)

head(freq.paraules, 5)

2.2 Representació gràfica de les paraules més freqüents

Farem una gràfica de les 5 paraules més freqüents.

frequents <- freq.paraules %>%
  top_n(5, n)

ggplot(frequents, aes(x=paraula, y = n)) +
  geom_col() +
  labs(title = "Paraules més freqüents",
       y = "Freqüència") +
  theme_minimal()

Una altra opció més atractiva és representar totes les paraules en un núvol.

library(wordcloud2)
wordcloud2(freq.paraules)

3 Anàlisi de les lletres de les cançons de Taylor Swift

En primer lloc, carreguem les lletres de les cançons. Les teniu disponibles al Campus Virtual. Veureu que el fitxer conté quatre camps amb: un número consecutiu, que ens permetrà referir-nos fàcilment a qualsevol cançó; títol de l’álbum; títol de la canço; i la lletra.

TS_lyrics <- readxl::read_excel("TS_data.xlsx")

Igual que a l’exemple anterior, procedim a separar les lletres de les cançons en paraules. Visualitzem les 20 primeres paraules per observar l’estructura del dataset.

lletresTS_brut <- TS_lyrics %>%
  unnest_tokens(word, Lyrics)

head(lletresTS_brut, 20)

A continuació, procedim a eliminar les paraules buides. Fem servir la llista de paraules buides en anglès que conté tidytext. Com que al fitxer de lletres ja estan en una columna que es diu “word”, igual que al diccionari de paraules buides, podem eliminar-les directament.

lletresTS <- lletresTS_brut %>%
  anti_join(stop_words)
## Joining, by = "word"

De què parlen les lletres de Taylor Swift? Es a dir, quines són les paraules més freqüents?

top <- lletresTS %>%
  count(word, sort = T)

top

També ho podem visualitzar en forma de núvol de paraules.

wordcloud2(top)

Pot ser interessant analitzar si els termes més freqüents són els mateixos a tots els discos o si les paraules més freqüents han canviat amb el pas del temps.

lletresTS %>% 
  group_by(Album) %>% 
  count(word, sort = TRUE) %>% 
  slice(1,2,3) %>%
  ggplot() +
  geom_bar(aes(x = word, weight = n, fill = word)) +
  coord_flip() +
  facet_wrap(~Album) +
  theme_minimal() +
  theme(legend.position = "none")

4 Anàlisi de sentiments

L’anàlisi de sentiments consisteix a classificar paraules o textos segons la seva polaritat emocional:

  • Positiva / Negativa

  • Alegria, tristesa, por, ira, etc. (emocions específiques)

Aquestes classificacions es basen en diccionaris predefinits anomenats lexicons. Amb el paquet tidytext, podem carregar diversos lexicons, però tots estan en anglès:

  • bing: Positiu / Negatiu. Exemple: “happy” = positiu

  • afinn: escala de -5 a +5. Exemple: “hate” = -3

  • NRC: emocions (alegria, por, tristesa…). Exemple: “fear”, “joy”

Imaginem que tenim una pizzeria i volem analitzar les ressenyes que alguns clients han escrit sobre el nostre negoci. Carregarem algunes frases que ens serviran d’exemple.

ressenyes <- tibble(ressenya = 1:5,
                    text = c("The pizza was absolutely delicious and the crust was perfect.",
                            "Terrible service. We waited 40 minutes for our order.",
                            "The staff was friendly and made us feel welcome.",
                            "The sauce was too salty and the dough was undercooked.",
                            "Great experience! We'll definitely come back again."))

El primer pas, consistirà a individualitzar les paraules.

paraules <- ressenyes %>%
            unnest_tokens(word, text)

A continuació, creuem les paraules presents a les ressenyes amb el lexicon bing.

sentiments <- paraules %>%
  inner_join(get_sentiments("bing"))
## Joining, by = "word"

Fem un resum del tipus de sentiment present a les ressenyes de la nostra pizzeria.

resum_sentiments <- sentiments %>%
  count(sentiment)

ggplot(resum_sentiments, aes(x = sentiment, y = n, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  labs(title = "Anàlisi de sentiments (bing)", y = "Nombre de paraules")

Veurem un segon exemple d’anàlisi de les emocions en un text polític fent servir el lexicon NRC. La descàrrega d’aquest lexicon és una mica pesada ja que conté gairebé 14.000 paraules associades a un o diversos sentiments. Si no voleu, no cal que descarregueu el lexicon, simplement podeu observar el següent exemple.

text.politic <- tibble(linia = 1, text = "Our nation stands at a crossroads. Citizens demand justice, transparency, and strong leadership. While fear and uncertainty grow, we must choose unity over division. Together, we can build a future rooted in hope and equality. We reject corruption and violence, and embrace progress, dialogue, and peace.")

Com és habitual, comencem amb l’extracció de les paraules.

tokens <- text.politic %>%
  unnest_tokens(word, text)

A continuació, creuem aquestes paraules amb les del lexicon NRC.

nrc_sentiments <- get_sentiments("nrc")

sentiments <- tokens %>%
  inner_join(nrc_sentiments, by = "word")

sentiments

Resumim i visualitzem les conclusions.

sentiments.resum <- sentiments %>%
  count(sentiment, sort = TRUE)

ggplot(sentiments.resum, aes(x = reorder(sentiment, n), y = n, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  coord_flip() +
  labs(title = "Emocions presents en un text (anàlisi amb NRC)",
       x = "Emoció",
       y = "Nombre de paraules")

5 Estilometria

L’estilometria és l’estudi quantitatiu de l’estil d’escriptura, generalment amb l’objectiu d’atribuir l’autoria d’un text o descriure característiques estilístiques d’un autor, període o gènere. Analitza elements lingüístics com ara la freqüència de paraules (sobretot les paraules funcionals com “i”, “de”, “que”, etc.), la longitud de les frases, l’ús de signes de puntuació i patrons gramaticals o lèxics.

Veurem un exemple bàsic d’anàlisi estilomètrica. No obstant, hi ha paquets específics per aquest tipus d’anàlis com stylo.

Carreguem 6 textos, de diferents estils, corresponents a 3 suposats autors.

textos <- tibble(autor = c("Clara Montes",
                           "Clara Montes",
                           "Mario Fuentes",
                           "Mario Fuentes",
                           "Sofía Delgado",
                           "Sofía Delgado"),
text = c(
"La luna se alzaba lenta sobre el horizonte, plateada y silenciosa. Los árboles susurraban secretos al viento...",
"La bruma cubría la ciudad como un velo tenue. Las luces difusas pintaban siluetas inciertas...",
"Juan llegó temprano. Nadie lo esperaba. Caminó al centro del cuarto y encendió la lámpara...",
"Corrió sin mirar atrás. Los pasos resonaban. El túnel era largo. Oscuro. Húmedo...",
"A veces pensaba que el tiempo no era más que una ilusión cuidadosamente construida...",
"Aquella mañana no fue distinta a las demás, y sin embargo algo en la manera en que el sol atravesaba..."))

Extreiem les paraules i comptabilitzem les que utilitza més freqüentment cada autora.

tokens <- textos %>%
  unnest_tokens(paraula, text) %>%
  count(autor, paraula, sort = TRUE)

tokens

Ho representem gràficament.

ggplot(tokens, aes(x = paraula, y = n, fill = autor)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~autor, scales = "free") +
  coord_flip() +
  labs(title = "Paraules més freqüents de cada autora", y = "Freqüència", x = "Paraula")

Per acabar, compararem la longitud de les frases de cada autora, tant el nombre de paraules per frase com el nombre de caràcteres per frase. Comencem separant els textos en frases.

frases <- textos %>%
  unnest_tokens(frase, text, token = "sentences")

Calculem la longitude les frases.

frases <- frases %>%
  mutate(
    n_paraules = str_count(frase, "\\S+"),  # Compta paraules per espais
    n_caracteres = nchar(frase)             # Compta caràcters
  )
frases %>%
  group_by(autor) %>%
  summarise(
    mitjana_paraules = mean(n_paraules),
    mitjana_caracteres = mean(n_caracteres))

6 Exercici 4: arbres de decisió i anàlisi textual

Com és habitual, l’exercici té quatre parts. Les tres primeres són obligatòries i la quarta és opcional.

Per donar resposta a l’exercici cal lliurar dos arxius a través del Campus Virtual: l’script de R que heu fet servir i un document en PDF explicant les respostes a les preguntes.

6.1 Primera part: portar ulleres o lentilles?

Una òptica ha recollit dades sobre una mostra de clients amb l’objectiu de determinar si és convenient que utilitzin lents de contacte, i en cas afirmatiu, quin tipus (toves o rígides). Per a cada client s’ha registrat la següent informació: edat (adolescent, jove o adult), patologia (miopia o hipermetropia), astigmatisme (si o no) i lacrimosidad (reduida o normal). A partir d’aquestes dades, s’indica si la persona ha de portar lents de contacte (toves o rígides) o si no és convenient que usi lents de contacte.

L’objectiu de l’activitat és elaborar un arbre de decisió amb el paquet party. Visualitzeu i interpreteu l’arbre: quines variables tenen més influència en la decisió? Per què? Quina seria la prescripció adequada per a un jove amb lacrimositat reduïda segons l’arbre generat?

6.2 Segona part: anàlisi d’un text de Mario Benedetti

Al Campus Virtual trobaràs el text del conte Pacto de sangre de l’escriptor uruguaià Mario Benedetti. Identifica els termes més freqüents en el text, reprodueix-los en un núvol de paraules, determina la longitud de les frases i, en general, intenta aplicar sobre el text el que has après en aquest Tema.

6.3 Tercera part: anàlisi de sentiments

Localitza a Amazon, Google Maps o una altra font 10 ressenyes de productes o serveis. Poden ser del mateix o de diferents productes, serveis, empreses, etc. Fes una anàlisi dels sentiments presents en aquestes ressenyes i comenta els resultats.

6.4 Quarta part (opcional): els efectes d’una targeta sobre les propines

L’objectiu d’aquest exercici és determinar si, en un bar, deixar una targeta amb un acudit al costat del compte incrementa les possibilitats d’obtenir una propina . Un estudi va investigar aquesta qüestió entre els clients que acudien solos a la terrassa d’un bar de la costa francesa i demanaven un cafè. El cambrer va dividir aleatòriament els 211 clients d’una setmana en tres grups. Al costat del compte, el primer grup rebia una targeta amb un acudit, el segon grup rebia una targeta de publicitat d’un restaurant local i el tercer grup no rebia cap targeta. En tots els casos, el cambrer anotava si el client deixava o no propina.

El dataset original (disponible en: https://vincentarelbundock.github.io/Rdatasets/csv/Stat2Data/TipJoke.csv) conté la següent informació:

  • Card: Type of card used (Ad, Joke, or None)

  • Tip: 1=customer left a tip or 0=no tip

  • Ad: Indicator for Ad card (1=ad card left or 0=no ad card)

  • Joke: Indicator for Joke card (1=joke card left or 0=no joke card)

  • None: Indicator for no card (1=no card left or 0=ad or joke card left)

Per facilitar-vos la feina, he penjat al Campus Virtual un fitxer anomentat propina que us facilitarà l’anàlisi.

L’objectiu de l’activitat és elaborar un arbre de decisió per a determinar si el cambrer rebrà o no una propina en funció del tipus de targeta que deixi al client. Crea l’arbre i comenta els resultats.

Font: Gueguen, Nicholas (2002). The effects of a joke on tipping when it is delivered at the same time as the bill.Journal of Applied Social Psychology, 32 (9), 1955-1963. https://doi.org/10.1111/j.1559-1816.2002.tb00266.x