Вы находитесь на странице: 1из 36

26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

4 Relaciones entre palabras: n-grams y


correlaciones.
Hasta ahora hemos considerado las palabras como unidades individuales, y hemos considerado
sus relaciones con los sentimientos o con los documentos. Sin embargo, muchos análisis de
texto interesantes se basan en las relaciones entre las palabras, ya sea que examinen qué
palabras tienden a seguir a otras de inmediato, o que tienden a coexistir dentro de los mismos
documentos.

En este capítulo, exploraremos algunos de los métodos que ofrece tidytext para calcular y
visualizar las relaciones entre las palabras en su conjunto de datos de texto. Esto incluye el
token = "ngrams" argumento, que se simboliza por pares de palabras adyacentes en lugar de
por los individuales. También presentaremos dos nuevos paquetes: ggraph , que extiende
ggplot2 para construir diagramas de red, y widyr , que calcula las correlaciones por pares y las
distancias dentro de un marco de datos ordenado. Juntos, expanden nuestra caja de
herramientas para explorar texto dentro del marco de datos ordenado.

4.1 Tokenización por n-gramo

Hemos estado usando la unnest_tokens función de tokenizar por palabra, o algunas veces por
oración, lo cual es útil para los tipos de análisis de frecuencia y sentimiento que hemos estado
haciendo hasta ahora. Pero también podemos usar la función para convertir en secuencias
consecutivas de palabras, llamadas n-grams . Al ver con qué frecuencia la palabra X es seguida
por la palabra Y, podemos construir un modelo de las relaciones entre ellos.

Hacemos esto agregando la token = "ngrams" opción unnest_tokens() y configurando n la


cantidad de palabras que deseamos capturar en cada n-gramo. Cuando establecemos n 2,
estamos examinando pares de dos palabras consecutivas, a menudo llamadas "bigramas":

https://www.tidytextmining.com/ngrams.html 1/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

library(dplyr)
library(tidytext)
library(janeaustenr)

austen_bigrams <- austen_books() %>%


unnest_tokens(bigram, text, token = "ngrams", n = 2)

austen_bigrams

## # A tibble: 725,049 x 2
## book bigram
## <fct> <chr>
## 1 Sense & Sensibility sense and
## 2 Sense & Sensibility and sensibility
## 3 Sense & Sensibility sensibility by
## 4 Sense & Sensibility by jane
## 5 Sense & Sensibility jane austen
## 6 Sense & Sensibility austen 1811
## 7 Sense & Sensibility 1811 chapter
## 8 Sense & Sensibility chapter 1
## 9 Sense & Sensibility 1 the
## 10 Sense & Sensibility the family
## # … with 725,039 more rows

Esta estructura de datos sigue siendo una variación del formato de texto ordenado. Está
estructurado como un token por fila (con metadatos adicionales, como book , aún se conserva),
pero cada token ahora representa un bigrama.

Tenga en cuenta que estos bigramas se superponen: "sentido y" es una señal,
mientras que "y sensibilidad" es otra.

https://www.tidytextmining.com/ngrams.html 2/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

4.1.1 Contando y filtrando n-gramas

Nuestras herramientas de ordenación habituales se aplican igualmente bien al análisis de n-


gramas. Podemos examinar los bigramas más comunes usando dplyr's count() :

austen_bigrams %>%
count(bigram, sort = TRUE)

## # A tibble: 211,236 x 2
## bigram n
## <chr> <int>
## 1 of the 3017
## 2 to be 2787
## 3 in the 2368
## 4 it was 1781
## 5 i am 1545
## 6 she had 1472
## 7 of her 1445
## 8 to the 1387
## 9 she was 1377
## 10 had been 1299
## # … with 211,226 more rows

Como es de esperar, muchos de los bigramas más comunes son pares de palabras comunes (no
interesantes), como of the y to be : lo que llamamos "palabras vacías " (consulte el Capítulo 1
). Este es un momento útil para usar tidyr's separate() , que divide una columna en múltiples
según un delimitador. Esto nos permite separarlo en dos columnas, "word1" y "word2", en cuyo
punto podemos eliminar los casos en los que cualquiera sea una palabra de parada.

https://www.tidytextmining.com/ngrams.html 3/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

library(tidyr)

bigrams_separated <- austen_bigrams %>%


separate(bigram, c("word1", "word2"), sep = " ")

bigrams_filtered <- bigrams_separated %>%


filter(!word1 %in% stop_words$word) %>%
filter(!word2 %in% stop_words$word)

# new bigram counts:


