¿Se puede resolver de forma «automática»?
00:01 (hora local). Aterrizaje efectuado sin dificultad. Propulsión convencial (ampliada). Velocidad de aterrizaje: 6:30 de la escala convencional (restringida). Velocidad en el momento del amaraje: 4 de la escala Bajo-U 109 de la escala Molina-Calvo. Cubicaje: AZ-0.3. Denominación local del lugar de aterrizaje: Sardanyola.
Así empieza uno de mis libros favoritos, «Sin noticias de Gurb», en el que Eduardo Mendoza nos contaba la historia de un extraterrestre recién aterrizado en Barcelona, con el objetivo de encontrar a un compañero perdido. Y es que si tuviéramos que elaborar un método en estas primeras semanas de 2022 para detectar si una persona acaba de llegar del espacio exterior, no habría uno mejor que preguntarle: «¿has jugado a WORDLE?»
Figure 1: Wordle, el juego de moda: https://www.powerlanguage.co.uk/wordle/
Este sencillo juego, que imita la dinámica del famoso Master Mind, no tiene muchas reglas pero es «adictivo»: una palabra, 5 letras, y 6 intentos para adivinar el vocablo mientras la aplicación te indica en cada paso que letras están bien colocadas (o mal colocadas o si directamente no aparecen en la palabra). No solo choca su sencillez sino que además es una web distinta a las que hoy nos tiene acostumbrados la red: sin pop-ups, sin anuncios, sin cookies, sin vídeos que se reproducen solos. Nada. Solo un juego, una interfaz sencilla (pero visualmente atractiva) que no reporta ningún beneficio a su creador, el ingenierio de software Josh Wardle. Un juego que, aunque ha alcanzado la categoría de fenómeno de masas a finales de 2021 y principios de 2022, nació además de una historia de amor, como relata el autor al periodista del New York Times Daniel Victor en esta entrevistahttps://www.nytimes.com/2022/01/03/technology/wordle-word-game-creator.html
Por si alguien llega a esta entrada sin conocer el juego, lo explicamos. El objetivo consiste en adivinar una palabra de 5 letras.
Figure 2: Wordle, el juego de moda: https://www.powerlanguage.co.uk/wordle/
En cada intento el juego nos indica con amarillo las letras que están en la palabra (pero mal colocadas), en verde las letras que están en la palabra y correctamente colocadas, y en gris las letras que no están en la palabra. Con esas pistas, el usuario tiene 6 intentos y solo podrá jugar una palabra al día (quizás esa sea una de las claves de las ganas de seguir jugando).
Figure 3: Wordle, el juego de moda: https://www.powerlanguage.co.uk/wordle/
Desde unas semanas el juego también cuenta con su versión en castellano, https://wordle.danielfrg.com/, adaptado por Daniel Rodríguez, y su versión en catalán, https://gelozp.com/games/wordle/, adaptada por Gerard López, y no han sido pocos los medios que han dedicado sus espacios a hablar de él.
Artículo de Xataka de la versión en castellano: https://www.xataka.com/videojuegos/habla-daniel-rodriguez-creador-wordle-espanol-asi-adapto-dos-tardes-juego-online-moda
Entrevista a Gerard López: https://www.xataka.com/videojuegos/habla-daniel-rodriguez-creador-wordle-espanol-asi-adapto-dos-tardes-juego-online-moda
Incluso no son pocos los matemáticos y estadísticos que se han lanzado a intentar analizar el juego, las opciones de ganar y la forma en la que juegan sus usuarios. Es el caso de Esteban Moro, a quién entrevistaban hace unos días en El País contando su estrategia para el juego en inglés, el caso del investigador y divulgador Picanúmeros o yo mismo.
El jueguito del Wordle lo está petando estos días.
— 📊⛏ Picanúmeros (@Picanumeros) January 9, 2022
Yo, que no tengo remedio, he analizado vuestros resultados… y en este hilo os muestro mis conclusiones.
tl;dr:
- Se nos da mal el inglés, pero bien el Wordle
- Aprendemos de nuestros errores
- El progreso depende del idioma
👇 pic.twitter.com/5lIukdSjOB
La estrategia de un investigador español para ganar el 99% de las veces al Wordle, el juego de moda en internet: https://elpais.com/tecnologia/2022-01-12/la-estrategia-de-un-investigador-espanol-para-ganar-al-wordle-el-99-de-las-veces.html?utm_source=Twitter&ssm=TW_CM#Echobox=1641975837
Las matemáticas detrás del fenómeno Wordle para ganar antes que nadie: https://www.elconfidencial.com/tecnologia/2022-01-13/matematicas-wordle-juego-estadistica_3357239/
Todo lo contenido en este documento está libremente disponible en GitHub https://github.com/dadosdelaplace/blog-R
Paquetes de R
que vamos a necesitar
{tidyverse}
: tratamiento y procesamiento de datos.{skimr}
: resúmenes numéricos{purrr}
: tratamiento de listas{glue}
: concatenación de cadenas de texto.Además para la creación de este tutorial he usado {rmarkdown}
con el paquete {distill}
, el paquete {tweetrmd}
para incrustar enlaces de Twitter, el paquete {DT}
para las tablas interactivas y {ggtext}
para fuentes en las gráficas. Si quieres empezar a programar en R
desde cero tienes por aquí materiales gratuitos https://dadosdelaplace.github.io/courses
Dado que se trata de un juego de adivinar palabras en castellano, lo primero que vamos a hacer es analizar (de forma muy de «andar por casa») cómo se comportan las palabras y letras en el castellano, así que necesitamos es un conjunto de palabras con las que trabajar.
Seguramente se pueda scrappear la web oficial del juego, en castellano https://wordle.danielfrg.com/, pero ando escaso de tiempo así que no he podido extraer el historial de palabras que se han jugado hasta ahora (si alguien se anima, todo suyo/a).
Extraer un listado de palabras de la RAE tampoco es sencillo ya que la propia institución no lo pone fácil, hasta el absurdo que su listado de palabras y definiciones no son de uso libre y tiene copyright, como ha comentado en varias ocasiones Jaime Gómez Obregón
Sin perjuicio de otros, el idioma español me parece maravilloso. Tiene un verbo, cerner, para describir la acción del polen cayendo de las flores. Y un nombre específico para la espuma de la cerveza: giste.
— Jaime Gómez-Obregón (@JaimeObregon) July 19, 2020
Lo que no está a la altura es su Diccionario de @RAEinforma. Me explico.
Dichos impedimentos hacen incluso difícil saber el número de palabras totales en castellano que la RAE incluye en el diccionario. Según la propia institución:
«Es imposible saber el número de palabras de una lengua. La última edición del diccionario académico (2014), registraba 93 111 artículos y 195 439 acepciones
#RAEconsultas Es imposible saber el número de palabras de una lengua. La última edición del diccionario académico (2014), registraba 93 111 artículos y 195 439 acepciones.
— RAE (@RAEinforma) January 23, 2019
Lo que si pone la RAE a nuestra disposición es el Corpus de Referencia del Español Actual (CREA). El CREA es un «conjunto de textos de diversa procedencia, almacenados en soporte informático, del que es posible extraer información para estudiar las palabras, sus significados y sus contextos». El corpus de referencia de la RAE cuenta con 152 560 documentos analizados, producidos en los países de habla hispana desde 1975 hasta 2004 (sesgo de selección, parte I), y seleccionados tanto de libros como de periódicos y revistas (sesgo de selección, parte II), y lo tienes en bruto en mi repositorio. Para su lectura podemos usar read_delim()
del paquete stringr
(cargado en el entorno {tidyverse}
).
# Corpus de Referencia del Español Actual (CREA)
# https://corpus.rae.es/lfrecuencias.html
datos_brutos_CREA <- # read
read_delim(file = "./CREA_bruto.txt", delim = "\t")
Dicho fichero lo he preprocesado para hacer más fácil su lectura. El archivo preprocesado lo tienes disponible en CREA_procesado.csv y el código que he ejecutado lo tienes debajo.
📝Código
# Eliminamos columna de orden y separamos última columna en dos
datos_CREA <-
datos_brutos_CREA[, -1] %>%
separate(col = 2, sep = "\t",
into = c("frec_abs", "frec_norm"))
# Renombramos columnas
names(datos_CREA) <- c("palabra", "frec_abs", "frec_norm")
# Convertimos a número que vienen como cadenas de texto
datos_CREA <- datos_CREA %>%
mutate(frec_abs = as.numeric(gsub(",", "", frec_abs)),
frec_norm = as.numeric(frec_norm))
# convertimos tildes
datos_CREA <-
datos_CREA %>%
mutate(palabra = gsub(" ", "", iconv(palabra, "latin1")))
La carga desde el archivo ya preprocesado puede hacerse con read_csv()
.
# Archivo ya preprocesado
datos_CREA <- read_csv(file = "./CREA_procesado.csv")
Tras cargarlo, dado que en el juego en castellano no se admiten tildes, pero si la letra ñ
, he decidido eliminar todas las tildes, acentos y diéresis del CREA y he eliminado duplicados (por ejemplo, mi
y mí
tras quitar tildes). Tienes debajo en 📝Código un resumen numérico y el código R
.
# Quitamos tildes pero no queremos eliminar la ñ
datos_CREA <- datos_CREA %>%
mutate(palabra =
gsub("ö", "o",
gsub("ä", "a",
gsub("ò", "o",
gsub("ï", "i",
gsub("ô", "o",
gsub("â", "a",
gsub("ë", "e",
gsub("ê", "e",
gsub("ã", "a",
gsub("î", "i",
gsub("ù", "u",
gsub("¢", "c",
gsub("ì", "i",
gsub("è", "e",
gsub("à", "a", gsub("ç", "c",
gsub("á", "a",
gsub("é", "e",
gsub("í", "i",
gsub("ó", "o",
gsub("ú", "u",
gsub("ü", "u",
as.character(palabra)))))))))))))))))))))))) %>%
# eliminamos duplicados
distinct(palabra, .keep_all = TRUE) %>%
# Eliminamos palabras con '
filter(!grepl("'", palabra) & !grepl("ø", palabra))
datos_CREA %>% skim()
Name | Piped data |
Number of rows | 693402 |
Number of columns | 3 |
_______________________ | |
Column type frequency: | |
character | 1 |
numeric | 2 |
________________________ | |
Group variables | None |
Variable type: character
skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
---|---|---|---|---|---|---|---|
palabra | 0 | 1 | 1 | 30 | 0 | 693402 | 0 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
frec_abs | 0 | 1 | 217.22 | 19637.76 | 1 | 1 | 2.00 | 9.00 | 9999518.00 | ▇▁▁▁▁ |
frec_norm | 0 | 1 | 1.42 | 128.72 | 0 | 0 | 0.01 | 0.05 | 65545.55 | ▇▁▁▁▁ |
Tras este preprocesamiento nuestro corpus se compone aproximadamente de 700 000 palabras/vocablos, de las que tenemos su frecuencia absoluta frec_abs
(nº de documentos analizados en los que aparece) y frecuencia normalizada frec_norm
(veces que aparece por cada 1000 documentos).
datos_CREA
# A tibble: 693,402 × 3
palabra frec_abs frec_norm
<chr> <dbl> <dbl>
1 de 9999518 65546.
2 la 6277560 41149.
3 que 4681839 30689.
4 el 4569652 29953.
5 en 4234281 27755.
6 y 4180279 27401.
7 a 3260939 21375.
8 los 2618657 17165.
9 se 2022514 13257.
10 del 1857225 12174.
# … with 693,392 more rows
Además, he calculado los siguientes parámetros de cada una de las palabras (tienes el código colapsado debajo) por si nos son de utilidad:
frec_rel
: la frecuencia relativa (proporción de palabras).log_frec_abs
: el logaritmo de las frecuencias absolutas.log_frec_rel
: la frecuencia relativa de log_frec_abs
.int_frec_norm
: una variable intervalo para categorizar las palabras en función de las veces que se repiten.nletras
: número de letras de cada palabra.📝Código
datos_CREA <- datos_CREA %>%
mutate(# frec. relativa
frec_relativa = frec_abs / sum(frec_abs),
# log(frec. absolutas)
log_frec_abs = log(frec_abs),
# log(frec. normalizadas)
log_frec_rel = log_frec_abs / sum(log_frec_abs),
# distribución de frec_norm
int_frec_norm =
cut(frec_norm,
breaks = c(-Inf, 0.01, 0.05, 0.1, 0.5, 1:5,
10, 20, 40, 60, 80, Inf)),
# número de letras
nletras = nchar(palabra))
¿Cómo se distribuyen las frecuencias de las palabras? Si nos fijamos en cómo se reparten las palabras y sus repeticiones a lo largo de los más de 150 000 documentos analizados, obtenemos que el 75% de los vocablos que contiene CREA aparecen, como mucho, en 5 de cada 100 000 documentos.
quantile(datos_CREA$frec_norm)
0% 25% 50% 75% 100%
0.00 0.00 0.01 0.05 65545.55
datos_CREA %>% skim()
Name | Piped data |
Number of rows | 693402 |
Number of columns | 8 |
_______________________ | |
Column type frequency: | |
character | 1 |
factor | 1 |
numeric | 6 |
________________________ | |
Group variables | None |
Variable type: character
skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
---|---|---|---|---|---|---|---|
palabra | 0 | 1 | 1 | 30 | 0 | 693402 | 0 |
Variable type: factor
skim_variable | n_missing | complete_rate | ordered | n_unique | top_counts |
---|---|---|---|---|---|
int_frec_norm | 0 | 1 | FALSE | 15 | (-I: 423578, (0.: 99155, (0.: 71980, (0.: 38683 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
frec_abs | 0 | 1 | 217.22 | 19637.76 | 1 | 1 | 2.00 | 9.00 | 9999518.00 | ▇▁▁▁▁ |
frec_norm | 0 | 1 | 1.42 | 128.72 | 0 | 0 | 0.01 | 0.05 | 65545.55 | ▇▁▁▁▁ |
frec_relativa | 0 | 1 | 0.00 | 0.00 | 0 | 0 | 0.00 | 0.00 | 0.07 | ▇▁▁▁▁ |
log_frec_abs | 0 | 1 | 1.41 | 1.83 | 0 | 0 | 0.69 | 2.20 | 16.12 | ▇▁▁▁▁ |
log_frec_rel | 0 | 1 | 0.00 | 0.00 | 0 | 0 | 0.00 | 0.00 | 0.00 | ▇▁▁▁▁ |
nletras | 0 | 1 | 8.97 | 2.95 | 1 | 7 | 9.00 | 11.00 | 30.00 | ▂▇▂▁▁ |
Es importante advertir que el CREA contiene aproximadamente 8 veces más vocablos que palabras hay registradas en la RAE (según la propia RAE). A diferencia de un diccionario, en CREA no solo hay palabras registradas oficialmente en castellano sino que recopila todo un conjunto de vocablos que aparecen en textos, que no siempre tienen porque estar «validadas» en los diccionarios, incluidos americanismos). Por ello, vamos a hacer un filtro inicial, eliminando aquellas palabras muy poco frecuentes, definiendo como poco frecuente toda aquella palabra que aparezca con una frecuencia inferior a 1 de cada 1000 textos analizados o más (aproximadamente 45 000 vocablos).
📝Código
datos_CREA_filtrado <- datos_CREA %>% filter(frec_norm >= 1)
datos_CREA_filtrado
# A tibble: 40,655 × 8
palabra frec_abs frec_norm frec_relativa log_frec_abs log_frec_rel
<chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 de 9999518 65546. 0.0664 16.1 0.0000164
2 la 6277560 41149. 0.0417 15.7 0.0000160
3 que 4681839 30689. 0.0311 15.4 0.0000157
4 el 4569652 29953. 0.0303 15.3 0.0000156
5 en 4234281 27755. 0.0281 15.3 0.0000156
6 y 4180279 27401. 0.0278 15.2 0.0000155
7 a 3260939 21375. 0.0217 15.0 0.0000153
8 los 2618657 17165. 0.0174 14.8 0.0000151
9 se 2022514 13257. 0.0134 14.5 0.0000148
10 del 1857225 12174. 0.0123 14.4 0.0000147
# … with 40,645 more rows, and 2 more variables: int_frec_norm <fct>,
# nletras <int>
Tras dicho filtrado, he hecho una tabla con las 10 000 palabras más repetidas en frecuencia absoluta, y la tabla con las 500 palabras menos repetidas (pero que aparecen en 1 de cada 1000 documentos analizados, o más), por si quieres curiosear algunas de ellas escribiendo en el buscador.
Palabras más repetidas en CREA (las 12 000 primeras)