Previo

Directorio

setwd("/Users/anaescoto/Dropbox/2020/2020_PAPIIT PERIODO ESPECIAL/Curso")

Paquetería

rm(list=ls()) ### borra objetos en el ambiente

if (!require("pacman")) install.packages("pacman") # instala pacman si se requiere
## Loading required package: pacman
#cargan los paquetes necesario. No se utilizan todos
pacman::p_load(tidyverse, tm, NLP, SnowballC, wordcloud, ggwordcloud,
               quanteda, udpipe, igraph, ggraph,
               sjlabelled, RColorBrewer, readxl, janitor, textrank,
               broom, wesanderson, epubr, pdftools)

Insumos - ¿dónde están?

Vamos a guardar los “caminos” dónde están los archivos con los que vamos a trabajar en objetos. R es un lenguaje de programación por objetos. Tenemos que declarar la información en objetos para poderla utilizar

## Insumos
path<-"./datos/Cien_botellas_en_una_pared_Ena_Lucia_Portella.epub" # formato epub
path2<-"./datos/El_lobo_el_bosque_y_el_hombre_nuevo_Senel_Paz.epub" #fortamo epub
path3<-"./datos/La_nada_cotidiana_Zoe_Valdes.pdf" #formato pdf
path4<-"./datos/amlo_abri.txt" #formato pdf

Tokenización y revisión UPOS

Importando modelo de tokenización

udmodel <- udpipe_download_model(language = "spanish")  # esto trabaja con la estructura del español
## Downloading udpipe model from https://raw.githubusercontent.com/jwijffels/udpipe.models.ud.2.4/master/inst/udpipe-ud-2.4-190531/spanish-gsd-ud-2.4-190531.udpipe to /Users/anaescoto/Dropbox/2020/2020_PAPIIT PERIODO ESPECIAL/Curso/spanish-gsd-ud-2.4-190531.udpipe
## Visit https://github.com/jwijffels/udpipe.models.ud.2.4 for model license details

Formato epub

Vamos a importar un libro desde su formato epub. Este formato es mejor que el de pdf porque no tenemos tantos cortes por páginas.

epub_head(path) # muestra lo primero
## # A tibble: 19 x 2
##    section                 text                                            
##    <chr>                   <chr>                                           
##  1 portada.xhtml           ""                                              
##  2 sec_0001.xhtml          "Ena Portella\n  \n\n  \n\n  \n    Cien botella…
##  3 sec_0002.xhtml          Obra premiada con el Premio Jaén de Novela 2002…
##  4 sec_0003.xhtml          "Para Marilyn Bobes,\n\n    por todo.\n\n    \n…
##  5 sec_0004.xhtml          "Algo pequeño ha decidido vivir.\n\n    ANNA AJ…
##  6 sec_0005.xhtml          "1. Por lo menos un tortazo\n\n  \n\n  Si algo …
##  7 sec_0006.xhtml          "2. La esquina del martillo alegre\n\n  \n\n  T…
##  8 sec_0007.xhtml          "3. Ella quería ser escritora\n\n  \n\n  Pero q…
##  9 sec_0008.xhtml          "4. Mangos y guayabas\n\n  \n\n  -Nos enseñan a…
## 10 sec_0009.xhtml          "5. Buscando nuevas ansiedades\n\n  \n\n  Encla…
## 11 sec_0010.xhtml          "6. La muchacha del jueves\n\n  \n\n  Qué coinc…
## 12 sec_0011.xhtml          "7. ¡Buen aniversario, chiquita!\n\n  \n\n  Lo …
## 13 sec_0012.xhtml          "8. El año próximo en Jerusalén\n\n  \n\n  Las …
## 14 sec_0013.xhtml          "9. Porque el amor lo disculpa todo\n\n  \n\n  …
## 15 sec_0014.xhtml          "10. Disparos en el piso veinte\n\n  \n\n  Que …
## 16 sec_0015.xhtml          "11. Mi marido, una amiga\n\n  \n\n  Ridículo, …
## 17 sec_0016.xhtml          "12. Para escapar al vértigo del tiempo\n\n  \n…
## 18 sec_0017.xhtml          "Sobre el autor y la obra\n\n  \n\n  En esta, s…
## 19 notas_a_pie_de_pagina.… "Notas\n\n  \n    \n  \n\n  1. Por lo menos un …
epub_meta(path) # muestra el meta-data del libro
## # A tibble: 1 x 8
##   creator  description   date  contributor title publisher subject language
##   <chr>    <chr>         <chr> <chr>       <chr> <chr>     <chr>   <chr>   
## 1 Ena Luc… En esta, su … 2002… ""          Cien… ""        Novela  es
x <- epub(path) # Importa todo el libro en el objeto x, pero no queremos todo
x
## # A tibble: 1 x 9
##   creator description date  contributor title publisher subject language
##   <chr>   <chr>       <chr> <lgl>       <chr> <lgl>     <chr>   <chr>   
## 1 Ena Lu… En esta, s… 2002… NA          Cien… NA        Novela  es      
## # … with 1 more variable: data <list>
class(x)
## [1] "tbl_df"     "tbl"        "data.frame"