bigram_counts <- bigrams_filtered %>%
count(word1, word2, sort = TRUE)

bigram_counts

## # A tibble: 33,421 x 3
## word1 word2 n
## <chr> <chr> <int>
## 1 sir thomas 287
## 2 miss crawford 215
## 3 captain wentworth 170
## 4 miss woodhouse 162
## 5 frank churchill 132
## 6 lady russell 118
## 7 lady bertram 114
## 8 sir walter 113
## 9 miss fairfax 109
## 10 colonel brandon 108
## # … with 33,411 more rows

Podemos ver que los nombres (ya sea el primero y el último o con un saludo) son las parejas
más comunes en los libros de Jane Austen.

https://www.tidytextmining.com/ngrams.html 4/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

En otros análisis, podemos querer trabajar con las palabras recombinadas. La unite() función
de tidyr es la inversa de separate() , y nos permite recombinar las columnas en una sola. Por lo
tanto, “separar / filtrar / contar / unir” nos permite encontrar los bigramas más comunes que no
contienen palabras clave.

bigrams_united <- bigrams_filtered %>%


unite(bigram, word1, word2, sep = " ")

bigrams_united

## # A tibble: 44,784 x 2
## book bigram
## <fct> <chr>
## 1 Sense & Sensibility jane austen
## 2 Sense & Sensibility austen 1811
## 3 Sense & Sensibility 1811 chapter
## 4 Sense & Sensibility chapter 1
## 5 Sense & Sensibility norland park
## 6 Sense & Sensibility surrounding acquaintance
## 7 Sense & Sensibility late owner
## 8 Sense & Sensibility advanced age
## 9 Sense & Sensibility constant companion
## 10 Sense & Sensibility happened ten
## # … with 44,774 more rows

En otros análisis puede interesarle los trigramas más comunes, que son secuencias
consecutivas de 3 palabras. Podemos encontrar esto configurando n = 3 :

https://www.tidytextmining.com/ngrams.html 5/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

austen_books() %>%
unnest_tokens(trigram, text, token = "ngrams", n = 3) %>%
separate(trigram, c("word1", "word2", "word3"), sep = " ") %>%
filter(!word1 %in% stop_words$word,
!word2 %in% stop_words$word,
!word3 %in% stop_words$word) %>%
count(word1, word2, word3, sort = TRUE)

## # A tibble: 8,757 x 4
## word1 word2 word3 n
## <chr> <chr> <chr> <int>
## 1 dear miss woodhouse 23
## 2 miss de bourgh 18
## 3 lady catherine de 14
## 4 catherine de bourgh 13
## 5 poor miss taylor 11
## 6 sir walter elliot 11
## 7 ten thousand pounds 11
## 8 dear sir thomas 10
## 9 twenty thousand pounds 8
## 10 replied miss crawford 7
## # … with 8,747 more rows

4.1.2 Analizando bigramas

Este formato de un bigrama por fila es útil para los análisis exploratorios del texto. Como un
simple ejemplo, podríamos estar interesados en las “calles” más comunes que se mencionan en
cada libro:

bigrams_filtered %>%
filter(word2 == "street") %>%
count(book, word1, sort = TRUE)

https://www.tidytextmining.com/ngrams.html 6/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

## # A tibble: 34 x 3
## book word1 n
## <fct> <chr> <int>
## 1 Sense & Sensibility berkeley 16
## 2 Sense & Sensibility harley 16
## 3 Northanger Abbey pulteney 14
## 4 Northanger Abbey milsom 11
## 5 Mansfield Park wimpole 10
## 6 Pride & Prejudice gracechurch 9
## 7 Sense & Sensibility conduit 6
## 8 Sense & Sensibility bond 5
## 9 Persuasion milsom 5
## 10 Persuasion rivers 4
## # … with 24 more rows

Un bigrama también puede tratarse como un término en un documento de la misma manera que
tratamos palabras individuales. Por ejemplo, podemos ver el tf-idf (Capítulo 3 ) de los bigramas
en las novelas de Austen. Estos valores de tf-idf pueden visualizarse dentro de cada libro, tal
como lo hicimos con las palabras (Figura 4.1 ).

bigram_tf_idf <- bigrams_united %>%


count(book, bigram) %>%
bind_tf_idf(bigram, book, n) %>%
arrange(desc(tf_idf))

bigram_tf_idf

https://www.tidytextmining.com/ngrams.html 7/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

