Comprendamos primeramente que es el análisis de texto.

El análisis de texto es un proceso de fragmentación de párrafos o comunicaciones escritas, en oraciones y en palabras, a partir de un separador definido, por ejemplo, un espacio. Con el fin de medir frecuencias de palabras, relaciones entre ellas o los sentimientos que evocan cada palabra.

Ejemplo 1

veamos un breve ejemplo de lo dicho anteriormente:

library(tidyverse)
library(tidytext)
wd= "C:/Users/danie/OneDrive/Escritorio/Laboratorio I"
setwd(wd)
discurso <- read_lines("texto.txt", skip = 4)
mensaje <- tibble (parrafo= seq_along(discurso),
                   texto = discurso)
## # A tibble: 1,230 × 2
##    parrafo texto                                                                
##      <int> <chr>                                                                
##  1       1 ########## FIN ENCABEZADO ##########                                 
##  2       2 – I –                                                                
##  3       3 En Marzo de 1808, y cuando habían transcurrido cuatro meses desde qu…
##  4       4 Mi vida al principio era tan triste y tan uniforme como aquel oficio…
##  5       5 Necesito explicarme mejor. Yo pensaba en la huérfana Inés, y todos l…
##  6       6 –Mi amiga está en Aranjuez con su reverendo tío, el padre D. Celesti…
##  7       7 Cuando no me ocupaba en estas alabanzas, departía mentalmente con el…
##  8       8 ¡Aquellos pensamientos y este mecanismo todas las horas, todos los d…
##  9       9 Pero la alegría no estaba sino en el alma. El sábado es el precursor…
## 10      10 Con voluble atención observo todos los accidentes del camino, y mis …
## # … with 1,220 more rows

Para este caso, utilizaremos dos librerias muy conocidas para la mineria de texto llamadas tidyverse() y tidytex(), seguidamente establecemos un directorio de trabajo y usaremos un texto de ejemplo (“texto”), dividimos un texto en parrafos con la función tibble, a lo que finalmente le haremos el proceso de tokenizacion para cada palabra del corpus

Tokens

realizando nuestro proceso de tokenizacion tenemos que tener encuenta algunos factores importantes, como lo son las mayusculas y algunos signos de puntuación dado que R puede llegar a todar la “A” y la “a” como tokens diferentes dificultando todo el proceso de análisis

mensaje_palabras <-  mensaje %>% unnest_tokens(palabra, texto)

mensaje %>%
  unnest_tokens(palabra,
                texto,
                to_lower = FALSE)
## # A tibble: 67,863 × 2
##    parrafo palabra   
##      <int> <chr>     
##  1       1 FIN       
##  2       1 ENCABEZADO
##  3       2 I         
##  4       3 En        
##  5       3 Marzo     
##  6       3 de        
##  7       3 1808      
##  8       3 y         
##  9       3 cuando    
## 10       3 habían    
## # … with 67,853 more rows

En este caso vemos como cada palabra ya fue dividida recuerden que, con la función unnest_tokens() le estás ordenando que extraiga todas y cada una de las palabras que conforman el texto que hay almacenado en mensaje y que las guarde en la columna palabra de la nueva tabla que le has dicho que se llamará mensaje_palabras

Frecuencia de palabras

la frecuencia con la que se repiten algunas palabras pueden ser muy utiles para nuestos análisis, con nuestro anterior ejemplo tenemos de mayor a menor, en la primera colmuna la palabra en cuestión y en la segunda colmuna la cantidad con que esta se repite, para este ejemplo las palabras que mas se repiten logicamente son conectores, sin embargo estos no son muy utiles para el análisis, por lo que posteriormente mostraremos como depurarlos.

mensaje_palabras %>%
  count(palabra,
        sort = TRUE)
## # A tibble: 10,705 × 2
##    palabra     n
##    <chr>   <int>
##  1 de       3491
##  2 que      2454
##  3 la       2290
##  4 y        2196
##  5 a        1668
##  6 el       1420
##  7 en       1406
##  8 no       1156
##  9 los       971
## 10 se        795
## # … with 10,695 more rows

Ejemplo 2

Para este segundo ejemplo usaremos las siguientes librerias las cuales se usaran más que todo para la grafiación de nuestro análisis.

library(tm)
library(SnowballC)
library(RColorBrewer)
library(wordcloud)
library(ggplot2)
library(dplyr)
library(readr)
library(cluster)

Establecemos nuevamente la ruta de trabajo para prepara nuestro texto (“quince”) denominado corpus.