Como observamos lo que queremos son las secciones que realmente tiene nuestro texto (¡aunque quizás también analizar contraportadas sea otro tema de análisis!)

x$data # esto muestra que aquí adentro está lo que queremos
## [[1]]
## # A tibble: 19 x 4
##    section            text                                      nword nchar
##    <chr>              <chr>                                     <int> <int>
##  1 portada.xhtml      ""                                            0     0
##  2 sec_0001.xhtml     "Ena Portella\n  \n\n  \n\n  \n    Cien …     7    54
##  3 sec_0002.xhtml     "Obra premiada con el Premio Jaén de Nov…    70   607
##  4 sec_0003.xhtml     "Para Marilyn Bobes,\n\n    por todo.\n\…    14    96
##  5 sec_0004.xhtml     "Algo pequeño ha decidido vivir.\n\n    …     7    50
##  6 sec_0005.xhtml     "1. Por lo menos un tortazo\n\n  \n\n  S…  5908 34501
##  7 sec_0006.xhtml     "2. La esquina del martillo alegre\n\n  …  7363 42526
##  8 sec_0007.xhtml     "3. Ella quería ser escritora\n\n  \n\n …  7856 44633
##  9 sec_0008.xhtml     "4. Mangos y guayabas\n\n  \n\n  -Nos en…  7823 44854
## 10 sec_0009.xhtml     "5. Buscando nuevas ansiedades\n\n  \n\n…  7833 45489
## 11 sec_0010.xhtml     "6. La muchacha del jueves\n\n  \n\n  Qu…  6632 38194
## 12 sec_0011.xhtml     "7. ¡Buen aniversario, chiquita!\n\n  \n…  6998 39366
## 13 sec_0012.xhtml     "8. El año próximo en Jerusalén\n\n  \n\…  7253 41638
## 14 sec_0013.xhtml     "9. Porque el amor lo disculpa todo\n\n …  8156 47135
## 15 sec_0014.xhtml     "10. Disparos en el piso veinte\n\n  \n\…  7982 45784
## 16 sec_0015.xhtml     "11. Mi marido, una amiga\n\n  \n\n  Rid…  7952 45489
## 17 sec_0016.xhtml     "12. Para escapar al vértigo del tiempo\…  7728 43904
## 18 sec_0017.xhtml     "Sobre el autor y la obra\n\n  \n\n  En …   228  1351
## 19 notas_a_pie_de_pa… "Notas\n\n  \n    \n  \n\n  1. Por lo me…   360  2450
epub_100<-x$data[[1]] # Nos quedamos con esa base de datos
epub_100<-epub_100[6:18, ]  # Nos quedamos de las líneas 6 a la 18, donde están los capítulos

Nuestra novela tokenizada

Una vez que ya tenemos un objeto con la información que necesitamos, usaremos nuestro modelo para tokenizarla. Este resultado lo guardaremos en un objeto.

cien_botellas<-udpipe(x = paste(epub_100$text), #paste nos asegura que se pegue como caracter
                      object=udmodel) #"tokeniza" el texto

Vamos a revisar ese objeto “tokenizado”

glimpse(cien_botellas)
## Observations: 111,239
## Variables: 17
## $ doc_id        <chr> "doc1", "doc1", "doc1", "doc1", "doc1", "doc1", "d…
## $ paragraph_id  <int> 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,…
## $ sentence_id   <int> 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,…
## $ sentence      <chr> "1.", "1.", "Por lo menos un tortazo", "Por lo men…
## $ start         <int> 1, 2, 4, 8, 11, 17, 20, 35, 38, 43, 46, 55, 66, 68…
## $ end           <int> 1, 2, 6, 9, 15, 18, 26, 36, 41, 44, 53, 65, 66, 69…
## $ term_id       <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,…
## $ token_id      <chr> "1", "2", "1", "2", "3", "4", "5", "1", "2", "3", …
## $ token         <chr> "1", ".", "Por", "lo", "menos", "un", "tortazo", "…
## $ lemma         <chr> "1", ".", "por", "él", "menos", "uno", "tortazo", …
## $ upos          <chr> "NUM", "PUNCT", "ADP", "PRON", "ADV", "DET", "NOUN…
## $ xpos          <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
## $ feats         <chr> "NumType=Card", NA, NA, "Case=Acc|Gender=Masc|Numb…
## $ head_token_id <chr> "0", "1", "2", "5", "4", "5", "0", "4", "4", "4", …
## $ dep_rel       <chr> "root", "punct", "case", "nmod", "advmod", "det", …
## $ deps          <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
## $ misc          <chr> "SpaceAfter=No", NA, NA, NA, NA, NA, "SpacesAfter=…