## # A tibble: 36,217 x 6
## book bigram n tf idf tf_idf
## <fct> <chr> <int> <dbl> <dbl> <dbl>
## 1 Persuasion captain wentworth 170 0.0299 1.79 0.0535
## 2 Mansfield Park sir thomas 287 0.0287 1.79 0.0515
## 3 Mansfield Park miss crawford 215 0.0215 1.79 0.0386
## 4 Persuasion lady russell 118 0.0207 1.79 0.0371
## 5 Persuasion sir walter 113 0.0198 1.79 0.0356
## 6 Emma miss woodhouse 162 0.0170 1.79 0.0305
## 7 Northanger Abbey miss tilney 82 0.0159 1.79 0.0286
## 8 Sense & Sensibility colonel brandon 108 0.0150 1.79 0.0269
## 9 Emma frank churchill 132 0.0139 1.79 0.0248
## 10 Pride & Prejudice lady catherine 100 0.0138 1.79 0.0247
## # … with 36,207 more rows

https://www.tidytextmining.com/ngrams.html 8/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

Figura 4.1: Los 12 bigrams con el mayor tf-idf de cada novela de Jane Austen

Por mucho que descubrimos en el Capítulo 3 , las unidades que distinguen cada libro de Austen
son casi exclusivamente nombres. También notamos algunas combinaciones de un verbo común
y un nombre, como "contestó elizabeth" en Pride & Prejudice, o "lloró emma" en Emma.

Hay ventajas y desventajas al examinar el tf-idf de los bigramas en lugar de las palabras
individuales. Los pares de palabras consecutivas pueden capturar una estructura que no está
presente cuando uno solo está contando palabras individuales, y puede proporcionar un contexto
que hace que los tokens sean más comprensibles (por ejemplo, "pulteney street", en Northanger

https://www.tidytextmining.com/ngrams.html 9/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

Abbey, es más informativo que "pulteney") . Sin embargo, los conteos por bigrama también son
más dispersos : un par de dos palabras típico es más raro que cualquiera de sus palabras
componentes. Por lo tanto, los bigramas pueden ser especialmente útiles cuando tienes un
conjunto de datos de texto muy grande.

4.1.3 Uso de bigrams para proporcionar contexto en el


análisis de sentimientos

Nuestro enfoque de análisis de sentimientos en el Capítulo 2 simplemente contó la aparición de


palabras positivas o negativas, de acuerdo con un léxico de referencia. Uno de los problemas
con este enfoque es que el contexto de una palabra puede importar tanto como su presencia.
Por ejemplo, las palabras "feliz" y "me gusta" se considerarán positivas, incluso en una oración
como "¡No soy feliz y no me gusta !"

Ahora que tenemos los datos organizados en bigrams, es fácil saber con qué frecuencia las
palabras van precedidas por una palabra como "no":

bigrams_separated %>%
filter(word1 == "not") %>%
count(word1, word2, sort = TRUE)

https://www.tidytextmining.com/ngrams.html 10/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

## # A tibble: 1,246 x 3
## word1 word2 n
## <chr> <chr> <int>
## 1 not be 610
## 2 not to 355
## 3 not have 327
## 4 not know 252
## 5 not a 189
## 6 not think 176
## 7 not been 160
## 8 not the 147
## 9 not at 129
## 10 not in 118
## # … with 1,236 more rows

Al realizar un análisis de sentimiento en los datos del bigrama, podemos examinar con qué
frecuencia las palabras asociadas con el sentimiento están precedidas por "no" u otras palabras
negativas. Podríamos usar esto para ignorar o incluso revertir su contribución al puntaje del
sentimiento.

Usemos el léxico AFINN para el análisis de sentimientos, que puede recordar que otorga una
puntuación numérica de sentimiento para cada palabra, con números positivos o negativos que
indican la dirección del sentimiento.

AFINN <- get_sentiments("afinn")

AFINN

https://www.tidytextmining.com/ngrams.html 11/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

## # A tibble: 2,476 x 2
## word score
## <chr> <int>
## 1 abandon -2
## 2 abandoned -2
## 3 abandons -2
## 4 abducted -2
## 5 abduction -2
## 6 abductions -2
## 7 abhor -3
## 8 abhorred -3
## 9 abhorrent -3
## 10 abhors -3
## # … with 2,466 more rows

Luego podemos examinar las palabras más frecuentes que fueron precedidas por "no" y que se
asociaron con un sentimiento.

not_words <- bigrams_separated %>%


filter(word1 == "not") %>%
inner_join(AFINN, by = c(word2 = "word")) %>%
count(word2, score, sort = TRUE)

not_words

https://www.tidytextmining.com/ngrams.html 12/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