wd= "C:/Users/danie/OneDrive/Escritorio/Laboratorio I"
setwd(wd)

nov_raw <- read_lines("quince.txt") #n_max, skip
str(nov_raw)
##  chr [1:313] "Cuento de Charles Bukowski: Quince centímetros" ...

para este ejemplo el texto lo que haremos es ampliar los parrafos del texto para 10 repeticiones, lo usaremos para que el grupo sea de 10 reglones cada uno de estos parrafos seran vectores que posteriormente usaremos para unirlo con nuestro texto.

diez <- rep(1:ceiling(length(nov_raw)/10), each = 10) # para hacer gurpos de 10 reglones 
diez <- diez[1:length(nov_raw)]

nov_text <- cbind(diez, nov_raw) %>% data.frame()

Ahora pues, concatenaremos los reglones con la función aggregate donde finalmente obtenemos una matriz de 32x1

formula = nov_raw ~ diez
nov_text <- aggregate(formula,
                      data = nov_text,
                      FUN = paste,
                      collapse = " ")
nov_text <- nov_text %>% select(nov_raw) %>% as.matrix
dim(nov_text)
## [1] 32  1

Limpieza de datos

Una vez realizado nuestro proceso de tokenizacion procedemos a limpiar o depurar caracteres especiales, muletillas, puntuación y espacios vacios excesivos.

nov_text <- gsub("[[:cntrl:]]", " ", nov_text) #eliminar caracteresespeciales 

nov_text <- tolower(nov_text) # convertir el texto en minusculas 

nov_text <- removeWords(nov_text, words = stopwords("spanish")) # para eliminar preposicion y muletillas 

nov_text <- removePunctuation(nov_text) # elimina la puntuacion 

nov_text <- stripWhitespace(nov_text) # eliminamos espacios vacios excesivos 

Corpus y graficas

Análisando nuestro corpus podemos ver que esta compuesto por 32 documentos

nov_corpus <- Corpus(VectorSource(nov_text))
nov_corpus
## <<SimpleCorpus>>
## Metadata:  corpus specific: 1, document level (indexed): 0
## Content:  documents: 32

las siguientes graficas son apartir del corpus.

wordcloud(nov_corpus,
          max.words = 80, random.order = F, colors = brewer.pal(name = "Dark2", n = 8))

Con este tipo de grafico podemos observar que, las palabras más grandes son las que más se repiten, en nuestra historia podemos observar como Sara es nuestra protagonista.

Algunas palabras como algunos conectores que aparecen en el anterior grafico no son de mucha utilidad por lo que depuraremos estas para acercarnos un poco más a un mejor análsis.

nov_text <- removeWords(nov_text, words = c( "dijo", "tan", "después", "aquel", "así", "aún", "sino", "entonces", "aunque"))
    nov_corpus <- nov_text %>% VectorSource() %>% Corpus()
    nov_ptd <- nov_corpus %>% tm_map(PlainTextDocument)
   
     wordcloud(
      nov_corpus, max.words = 80, 
      random.order = F, 
      colors=brewer.pal(name = "Dark2", n = 8)
    )   

Con esto podemos observar un breve resumen del texto.

nov_tdm <- TermDocumentMatrix(nov_corpus) # asociacion entre palabras
     nov_tdm
## <<TermDocumentMatrix (terms: 1128, documents: 32)>>
## Non-/sparse entries: 1674/34422
## Sparsity           : 95%
## Maximal term length: 17
## Weighting          : term frequency (tf)

Frecuencia de palabras

Veamos pues para este ejemplo la frecuencia con la que son usadas algunas palabras

nov_mat <- as.matrix(nov_tdm)
dim(nov_mat)
## [1] 1128   32
nov_mat <- nov_mat %>% rowSums() %>% sort(decreasing = TRUE)
nov_mat <- data.frame(palabra = names(nov_mat), frec = nov_mat)

nov_mat[1:20,]
##                 palabra frec
## —                     —   46
## sara               sara   32
## luego             luego   21
## cerveza         cerveza   15
## centímetros centímetros   14
## vez                 vez   14
## —¿                   —¿   12
## noche             noche   12
## alfiler         alfiler   11
## allí               allí    9
## empezó           empezó    9
## harry             harry    9
## cada               cada    9
## podía             podía    8
## quince           quince    8
## veces             veces    8
## cabeza           cabeza    8
## hacia             hacia    8
## bien               bien    7
## hacer             hacer    7