Nos vamos a concentrar en la variable “upos”, proviende de UPOS Universal Parts of Speech https://universaldependencies.org/u/pos/index.html

cien_botellas %>% 
  tabyl(upos) # esto nos da un tabulado
##   upos     n      percent valid_percent
##    ADJ  5746 5.165455e-02  5.270883e-02
##    ADP 13518 1.215221e-01  1.240024e-01
##    ADV  6750 6.068016e-02  6.191865e-02
##    AUX  2710 2.436196e-02  2.485919e-02
##  CCONJ  4068 3.656991e-02  3.731631e-02
##    DET 12833 1.153642e-01  1.177188e-01
##   INTJ   135 1.213603e-03  1.238373e-03
##   NOUN 17155 1.542175e-01  1.573651e-01
##    NUM   449 4.036354e-03  4.118737e-03
##   PART     5 4.494826e-05  4.586567e-05
##   PRON  9684 8.705580e-02  8.883263e-02
##  PROPN  2913 2.618686e-02  2.672134e-02
##  PUNCT 17206 1.546760e-01  1.578329e-01
##  SCONJ  3472 3.121207e-02  3.184912e-02
##    SYM    14 1.258551e-04  1.284239e-04
##   VERB 12032 1.081635e-01  1.103711e-01
##      X   324 2.912648e-03  2.972095e-03
##   <NA>  2225 2.000198e-02            NA

Parece complejo, por eso lo repetiremos para otra novela, para ver qué elementos hay que cambiar de este código.

Lobo

Hacemos lo mismo para el libro de Senel

x <- epub(path2) # Importa todo el libro en el objeto x, pero no queremos todo
x
## # A tibble: 1 x 9
##   creator description date  contributor title publisher subject language
##   <chr>   <chr>       <chr> <lgl>       <chr> <lgl>     <chr>   <chr>   
## 1 Senel … "La Habana… 1991… NA          El l… NA        Variada es      
## # … with 1 more variable: data <list>
x$data # esto muestra que aquí adentro está lo que queremos
## [[1]]
## # A tibble: 5 x 4
##   section      text                                             nword nchar
##   <chr>        <chr>                                            <int> <int>
## 1 sec_0001.xh… "El lobo, el bosque y el hombre nuevo\n\n\n\nSe…    10    49
## 2 sec_0002.xh… "Sinopsis\n\nLa Habana, a treinta años del triu…   236  1421
## 3 sec_0003.xh… "©1991, Paz, Senel\nEditorial: Ediciones ERA\nI…    12    95
## 4 sec_0004.xh… "El lobo, el bosque y el hombre nuevo\n\nIsmael… 10505 58940
## 5 titlepage    ""                                                   0     0
epub_lobo<-x$data[[1]] # Nos quedamos con esa base de datos
epub_lobo<-epub_100[4, ]  # Nos quedamos con línea 4


lobo<-udpipe(x = paste(epub_lobo$text), object=udmodel) #"tokeniza" el texto

Revisando elementos UPOS

Nombres

Vamos a revisar un tipo especial, los sustantivos. “NOUN”, en inglés

Veamos para el caso de nuestra primera novela

stats<- cien_botellas %>% 
  filter(upos=="NOUN")

stats.freq <- txt_freq(stats$token)
stats.freq$key <- factor(stats.freq$key, levels = rev(stats.freq$key)) # ordena

stats.freq[1:25,] %>% 
  ggplot(aes(x=key, y=freq)) +geom_bar(stat="identity") + 
  coord_flip() + labs(y="Frecuencia", x="Sustantivo") + theme_minimal()

¿Se ve complejo? Volvamos a hacerlo, para ver qué elementos habría que cambiar en este código para un nuevo caso

stats<- lobo %>% 
  filter(upos=="NOUN") #checa que esto sobreescribe los objetos que teníasmo

stats.freq <- txt_freq(stats$token)
stats.freq$key <- factor(stats.freq$key, levels = rev(stats.freq$key)) # ordena

stats.freq[1:25,] %>% 
  ggplot(aes(x=key, y=freq)) +geom_bar(stat="identity") + 
  coord_flip() + labs(y="Frecuencia", x="Sustantivo") + theme_minimal()

Nube de sustantivos

Con esto podemos hacer una nube, esas son famosas:

set.seed(42) # tiene un elemento aleatorio

stats.freq[1:25,] %>% 
  ggplot(aes(label=key, size=freq)) +  geom_text_wordcloud() +
  theme_minimal()

La vamos a poner más chula:

stats.freq[1:25,] %>% 
    ggplot(
        aes(
        label =key, size = freq,
        color = factor(sample.int(15, nrow(stats.freq[1:25,]), replace = TRUE))
        )
    ) +
      geom_text_wordcloud_area() +
      scale_size_area(max_size = 12) +
      theme_minimal()

Otra paquetería, es más fácil pero menos editable

set.seed(1234)

paleta_color<-wes_palette(n=5,
                          name="Darjeeling1",
                          type="continuous")

wordcloud(words = stats.freq$key, freq = stats.freq$freq,
          min.freq = 5,
          max.words=200, 
          random.order=FALSE, 
          colors=paleta_color)

Adjetivos

Vamos a encontrar los adjetivos más usados para la novela “Cien botellas..”

stats<- cien_botellas %>% 
  filter(upos=="ADJ") #checa que esto sobreescribe los objetos que teníasmo

stats.freq <- txt_freq(stats$token)
stats.freq$key <- factor(stats.freq$key, levels = rev(stats.freq$key)) # ordena

stats.freq[1:25,] %>% 
  ggplot(aes(x=key, y=freq)) +geom_bar(stat="identity") + 
  coord_flip() + labs(y="Frecuencia", x="Adjetivo") + theme_minimal()

Todas las palabras

Cuando analizamos texto hay palabras que son muy comunes.