## # A tibble: 245 x 3
## word2 score n
## <chr> <int> <int>
## 1 like 2 99
## 2 help 2 82
## 3 want 1 45
## 4 wish 1 39
## 5 allow 1 36
## 6 care 2 23
## 7 sorry -1 21
## 8 leave -1 18
## 9 pretend -1 18
## 10 worth 2 17
## # … with 235 more rows

Por ejemplo, la palabra asociada al sentimiento más común para seguir "no" era "me gusta", que
normalmente tendría una puntuación (positiva) de 2.

Vale la pena preguntar qué palabras contribuyeron más en la dirección "incorrecta". Para
calcularlo, podemos multiplicar su puntuación por la cantidad de veces que aparecen (de modo
que una palabra con una puntuación de +3 aparece 10 veces más impacto que una palabra con
una puntuación de sentimiento de +1 ocurriendo 30 veces). Visualizamos el resultado con un
gráfico de barras (Figura 4.2 ).

https://www.tidytextmining.com/ngrams.html 13/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

library(ggplot2)

not_words %>%
mutate(contribution = n * score) %>%

arrange(desc(abs(contribution))) %>%
head(20) %>%
mutate(word2 = reorder(word2, contribution)) %>%
ggplot(aes(word2, n * score, fill = n * score > 0)) +
geom_col(show.legend = FALSE) +
xlab("Words preceded by \"not\"") +
ylab("Sentiment score * number of occurrences") +
coord_flip()

https://www.tidytextmining.com/ngrams.html 14/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

Figura 4.2: Las 20 palabras precedidas por "no" que tuvieron la mayor contribución a los
puntajes de sentimiento, en una dirección positiva o negativa

Los bigramas "no me gusta" y "no ayuda" fueron abrumadoramente las principales causas de
identificación errónea, haciendo que el texto pareciera mucho más positivo de lo que es. Pero
podemos ver frases como "sin miedo" y "no fallar" a veces sugerir que el texto es más negativo
de lo que es.

"No" no es el único término que proporciona algún contexto para la siguiente palabra. Podríamos
elegir cuatro palabras comunes (o más) que nieguen el término subsiguiente, y usar el mismo
enfoque de unir y contar para examinarlos todos a la vez.

negation_words <- c("not", "no", "never", "without")

negated_words <- bigrams_separated %>%


filter(word1 %in% negation_words) %>%
inner_join(AFINN, by = c(word2 = "word")) %>%
count(word1, word2, score, sort = TRUE)

Luego podríamos visualizar cuáles son las palabras más comunes para seguir cada negación en
particular (Figura 4.3 ). Si bien "no me gusta" y "no ayuda" siguen siendo los dos ejemplos más
comunes, también podemos ver parejas como "no muy bueno" y "nunca amado". Podríamos
combinar esto con los enfoques en el Capítulo 2 para revertir las puntuaciones de AFINN De
cada palabra que sigue una negación. Estos son solo algunos ejemplos de cómo encontrar
palabras consecutivas puede dar contexto a los métodos de minería de texto.

https://www.tidytextmining.com/ngrams.html 15/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

Figura 4.3: Las palabras positivas o negativas más comunes para seguir negaciones como
'nunca', 'no', 'no' y 'sin'

4.1.4 Visualizando una red de bigramas con ggraph

Es posible que estemos interesados en visualizar todas las relaciones entre las palabras
simultáneamente, en lugar de solo las mejores a la vez. Como una visualización común,
podemos organizar las palabras en una red o "gráfico". Aquí nos referiremos a un "gráfico" no en

https://www.tidytextmining.com/ngrams.html 16/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

el sentido de una visualización, sino como una combinación de nodos conectados. Un gráfico se
puede construir a partir de un objeto ordenado ya que tiene tres variables:

de : el nodo del que viene una arista


a : el nodo hacia donde va un borde
peso : un valor numérico asociado con cada borde

El paquete igraph tiene muchas funciones poderosas para manipular y analizar redes. Una forma
de crear un objeto igraph a partir de datos ordenados es la graph_from_data_frame() función,
que toma un marco de datos de bordes con columnas para los atributos "desde", "hasta" y de
borde (en este caso n ):

library(igraph)

# original counts
bigram_counts

## # A tibble: 33,421 x 3
## word1 word2 n
## <chr> <chr> <int>
## 1 sir thomas 287
## 2 miss crawford 215
## 3 captain wentworth 170
## 4 miss woodhouse 162
## 5 frank churchill 132
## 6 lady russell 118
## 7 lady bertram 114
## 8 sir walter 113
## 9 miss fairfax 109
## 10 colonel brandon 108
## # … with 33,411 more rows