Adicionalmente grafiquemos la frecuencia de esto solo usaremos las 10 palabras con más frecuencia.

nov_mat[1:10, ] %>%
  ggplot(aes(palabra, frec)) +
  geom_bar(stat = "identity", color = "black", fill = "#FFBA61") +
  geom_text(aes(hjust = 1.3, label = frec)) + 
  coord_flip() + 
  labs(title = "Diez palabras más frecuentes",  x = "Palabras", y = "Número de usos")

nov_mat %>%
  mutate(perc = (frec/sum(frec))*100) %>%
  .[1:10, ] %>%
  ggplot(aes(palabra, perc)) +
  geom_bar(stat = "identity", color = "black", fill = "#FFBA61") +
  geom_text(aes(hjust = 1.3, label = round(perc, 2))) + 
  coord_flip() +
  labs(title = "Diez palabras más frecuentes", x = "Palabras", y = "Porcentaje de uso")

Asociaciones entre palabras

Estas asociaciones nos pertimirar ver la relación que tienen algunas palabras con otras podemos buscar una palabra especifica a la cual queremos ver su asociacion.

findAssocs(nov_tdm, terms = c( "sara", "hombre"), corlimit = .60)     
## $sara
## apenas 
##   0.71 
## 
## $hombre
##          parte       abiertas        acabase       adelante     aproximaba 
##           0.68           0.66           0.66           0.66           0.66 
##        aquella        arderme       arqueaba      arremetía          atrás 
##           0.66           0.66           0.66           0.66           0.66 
##          barca       bolsitas         bosque          capas       cerveza— 
##           0.66           0.66           0.66           0.66           0.66 
##         cuerpo          curvo          dedos        dentro…       despacio 
##           0.66           0.66           0.66           0.66           0.66 
##        espalda         gancho         gemido          gemir   insoportable 
##           0.66           0.66           0.66           0.66           0.66 
##         jadeos        lanzaba        llénalo          monín        moverme 
##           0.66           0.66           0.66           0.66           0.66 
##      oscuridad        oxígeno            oía         pegaba          pelos 
##           0.66           0.66           0.66           0.66           0.66 
##          peste        piernas        poquito        posible   presintiendo 
##           0.66           0.66           0.66           0.66           0.66 
##           puse       realidad     repugnante       respirar         rígido 
##           0.66           0.66           0.66           0.66           0.66 
##       sufriría superiluminado       superior       terrible verdaderamente 
##           0.66           0.66           0.66           0.66           0.66 
##       —saborea           cosa 
##           0.66           0.64

eliminamos terminos dispersos para tener mas claridad en nuestro analisis y compararmos

nov_new <- removeSparseTerms(nov_tdm, sparse = .85)
#texto anterior
nov_tdm
## <<TermDocumentMatrix (terms: 1128, documents: 32)>>
## Non-/sparse entries: 1674/34422
## Sparsity           : 95%
## Maximal term length: 17
## Weighting          : term frequency (tf)
#texto nuevo
nov_new    
## <<TermDocumentMatrix (terms: 28, documents: 32)>>
## Non-/sparse entries: 211/685
## Sparsity           : 76%
## Maximal term length: 11
## Weighting          : term frequency (tf)

vemos como pasamos de tener 1128 terminos a 28 solamente por lo que nuestro analisis sera mucho mas facil.

Graficar asociaciones.

Para ello tenemos dos metodos el primero llamado hclust y el segundo llamado Agnes ambos metodos trabajan de forma matricial por tanto tenemos que transformar las matrices y sus distancias.

#transformacion de matriz 
nov_new <- nov_new %>% as.matrix()

#Matriz de distancia
nov_new <- nov_new / rowSums(nov_new)
nov_dist <- dist(nov_new, method = "euclidian")

con el metodo de hclust tenemos las siguiente grafica de asociación, donde las palabras mas alejadas son las menos asociadas que lo podemos ver a trabajes de cuadros

nov_hclust <-  hclust(nov_dist, method = "ward.D")

plot(nov_hclust, main = "Dendrograma - hclust", sub = "", xlab = "")
rect.hclust(nov_hclust, k = 10, border="red")

la diferencia con el metodo de agnes en realidad no es muy grande, sin embargo, este metodo nos muestra con más claridad las palabras mas aisladas de la asociación.

nov_agnes <- agnes(nov_dist, method = "average")
plot(nov_agnes, which.plots = 2, main = "Dendrograma - Agnes", sub = "", xlab = "")
rect.hclust(nov_agnes, k = 10, border = "red")