#Elegir palabras comunes
stopwords("spanish") # de la paquetería quanteda
##   [1] "de"           "la"           "que"          "el"          
##   [5] "en"           "y"            "a"            "los"         
##   [9] "del"          "se"           "las"          "por"         
##  [13] "un"           "para"         "con"          "no"          
##  [17] "una"          "su"           "al"           "lo"          
##  [21] "como"         "más"          "pero"         "sus"         
##  [25] "le"           "ya"           "o"            "este"        
##  [29] "sí"           "porque"       "esta"         "entre"       
##  [33] "cuando"       "muy"          "sin"          "sobre"       
##  [37] "también"      "me"           "hasta"        "hay"         
##  [41] "donde"        "quien"        "desde"        "todo"        
##  [45] "nos"          "durante"      "todos"        "uno"         
##  [49] "les"          "ni"           "contra"       "otros"       
##  [53] "ese"          "eso"          "ante"         "ellos"       
##  [57] "e"            "esto"         "mí"           "antes"       
##  [61] "algunos"      "qué"          "unos"         "yo"          
##  [65] "otro"         "otras"        "otra"         "él"          
##  [69] "tanto"        "esa"          "estos"        "mucho"       
##  [73] "quienes"      "nada"         "muchos"       "cual"        
##  [77] "poco"         "ella"         "estar"        "estas"       
##  [81] "algunas"      "algo"         "nosotros"     "mi"          
##  [85] "mis"          "tú"           "te"           "ti"          
##  [89] "tu"           "tus"          "ellas"        "nosotras"    
##  [93] "vosotros"     "vosotras"     "os"           "mío"         
##  [97] "mía"          "míos"         "mías"         "tuyo"        
## [101] "tuya"         "tuyos"        "tuyas"        "suyo"        
## [105] "suya"         "suyos"        "suyas"        "nuestro"     
## [109] "nuestra"      "nuestros"     "nuestras"     "vuestro"     
## [113] "vuestra"      "vuestros"     "vuestras"     "esos"        
## [117] "esas"         "estoy"        "estás"        "está"        
## [121] "estamos"      "estáis"       "están"        "esté"        
## [125] "estés"        "estemos"      "estéis"       "estén"       
## [129] "estaré"       "estarás"      "estará"       "estaremos"   
## [133] "estaréis"     "estarán"      "estaría"      "estarías"    
## [137] "estaríamos"   "estaríais"    "estarían"     "estaba"      
## [141] "estabas"      "estábamos"    "estabais"     "estaban"     
## [145] "estuve"       "estuviste"    "estuvo"       "estuvimos"   
## [149] "estuvisteis"  "estuvieron"   "estuviera"    "estuvieras"  
## [153] "estuviéramos" "estuvierais"  "estuvieran"   "estuviese"   
## [157] "estuvieses"   "estuviésemos" "estuvieseis"  "estuviesen"  
## [161] "estando"      "estado"       "estada"       "estados"     
## [165] "estadas"      "estad"        "he"           "has"         
## [169] "ha"           "hemos"        "habéis"       "han"         
## [173] "haya"         "hayas"        "hayamos"      "hayáis"      
## [177] "hayan"        "habré"        "habrás"       "habrá"       
## [181] "habremos"     "habréis"      "habrán"       "habría"      
## [185] "habrías"      "habríamos"    "habríais"     "habrían"     
## [189] "había"        "habías"       "habíamos"     "habíais"     
## [193] "habían"       "hube"         "hubiste"      "hubo"        
## [197] "hubimos"      "hubisteis"    "hubieron"     "hubiera"     
## [201] "hubieras"     "hubiéramos"   "hubierais"    "hubieran"    
## [205] "hubiese"      "hubieses"     "hubiésemos"   "hubieseis"   
## [209] "hubiesen"     "habiendo"     "habido"       "habida"      
## [213] "habidos"      "habidas"      "soy"          "eres"        
## [217] "es"           "somos"        "sois"         "son"         
## [221] "sea"          "seas"         "seamos"       "seáis"       
## [225] "sean"         "seré"         "serás"        "será"        
## [229] "seremos"      "seréis"       "serán"        "sería"       
## [233] "serías"       "seríamos"     "seríais"      "serían"      
## [237] "era"          "eras"         "éramos"       "erais"       
## [241] "eran"         "fui"          "fuiste"       "fue"         
## [245] "fuimos"       "fuisteis"     "fueron"       "fuera"       
## [249] "fueras"       "fuéramos"     "fuerais"      "fueran"      
## [253] "fuese"        "fueses"       "fuésemos"     "fueseis"     
## [257] "fuesen"       "siendo"       "sido"         "tengo"       
## [261] "tienes"       "tiene"        "tenemos"      "tenéis"      
## [265] "tienen"       "tenga"        "tengas"       "tengamos"    
## [269] "tengáis"      "tengan"       "tendré"       "tendrás"     
## [273] "tendrá"       "tendremos"    "tendréis"     "tendrán"     
## [277] "tendría"      "tendrías"     "tendríamos"   "tendríais"   
## [281] "tendrían"     "tenía"        "tenías"       "teníamos"    
## [285] "teníais"      "tenían"       "tuve"         "tuviste"     
## [289] "tuvo"         "tuvimos"      "tuvisteis"    "tuvieron"    
## [293] "tuviera"      "tuvieras"     "tuviéramos"   "tuvierais"   
## [297] "tuvieran"     "tuviese"      "tuvieses"     "tuviésemos"  
## [301] "tuvieseis"    "tuviesen"     "teniendo"     "tenido"      
## [305] "tenida"       "tenidos"      "tenidas"      "tened"
stop<-stopwords("spanish") # guarda todas esas palabras en un objeto
stop
##   [1] "de"           "la"           "que"          "el"          
##   [5] "en"           "y"            "a"            "los"         
##   [9] "del"          "se"           "las"          "por"         
##  [13] "un"           "para"         "con"          "no"          
##  [17] "una"          "su"           "al"           "lo"          
##  [21] "como"         "más"          "pero"         "sus"         
##  [25] "le"           "ya"           "o"            "este"        
##  [29] "sí"           "porque"       "esta"         "entre"       
##  [33] "cuando"       "muy"          "sin"          "sobre"       
##  [37] "también"      "me"           "hasta"        "hay"         
##  [41] "donde"        "quien"        "desde"        "todo"        
##  [45] "nos"          "durante"      "todos"        "uno"         
##  [49] "les"          "ni"           "contra"       "otros"       
##  [53] "ese"          "eso"          "ante"         "ellos"       
##  [57] "e"            "esto"         "mí"           "antes"       
##  [61] "algunos"      "qué"          "unos"         "yo"          
##  [65] "otro"         "otras"        "otra"         "él"          
##  [69] "tanto"        "esa"          "estos"        "mucho"       
##  [73] "quienes"      "nada"         "muchos"       "cual"        
##  [77] "poco"         "ella"         "estar"        "estas"       
##  [81] "algunas"      "algo"         "nosotros"     "mi"          
##  [85] "mis"          "tú"           "te"           "ti"          
##  [89] "tu"           "tus"          "ellas"        "nosotras"    
##  [93] "vosotros"     "vosotras"     "os"           "mío"         
##  [97] "mía"          "míos"         "mías"         "tuyo"        
## [101] "tuya"         "tuyos"        "tuyas"        "suyo"        
## [105] "suya"         "suyos"        "suyas"        "nuestro"     
## [109] "nuestra"      "nuestros"     "nuestras"     "vuestro"     
## [113] "vuestra"      "vuestros"     "vuestras"     "esos"        
## [117] "esas"         "estoy"        "estás"        "está"        
## [121] "estamos"      "estáis"       "están"        "esté"        
## [125] "estés"        "estemos"      "estéis"       "estén"       
## [129] "estaré"       "estarás"      "estará"       "estaremos"   
## [133] "estaréis"     "estarán"      "estaría"      "estarías"    
## [137] "estaríamos"   "estaríais"    "estarían"     "estaba"      
## [141] "estabas"      "estábamos"    "estabais"     "estaban"     
## [145] "estuve"       "estuviste"    "estuvo"       "estuvimos"   
## [149] "estuvisteis"  "estuvieron"   "estuviera"    "estuvieras"  
## [153] "estuviéramos" "estuvierais"  "estuvieran"   "estuviese"   
## [157] "estuvieses"   "estuviésemos" "estuvieseis"  "estuviesen"  
## [161] "estando"      "estado"       "estada"       "estados"     
## [165] "estadas"      "estad"        "he"           "has"         
## [169] "ha"           "hemos"        "habéis"       "han"         
## [173] "haya"         "hayas"        "hayamos"      "hayáis"      
## [177] "hayan"        "habré"        "habrás"       "habrá"       
## [181] "habremos"     "habréis"      "habrán"       "habría"      
## [185] "habrías"      "habríamos"    "habríais"     "habrían"     
## [189] "había"        "habías"       "habíamos"     "habíais"     
## [193] "habían"       "hube"         "hubiste"      "hubo"        
## [197] "hubimos"      "hubisteis"    "hubieron"     "hubiera"     
## [201] "hubieras"     "hubiéramos"   "hubierais"    "hubieran"    
## [205] "hubiese"      "hubieses"     "hubiésemos"   "hubieseis"   
## [209] "hubiesen"     "habiendo"     "habido"       "habida"      
## [213] "habidos"      "habidas"      "soy"          "eres"        
## [217] "es"           "somos"        "sois"         "son"         
## [221] "sea"          "seas"         "seamos"       "seáis"       
## [225] "sean"         "seré"         "serás"        "será"        
## [229] "seremos"      "seréis"       "serán"        "sería"       
## [233] "serías"       "seríamos"     "seríais"      "serían"      
## [237] "era"          "eras"         "éramos"       "erais"       
## [241] "eran"         "fui"          "fuiste"       "fue"         
## [245] "fuimos"       "fuisteis"     "fueron"       "fuera"       
## [249] "fueras"       "fuéramos"     "fuerais"      "fueran"      
## [253] "fuese"        "fueses"       "fuésemos"     "fueseis"     
## [257] "fuesen"       "siendo"       "sido"         "tengo"       
## [261] "tienes"       "tiene"        "tenemos"      "tenéis"      
## [265] "tienen"       "tenga"        "tengas"       "tengamos"    
## [269] "tengáis"      "tengan"       "tendré"       "tendrás"     
## [273] "tendrá"       "tendremos"    "tendréis"     "tendrán"     
## [277] "tendría"      "tendrías"     "tendríamos"   "tendríais"   
## [281] "tendrían"     "tenía"        "tenías"       "teníamos"    
## [285] "teníais"      "tenían"       "tuve"         "tuviste"     
## [289] "tuvo"         "tuvimos"      "tuvisteis"    "tuvieron"    
## [293] "tuviera"      "tuvieras"     "tuviéramos"   "tuvierais"   
## [297] "tuvieran"     "tuviese"      "tuvieses"     "tuviésemos"  
## [301] "tuvieseis"    "tuviesen"     "teniendo"     "tenido"      
## [305] "tenida"       "tenidos"      "tenidas"      "tened"