https://www.tidytextmining.com/ngrams.html 17/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

# filter for only relatively common combinations


bigram_graph <- bigram_counts %>%
filter(n > 20) %>%
graph_from_data_frame()

bigram_graph

## IGRAPH f0c5564 DN-- 91 77 --


## + attr: name (v/c), n (e/n)
## + edges from f0c5564 (vertex names):
## [1] sir ->thomas miss ->crawford captain ->wentworth miss ->woodhouse
## [5] frank ->churchill lady ->russell lady ->bertram sir ->walter
## [9] miss ->fairfax colonel ->brandon miss ->bates lady ->catherine
## [13] sir ->john jane ->fairfax miss ->tilney lady ->middleton
## [17] miss ->bingley thousand->pounds miss ->dashwood miss ->bennet
## [21] john ->knightley miss ->morland captain ->benwick dear ->miss
## [25] miss ->smith miss ->crawford's henry ->crawford miss ->elliot
## [29] dr ->grant miss ->bertram sir ->thomas's ten ->minutes
## + ... omitted several edges

igraph tiene funciones de trazado incorporadas, pero no son para lo que está diseñado el
paquete, por lo que muchos otros paquetes han desarrollado métodos de visualización para
objetos gráficos. Recomendamos el paquete ggraph (Pedersen 2017 ) , porque implementa
estas visualizaciones en términos de la gramática de los gráficos, con los que ya estamos
familiarizados con ggplot2.

Podemos convertir un objeto igraph en un ggraph con la ggraph función, después de lo cual le
agregamos capas, al igual que las capas se agregan en ggplot2. Por ejemplo, para un gráfico
básico necesitamos agregar tres capas: nodos, bordes y texto.

https://www.tidytextmining.com/ngrams.html 18/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

library(ggraph)
set.seed(2017)

ggraph(bigram_graph, layout = "fr") +


geom_edge_link() +
geom_node_point() +
geom_node_text(aes(label = name), vjust = 1, hjust = 1)

https://www.tidytextmining.com/ngrams.html 19/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

Figura 4.4: Bigrames comunes en las novelas de Jane Austen, que muestran las que ocurrieron
más de 20 veces y donde ninguna de las palabras era una palabra de alto.

En la Figura 4.4 , podemos visualizar algunos detalles de la estructura del texto. Por ejemplo,
vemos que las salutaciones como "señorita", "dama", "señor", "y" coronel "forman centros
comunes de nodos, a menudo seguidos de nombres. También vemos parejas o trillizos a lo largo
del exterior que forman frases cortas comunes ("media hora", "mil libras" o "tiempo corto /
pausa").

Concluimos con unas pocas operaciones de pulido para hacer un gráfico de mejor aspecto
(Figura 4.5 ):

Agregamos la edge_alpha estética a la capa de enlace para hacer que los enlaces sean
transparentes según lo común o raro que sea el bigrama.
Añadimos direccionalidad con una flecha, construida usando grid::arrow() , incluida una
end_cap opción que le dice a la flecha que termine antes de tocar el nodo
Probamos las opciones de la capa de nodos para hacer que los nodos sean más atractivos
(más grandes, puntos azules)
Añadimos un tema que es útil para trazar redes, theme_void()

set.seed(2016)

a <- grid::arrow(type = "closed", length = unit(.15, "inches"))

ggraph(bigram_graph, layout = "fr") +


geom_edge_link(aes(edge_alpha = n), show.legend = FALSE,
arrow = a, end_cap = circle(.07, 'inches')) +
geom_node_point(color = "lightblue", size = 5) +
geom_node_text(aes(label = name), vjust = 1, hjust = 1) +
theme_void()

https://www.tidytextmining.com/ngrams.html 20/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

Figura 4.5: Bigrames comunes en las novelas de Jane Austen, con algo de pulido.

Puede tomar algo de experimentación con ggraph para que sus redes tengan un formato
presentable como este, pero la estructura de la red es una forma útil y flexible de visualizar datos
ordenados relacionales.

Tenga en cuenta que esta es una visualización de una cadena de Markov , un


modelo común en el procesamiento de texto. En una cadena de Markov, cada
elección de palabra depende solo de la palabra anterior. En este caso, un generador
aleatorio que sigue este modelo podría escupir "querido", luego "señor", luego "william
https://www.tidytextmining.com/ngrams.html 21/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

/ walter / thomas / thomas", siguiendo cada palabra hasta las palabras más comunes
que lo siguen. Para hacer que la visualización sea interpretable, optamos por mostrar
solo las conexiones palabra a palabra más comunes, pero uno podría imaginar un
gráfico enorme que represente todas las conexiones que ocurren en el texto.

4.1.5 Visualizar bigramas en otros textos.

Trabajamos mucho en la limpieza y visualización de bigramas en un conjunto de datos de texto,


por lo que vamos a recopilarlo en una función para que podamos realizarla fácilmente en otros
conjuntos de datos de texto.

Para facilitar el uso del count_bigrams() y visualize_bigrams() usted, también


hemos recargado los paquetes necesarios para ellos.

https://www.tidytextmining.com/ngrams.html 22/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

library(dplyr)
library(tidyr)
library(tidytext)
library(ggplot2)
library(igraph)

library(ggraph)

count_bigrams <- function(dataset) {


dataset %>%
unnest_tokens(bigram, text, token = "ngrams", n = 2) %>%
separate(bigram, c("word1", "word2"), sep = " ") %>%
filter(!word1 %in% stop_words$word,
!word2 %in% stop_words$word) %>%
count(word1, word2, sort = TRUE)
}

visualize_bigrams <- function(bigrams) {


set.seed(2016)
a <- grid::arrow(type = "closed", length = unit(.15, "inches"))

bigrams %>%
graph_from_data_frame() %>%
ggraph(layout = "fr") +
geom_edge_link(aes(edge_alpha = n), show.legend = FALSE, arrow = a) +
geom_node_point(color = "lightblue", size = 5) +
geom_node_text(aes(label = name), vjust = 1, hjust = 1) +
theme_void()
}

En este punto, podríamos visualizar bigramas en otras obras, como la versión King James de la
Biblia:

https://www.tidytextmining.com/ngrams.html 23/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

# the King James version is book 10 on Project Gutenberg:


library(gutenbergr)
kjv <- gutenberg_download(10)

library(stringr)

kjv_bigrams <- kjv %>%


count_bigrams()

# filter out rare combinations, as well as digits


kjv_bigrams %>%
filter(n > 40,
!str_detect(word1, "\\d"),
!str_detect(word2, "\\d")) %>%
visualize_bigrams()

https://www.tidytextmining.com/ngrams.html 24/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

Figura 4.6: Gráfica dirigida de bigramas comunes en la Biblia de King James, que muestra los
que ocurrieron más de 40 veces

Por lo tanto, la figura 4.6 presenta un "modelo" común de lenguaje dentro de la Biblia,
especialmente centrado en "tu" y "tú" (¡lo que probablemente podría ser considerado palabras de
parada!) Puedes usar el paquete gutenbergr y estas count_bigrams /
visualize_bigrams funciones para visualizar bigramas en otros libros clásicos que te interesan.

4.2 Contando y correlacionando pares de palabras


con el paquete widyr

La simulación por n-gramo es una forma útil de explorar pares de palabras adyacentes. Sin
embargo, también nos pueden interesar las palabras que tienden a coexistir en documentos o
capítulos específicos, incluso si no aparecen uno junto al otro.

Los datos ordenados son una estructura útil para comparar variables o agrupar por filas, pero
puede ser difícil comparar entre filas: por ejemplo, contar la cantidad de veces que aparecen dos
palabras dentro del mismo documento o ver qué tan relacionadas están . La mayoría de las
operaciones para encontrar conteos por pares o correlaciones deben convertir primero los datos
en una matriz amplia.

https://www.tidytextmining.com/ngrams.html 25/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

Figura 4.7: La filosofía detrás del paquete widyr, que puede realizar operaciones como contar y
correlacionar en pares de valores en un conjunto de datos ordenado. El paquete widyr primero
'convierte' un conjunto de datos ordenado en una matriz amplia, realiza una operación como una
correlación en él, luego vuelve a ordenar el resultado.

Examinaremos algunas de las formas en que el texto ordenado se puede convertir en una amplia
matriz en el Capítulo 5 , pero en este caso no es necesario. El paquete widyr hace que las
operaciones tales como cómputos y correlaciones sean fáciles, al simplificar el patrón de
“ampliar datos, realizar una operación y luego volver a ordenar los datos” (Figura 4.7 ). Nos
centraremos en un conjunto de funciones que hacen comparaciones por pares entre grupos de
observaciones (por ejemplo, entre documentos o secciones de texto).

4.2.1 Conteo y correlación entre secciones.

https://www.tidytextmining.com/ngrams.html 26/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

Considere el libro "Orgullo y prejuicio" dividido en secciones de 10 líneas, como lo hicimos (con
secciones más grandes) para el análisis de sentimientos en el Capítulo 2 . Podemos estar
interesados en qué palabras tienden a aparecer en la misma sección.

austen_section_words <- austen_books() %>%


filter(book == "Pride & Prejudice") %>%
mutate(section = row_number() %/% 10) %>%
filter(section > 0) %>%
unnest_tokens(word, text) %>%
filter(!word %in% stop_words$word)

austen_section_words

## # A tibble: 37,240 x 3
## book section word
## <fct> <dbl> <chr>
## 1 Pride & Prejudice 1 truth

## 2 Pride & Prejudice 1 universally


## 3 Pride & Prejudice 1 acknowledged
## 4 Pride & Prejudice 1 single
## 5 Pride & Prejudice 1 possession
## 6 Pride & Prejudice 1 fortune
## 7 Pride & Prejudice 1 wife
## 8 Pride & Prejudice 1 feelings
## 9 Pride & Prejudice 1 views
## 10 Pride & Prejudice 1 entering
## # … with 37,230 more rows

Una función útil de widyr es la pairwise_count() función. El prefijo pairwise_ significa que dará
como resultado una fila para cada par de palabras en la word variable. Esto nos permite contar
pares de palabras comunes que aparecen simultáneamente en la misma sección:

https://www.tidytextmining.com/ngrams.html 27/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

library(widyr)

# count words co-occuring within sections


word_pairs <- austen_section_words %>%
pairwise_count(word, section, sort = TRUE)

word_pairs

## # A tibble: 796,008 x 3
## item1 item2 n
## <chr> <chr> <dbl>
## 1 darcy elizabeth 144
## 2 elizabeth darcy 144
## 3 miss elizabeth 110
## 4 elizabeth miss 110
## 5 elizabeth jane 106
## 6 jane elizabeth 106
## 7 miss darcy 92
## 8 darcy miss 92
## 9 elizabeth bingley 91

## 10 bingley elizabeth 91
## # … with 795,998 more rows

Tenga en cuenta que si bien la entrada tenía una fila para cada par de un documento (una
sección de 10 líneas) y una palabra, la salida tiene una fila para cada par de palabras. Este es
también un formato ordenado, pero de una estructura muy diferente que podemos usar para
responder nuevas preguntas.

Por ejemplo, podemos ver que el par de palabras más común en una sección es "Elizabeth" y
"Darcy" (los dos personajes principales). Podemos encontrar fácilmente las palabras que ocurren
con más frecuencia con Darcy:

https://www.tidytextmining.com/ngrams.html 28/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

word_pairs %>%
filter(item1 == "darcy")

## # A tibble: 2,930 x 3
## item1 item2 n
## <chr> <chr> <dbl>
## 1 darcy elizabeth 144
## 2 darcy miss 92
## 3 darcy bingley 86
## 4 darcy jane 46
## 5 darcy bennet 45
## 6 darcy sister 45
## 7 darcy time 41
## 8 darcy lady 38
## 9 darcy friend 37
## 10 darcy wickham 37
## # … with 2,920 more rows

4.2.2 Correlación por pares

Parejas como "Elizabeth" y "Darcy" son las palabras más comunes que ocurren con frecuencia,
pero eso no es particularmente significativo ya que también son las palabras individuales más
comunes. En su lugar, podemos querer examinar la correlación entre las palabras, lo que indica
con qué frecuencia aparecen juntas en relación con la frecuencia con que aparecen por
separado.

En particular, aquí nos centraremos en el coeficiente phi , una medida común para la correlación
binaria. El enfoque del coeficiente phi es cuánto más probable es que sea tanto la palabra X e Y
aparecen, o no hacer, lo que parece que uno sin el otro.

Considere la siguiente tabla:

https://www.tidytextmining.com/ngrams.html 29/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

Tiene la palabra Y Ninguna palabra y Total

Tiene la palabra x n 11 n 10 n 1 ⋅

Ninguna palabra x n 01 n 00 n 0 ⋅

Total n ⋅ 1 n ⋅ 0 norte

n 11 n 00 n 10 n 01

n 11 n 00 - n 10 n 01
ϕ =
√ n 1 ⋅ n 0 ⋅ n ⋅ 0 n ⋅ 1

El coeficiente phi es equivalente a la correlación de Pearson, que puede haber


escuchado en otra parte, cuando se aplica a datos binarios).