De nuestro UPOS tenemos algunos que no vamos a querer

no_upos<-c("X","SYM","PUNCT")
stats<- cien_botellas %>% 
  filter(!upos%in%no_upos) %>%  #selecciona todos menos estos tipos
  mutate(token=tolower(token)) %>% # cambia a que token no tenga mayúsculas
  filter(!token%in%stop)  # selecciona todas las palabras menos las que están en nuestro vector "stop"

stats.freq <- txt_freq(stats$token)
stats.freq$key <- factor(stats.freq$key, levels = rev(stats.freq$key)) # ordena

Podemos graficar esto y hacer nubes:

stats.freq[1:25,] %>% 
  ggplot(aes(x=key, y=freq)) +geom_bar(stat="identity") + 
  coord_flip() + labs(y="Frecuencia", x="Palabra") + theme_minimal()

Un modelito: RAKE

El algoritmo RAKE, que es el acrónimo de Rapid Automatic Keyword Extraction. Este algoritmo busca palabras clave buscando una secuencia contigua de palabras que no contengan palabras irrelevantes. Es decir, al calcular una puntuación para cada palabra que forma parte de cualquier palabra clave candidata, esto se hace entre las palabras de las palabras clave candidatas, el algoritmo observa cuántas veces aparece cada palabra y cuántas veces se produce con otras palabras, cada palabra obtiene un puntaje que es la razón del grado de la palabra (cuántas veces se produce con otras palabras) a la frecuencia de la palabra. Se calcula un puntaje RAKE para la palabra clave candidata completa sumando los puntajes de cada una de las palabras que definen la palabra clave

stats <- keywords_rake(x = cien_botellas, term = "lemma", group = "doc_id", 
                       relevant = cien_botellas$upos %in% c("NOUN", "ADJ"))

stats$key <- factor(stats$keyword, levels = rev(stats$keyword))

Esto también se puede graficar

stats %>%
  filter(freq>3 & ngram>1) %>% 
  ggplot(aes(x=key, y=rake)) +geom_bar(stat="identity") + 
  coord_flip() + labs(y="RAKE", x="Palabras clave") + theme_minimal()

stats %>%
  filter(rake>0 & ngram>1) %>% 
  ggplot(aes(x=key, y=freq)) +geom_bar(stat="identity") + 
  coord_flip() + labs(y="Freq", x="Palabras clave") + theme_minimal()

# Si queremos guardar esta info

write_csv(stats, "cien_botellas_rake.csv") # lo guarda en nuestro directorio

Correlaciones y co-ocurrencias de palabras

Otro elemento interéses saber qué tan común es que dos palabras vayan juntas.

cooc <- cooccurrence(x = subset(cien_botellas, upos %in% c("NOUN", "ADJ")), 
                     term = "lemma", 
                     group = c("doc_id", "paragraph_id", "sentence_id"))
head(cooc)
##        term1 term2 cooc
## 1        tal   vez   44
## 2    botella pared   43
## 3      negro  pelo   32
## 4 muchachita negro   27
## 5 muchachita  pelo   27
## 6    primero   vez   21

Esto se puede graficar de este modo:

wordnetwork <- cooc[1:30, ] # nos quedan las primera 30 lineas

wordnetwork <- graph_from_data_frame(wordnetwork)

ggraph(wordnetwork, layout = "fr") +
  geom_edge_link(aes(width = cooc, edge_alpha = cooc), edge_colour = "pink") +
  geom_node_text(aes(label = name), col = "darkgreen", size = 4) +
  theme_graph(base_family = "Arial Narrow") +
  theme(legend.position = "none") +
  labs(title = "Cooccurrencias dentro de una oración", subtitle = "Nombres y Adjetivos")

Correlaciones

cien_botellas$id <- unique_identifier(cien_botellas, fields = c("sentence_id", "doc_id"))
dtm <- subset(cien_botellas, upos %in% c("NOUN", "ADJ"))
dtm <- document_term_frequencies(dtm, document = "id", term = "lemma")
dtm <- document_term_matrix(dtm)
dtm <- dtm_remove_lowfreq(dtm, minfreq = 5)

termcorrelations <- dtm_cor(dtm)
y <- as_cooccurrence(termcorrelations)
y <- subset(y, term1 < term2 & abs(cooc) > 0.2)
y <- y[order(abs(y$cooc), decreasing = TRUE), ]
head(y,24)
##                 term1       term2      cooc
## 1008361      bajitico   suavecito 1.0000000
## 649765        caníbal     mayonés 0.9127755
## 1110920      adecuado     vocablo 0.8942776
## 724282        marqués       nieto 0.8898988
## 334564         correo electrónico 0.8450281
## 644332         abuelo     marqués 0.8340696
## 940619        antiguo      romano 0.8251174
## 723682         abuelo       nieto 0.8229009
## 1042140        abuelo         tío 0.8127789
## 1009652     embustera    sublimir 0.7997910
## 1042740       marqués         tío 0.7686678
## 1042815         nieto         tío 0.7583360
## 185210  apartamentico celebérrimo 0.7381629
## 780173          frita      papita 0.7373466
## 197996      campanita       chivo 0.7299915
## 1061334     carapacho      triste 0.7065151
## 656139          cerdo   megaterio 0.6983858
## 785155        botella       pared 0.6943703
## 460418          chivo     gallina 0.6757348
## 1096938        puesto      vianda 0.6757348
## 806859     muchachita        pelo 0.6419273
## 656268          dueña   megaterio 0.6414166
## 574628       cabecita          ja 0.6393838
## 326043          cerdo       dueño 0.5959512

Este objeto y, puede ser muy útil de exportar a un formato compatible con Excel:

write_csv(y, "cien_botellas_corr.csv") # lo guarda en nuestro directorio

Importación desde otros formatos

El formato epub no es el único. Vamos a importar texto desde otro formato y luego tokenizarlo. ## Desde pdf

la_nada_pdf <- pdf_text(path3)

Esto nos da un vector de caracteres y no una matriz