La pairwise_cor() función en widyr nos permite encontrar el coeficiente phi entre las palabras
según la frecuencia con la que aparecen en la misma sección. Su sintaxis es similar a la
pairwise_count() .

# we need to filter for at least relatively common words first


word_cors <- austen_section_words %>%
group_by(word) %>%
filter(n() >= 20) %>%
pairwise_cor(word, section, sort = TRUE)

word_cors

https://www.tidytextmining.com/ngrams.html 30/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

## # A tibble: 154,842 x 3
## item1 item2 correlation
## <chr> <chr> <dbl>
## 1 bourgh de 0.951
## 2 de bourgh 0.951
## 3 pounds thousand 0.701
## 4 thousand pounds 0.701
## 5 william sir 0.664
## 6 sir william 0.664
## 7 catherine lady 0.663
## 8 lady catherine 0.663
## 9 forster colonel 0.622
## 10 colonel forster 0.622
## # … with 154,832 more rows

Este formato de salida es útil para la exploración. Por ejemplo, podríamos encontrar las palabras
más correlacionadas con una palabra como "libras" mediante una filter operación.

word_cors %>%
filter(item1 == "pounds")

https://www.tidytextmining.com/ngrams.html 31/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

## # A tibble: 393 x 3
## item1 item2 correlation
## <chr> <chr> <dbl>
## 1 pounds thousand 0.701
## 2 pounds ten 0.231
## 3 pounds fortune 0.164
## 4 pounds settled 0.149
## 5 pounds wickham's 0.142
## 6 pounds children 0.129
## 7 pounds mother's 0.119
## 8 pounds believed 0.0932
## 9 pounds estate 0.0890
## 10 pounds ready 0.0860
## # … with 383 more rows