#Es un vector de caracteres, no una matrix
la_nada_pdf[6]
## [1] "1\nMorir por la patria es vivir\nAvoir peur de l’avenir, cela nous facilite la mort.\nTener miedo del futuro, eso nos facilita la muerte.\nMarguerite Yourcenar.\nElla viene de una isla que quiso construir el paraíso. El fuego de la\nagresividad devora su rostro. Los ojos casi siempre húmedos, la boca\nsuplicante como la de una estatua de bronce, la nariz afilada.\nElla es como cualquier mujer, salvo que abre los ojos a la manera de las\nmujeres que habitan las islas: hay una tranquila indiferencia en sus\npárpados. También tiene el cuerpo tenso, en contradicción con sus\npupilas demasiado fluidas. No es verdaderamente bella, pero tiene\nalgo… no sabríamos qué, quizás un rictus de ironía o bien un miedo\nextraordinario. Ella no cambia nunca, no cambiará. Morirá joven y con\ntodos sus deseos.\n—¿Cómo te llamas? —pregunta el Querubín.\nElla cree escuchar la voz de un angelote. Y no responde. El mar informe\nestá detrás de sus pensamientos. De pronto había olvidado su nombre. Y\ntambién borra al angelote.\nTodo se ha vuelto opaco alrededor de su cuerpo. Sus piernas no\nresponden a la orden de avanzar. Ella levita. Sus piernas no existen. ¿Y\nella, ella existe?\nTiene hambre y nada qué comer. Su estómago comprende muy bien que\ndebe resistir. En su isla, cada parte del cuerpo debía aprender a resistir.\nEl sacrificio era la escena cotidiana, como la nada. Morir y vivir: el\nmismo verbo, como por ejemplo reír. Sólo que se reía para no morir a\ncausa del exceso de vida obligatoria.\nEl espacio se transforma en nube blanca, pura. Podríamos imaginar un\nmuro que acaba de ser pintado con lechada. Nadie se acerca a ella.\nAdemás, no hay nadie. Ni siquiera un espíritu. Salvo ella. Creyendo\ntodavía que existe.\nMuy ligera, siempre levitando, encuentra un espejo redondo y, para\npasar el tiempo, refleja su sexo en el azogue. Ciertamente es una\nhembra. Por una pequeña cicatriz de seis puntos entre la vulva y el ano\nha comprendido, recuerda, haber tenido hijos. ¿Cuántos? No sabe. Su\n                                                                            6/81\n"
cat(la_nada_pdf[6])
## 1
## Morir por la patria es vivir
## Avoir peur de l’avenir, cela nous facilite la mort.
## Tener miedo del futuro, eso nos facilita la muerte.
## Marguerite Yourcenar.
## Ella viene de una isla que quiso construir el paraíso. El fuego de la
## agresividad devora su rostro. Los ojos casi siempre húmedos, la boca
## suplicante como la de una estatua de bronce, la nariz afilada.
## Ella es como cualquier mujer, salvo que abre los ojos a la manera de las
## mujeres que habitan las islas: hay una tranquila indiferencia en sus
## párpados. También tiene el cuerpo tenso, en contradicción con sus
## pupilas demasiado fluidas. No es verdaderamente bella, pero tiene
## algo… no sabríamos qué, quizás un rictus de ironía o bien un miedo
## extraordinario. Ella no cambia nunca, no cambiará. Morirá joven y con
## todos sus deseos.
## —¿Cómo te llamas? —pregunta el Querubín.
## Ella cree escuchar la voz de un angelote. Y no responde. El mar informe
## está detrás de sus pensamientos. De pronto había olvidado su nombre. Y
## también borra al angelote.
## Todo se ha vuelto opaco alrededor de su cuerpo. Sus piernas no
## responden a la orden de avanzar. Ella levita. Sus piernas no existen. ¿Y
## ella, ella existe?
## Tiene hambre y nada qué comer. Su estómago comprende muy bien que
## debe resistir. En su isla, cada parte del cuerpo debía aprender a resistir.
## El sacrificio era la escena cotidiana, como la nada. Morir y vivir: el
## mismo verbo, como por ejemplo reír. Sólo que se reía para no morir a
## causa del exceso de vida obligatoria.
## El espacio se transforma en nube blanca, pura. Podríamos imaginar un
## muro que acaba de ser pintado con lechada. Nadie se acerca a ella.
## Además, no hay nadie. Ni siquiera un espíritu. Salvo ella. Creyendo
## todavía que existe.
## Muy ligera, siempre levitando, encuentra un espejo redondo y, para
## pasar el tiempo, refleja su sexo en el azogue. Ciertamente es una
## hembra. Por una pequeña cicatriz de seis puntos entre la vulva y el ano
## ha comprendido, recuerda, haber tenido hijos. ¿Cuántos? No sabe. Su
##                                                                             6/81

Vamos a tokenizar esta página

la_nada_p6<-la_nada_pdf[6]
la_nada<-udpipe(x = la_nada_p6, object=udmodel) #"tokeniza" el texto

Desde .txt

text <- readLines(path4)
amlo<-udpipe(x = text, object=udmodel) #"tokeniza" el texto