Esto nos permite escoger palabras interesantes particulares y encontrar las otras palabras más
asociadas con ellas (Figura 4.8 ).

word_cors %>%
filter(item1 %in% c("elizabeth", "pounds", "married", "pride")) %>%
group_by(item1) %>%
top_n(6) %>%
ungroup() %>%
mutate(item2 = reorder(item2, correlation)) %>%
ggplot(aes(item2, correlation)) +
geom_bar(stat = "identity") +
facet_wrap(~ item1, scales = "free") +
coord_flip()

https://www.tidytextmining.com/ngrams.html 32/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

Figura 4.8: Palabras de Orgullo y Prejuicio que se correlacionaron más con 'elizabeth', 'libras',
'matrimonio' y 'orgullo'

Así como usamos ggraph para visualizar bigrams, podemos usarlo para visualizar las
correlaciones y grupos de palabras que se encontraron en el paquete widyr (Figura 4.9 ).

https://www.tidytextmining.com/ngrams.html 33/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

set.seed(2016)

word_cors %>%
filter(correlation > .15) %>%
graph_from_data_frame() %>%
ggraph(layout = "fr") +
geom_edge_link(aes(edge_alpha = correlation), show.legend = FALSE) +
geom_node_point(color = "lightblue", size = 5) +
geom_node_text(aes(label = name), repel = TRUE) +
theme_void()

https://www.tidytextmining.com/ngrams.html 34/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

Figura 4.9: Pares de palabras en Orgullo y prejuicio que muestran al menos una correlación de
.15 de aparecer dentro de la misma sección de 10 líneas

Tenga en cuenta que a diferencia del análisis del bigrama, las relaciones aquí son simétricas, en
lugar de direccionales (no hay flechas). También podemos ver que mientras que los pares de
nombres y títulos que dominaron los pares de bigram son comunes, como "coronel / fitzwilliam",
también podemos ver pares de palabras que aparecen cerca uno del otro, como "caminar" y
"estacionar", o "baile" y "pelota".

https://www.tidytextmining.com/ngrams.html 35/36
26-04-2019 4 Relaciones entre palabras: n-grams y correlaciones | Minería de textos con R

4.3 Resumen

Este capítulo mostró cómo el enfoque de texto ordenado es útil no solo para analizar palabras
individuales, sino también para explorar las relaciones y conexiones entre palabras. Dichas
relaciones pueden involucrar n-gramas, que nos permiten ver qué palabras tienden a aparecer
después de otras, o co-ocurrencias y correlaciones, para palabras que aparecen cerca unas de
otras. Este capítulo también demostró el paquete ggraph para visualizar ambos tipos de
relaciones como redes. Estas visualizaciones de red son una herramienta flexible para explorar
relaciones, y desempeñarán un papel importante en los estudios de caso en capítulos
posteriores.

Referencias

Pedersen, Thomas Lin. 2017. ggraph: una implementación de gramática de gráficos para
gráficos y redes . https://cran.r-project.org/package=ggraph .

https://www.tidytextmining.com/ngrams.html 36/36

Вам также может понравиться