¿Cuál será la religión más positiva o negativa? — Análisis de sentimientos de Libros Sagrados con R

Análisis de dogmas religiosos explorando sus Libros Sagrados (La Biblia, El Corán, El Dhammapada y El Libro de Mormón) con R

Dashboard para visualizar plots generados de Análisis de sentimentos de Libros Sagrados con R. Link al final del articulo

Se estima que alrededor del mundo existen cerca de 10,000 religiones actualmente, de las cuales el 80% de la población afín a alguna, principalmente pertenece al cristianismo, protestantismo, islam, budismo, ó hinduísmo. En su gran mayoría, toda religión tiene sus bases fundamentadas en sus propias escrituras sagradas, libros que definen los preceptos y filosofía de cada corriente religiosa, textos que funcionan como una fiel guía de una vida para sus creyentes. Factores como la geografía y la familia en la que nacimos son determinantes pues nuestros padres son los primeros en inculcarnos estas creencias desde la cuna.

Llegamos a determinada edad en la que aceptamos como verdad absoluta estas creencias, o bien lo revaloramos, para optar quizás por otro camino espiritual. Cualquiera que sea tu posición, el objetivo de este artículo no es poner en duda tus creencias, simplemente es ponerte en perspectiva desde un punto de vista analítico, una comparación objetiva entre cuatro de los Libros Sagrados pertenecientes a cuatro de las religiones con mayores seguidores mundialmente: La Biblia (Cristianismo), El Corán (Islam), El Dhammapada (Budismo) y El Libro de Mormón (Movimiento de los Santos de los Últimos Días). Me pareció interesante compartir algunos interesantes hallazgos, como qué sentimientos expresan estos textos, que similutes o diferencias tienen, entre otras cosas. Claro que tú puedes realizar tus propios análisis con los que desees.

¿En dónde puedo obtener los textos de los Libros Sagrados?

Serviría encontrar cualquier versión de los textos sagrados en formato pdf, o txt para trabajarlos. Me pareció práctico para este ejemplo ahorrar esa parte y hacer uso del package “gutenbergr”, que permite extraer del sitio web de “Project Gutenberg” los textos anteriormente mencionados. Para quien no conoce este sitio web, a grandes rasgos se trata de una librería de más de 60,000 eBooks de dominio público, donde puedes descargar libros en distintos formatos gratis o leerlos en línea.

Screenshot: Sitio web Project Gutenberg

Lectura de los textos de los Libros Sagrados

Lo primero que tienes que hacer es establecer los packages que usarás para este ejemplo, comenzando con un nuevo script en R.

# PACKAGES REQUERIDOSlibrary(gutenbergr)
library(dplyr)
library(tidytext)
library(ggplot2)
library(tidyr)
library(wordcloud)
library(reshape2)
# EN CASO DE NO CONTAR CON "ggradar":
# devtools::install_github("ricardo-bion/ggradar", dependencies = TRUE)
library(ggradar)
library(gridExtra)
library(igraph)
library(ggraph)

Usar el package “gutenbergr” es sencillo, sólo tienes que realizar la búsqueda de los libros que elijas, para usar la función “gutenberg_download(ebook_number)” donde “ebook_number” es el identificador del libro, que encontrarás en los datos bibliográficos, e incluso en la url del libro. Por ejemplo, en el caso de La Biblia (King James Version), encontramos que su ebook number es el 30.

Screenshot: Sitio web Project Gutemberg

De esta manera podremos identificar el ebook number de cada Libro Sagrado, para trabajar sus textos en R.

# EXTRAER DE PROJECT GUTEMBERG: LA BIBLIA, EL LIBRO DE MORMÓN, EL DHAMMAPADA Y EL CORÁNtheBible <- gutenberg_download(30)
names(theBible) <- c("book","text")
theBible$book <- "The Bible"
bookMormon <- gutenberg_download(17)
names(bookMormon) <- c("book","text")
bookMormon$book<- "The Book of Mormon"
dhammapada <- gutenberg_download(35185)
names(dhammapada) <- c("book","text")
dhammapada$book<- "Dhammapada"
theQuran <- gutenberg_download(7440)
names(theQuran) <- c("book","text")
theQuran$book<- "The Quran"

Crear un nuevo Data Set, limpiar y separar palabras de los Libros Sagrados

Lo siguiente que tienes que hacer es crear un solo Data Set, compuesto de los textos de los Libros Sagrados, para posteriormente cargarlo, realizar limpieza de datos y separar por el número de línea de texto, para finalmente separar las palabras.

# CREAR UN SOLO DATA SET Y GUARDAR EN UN RDATAallHolybooks <- rbind(theBible,bookMormon,dhammapada,theQuran)
allHolybooks <- allHolybooks[allHolybooks$text !="",]
allHolybooks$text <- gsub('[[:punct:]]|[[:digit:]]','',allHolybooks$text)
rm(theBible,dhammapada,theQuran,bookMormon)save(list = ls(),file = "allHolybooks.Rdata")# CARGAR NUEVO DATA SET, LIMPIAR Y SEPARAR PALABRASload("allHolybooks.Rdata")cleanHolybooks <- allHolybooks %>%
group_by(book) %>%
mutate(numberLine = row_number()) %>%
ungroup()
vocabulary <- cleanHolybooks %>%
unnest_tokens(word, text)
vocabulary<- filter(vocabulary, nchar(vocabulary$word)>2)vocabulary<- vocabulary %>%
group_by(book) %>%
mutate(idx = round(100*(numberLine/max(numberLine)),0))
data(stop_words)cleanTerms <- vocabulary %>%
anti_join(stop_words)

¿Cuáles son las palabras que más se repiten en todos los Libros Sagrados?

Esta podría ser una primera pregunta a responder. Puedes observar dentro de los cuatro Libros Sagrados, cuáles son las palabras que más se repiten, estableciendo un mínimo de más de 2,300 veces.

# PLOT PALABRAS MÁS REPETIDAS EN TODOS LOS LIBROS SAGRADOScleanTerms %>%
count(word, sort = TRUE) %>%
filter(n > 2300) %>%
mutate(word = reorder(word, n)) %>%
ggplot(aes(n, word)) +
geom_bar(stat = "identity", fill="steelblue")+
ylab("word") + xlab("# times repeated") +
ggtitle("Most repeated words in all Holy Books", "> 2300 times") +
coord_flip()

Hay que tener en cuenta claro, que la extensión de El Dhammapada por ejemplo, es muy pero muy pequeña en comparación con los demás Libros Sagrados. Podrás visualizar que la palabra “God” (Dios) predomina. repitiéndose en más de 7,500 ocasiones.

Análisis de sentimientos de Libros Sagrados con R— Plot de palabras que se repiten más en todos los Libros Sagrados.

¿Qué tan negativos o positivos son los sentimientos expresados a lo largo de cada Libro Sagrado?

Gracias al package “tidytext” para minería de texto, utilizando tidy tools como “dplyr” y “tidyr”, puedes responder a esta pregunta realizando el análisis de sentimientos de cada Libro Sagrado, indexado por qué tan positivo o negativo resultan de principio a fin.

# ANÁLISIS DE SENTIMIENTOS INDEXADO POR SENTIMIENTOS NEGATIVOS Y POSITIVOSbooksSentiments <- vocabulary %>%
inner_join(get_sentiments("bing")) %>%
count(book, index = idx, sentiment) %>%
spread(sentiment, n, fill = 0) %>%
mutate(sentiment = positive - negative)
booksSentiments<- booksSentiments %>%
group_by(book) %>%
mutate(centeredSentiment = as.numeric(scale(sentiment)))
# PLOT FLUJO DE SENTIMIENTOS EN LOS LIBROS SAGRADOSggplot(booksSentiments, aes(index, centeredSentiment, fill=as.factor(sentiment>0))) +
geom_bar(stat = "identity", show.legend = FALSE) +
geom_segment(mapping=aes(x=0, y=0, xend=103, yend=0),
arrow=arrow(angle = 30,length = unit(0.05, "inches"),
ends = "last", type = "closed"),
size=0.05, color="#5b5b5b") +
facet_wrap(~book, ncol = 1) +
scale_x_continuous(label=function(x){return(paste0(x, "%"))}) +
scale_fill_manual("",values = c("#cf0a00","#1a954d")) +
labs(x= expression("trayectoria del libro de principio a fin"),
y= "sentimientos") +
ggtitle("Flujo de sentimientos en los Libros Sagrados", "Escalado y centrado \n") +
theme_bw() +
theme(legend.position="none",
panel.border = element_blank(),
panel.grid.major = element_line(colour = "#f9f9f9"),
strip.text.x = element_text(size=11,hjust=0.05,face="plain"),
strip.background = element_blank())

Obtendrás el siguiente plot, donde podrás visualizar los sentimientos centrados y escalados. A simple vista puedes observar por ejemplo, que La Biblia muestra tener mayormente sentimientos positivos hacia su final, en comparación con el principio del libro. Es difícil a simple vista emitir un juicio acertado sobre cuál de los cuatro Libros Sagrados resulta más positivo o negativo, pero queda claro que todos poseen en sus textos ambas polaridades. No existe un sólo libro que se exprese completamente positivo o completamente negativo, sin embargo, podemos profundizar en detalles de cada uno.

Análisis de sentimientos de Libros Sagrados con R— Plot de sentimientos negativos y positivos expresados en los Libros Sagrados.

Puedes dar un vistazo un poco más profundo, creando una nube de palabras por cada Libro Sagrado, que muestre las palabras más representativas dentro de los sentimientos negativos y positivos.

# NUBE DE PALABRAS DE SENTIMIENTO POSITIVO Y NEGATIVO MÁS GRANDE POR CADA LIBRO SANTOcleanTerms %>%
filter(book=="The Bible") %>%
filter(idx=="53") %>%
inner_join(get_sentiments("bing")) %>%
count(word, sentiment, sort = TRUE) %>%
acast(word ~ sentiment, value.var = "n", fill = 0) %>%
comparison.cloud(colors = c("#cf0a00","#1a954d"),
random.order=FALSE,
rot.per=0,
max.words = 100)

Sólo tienes que replicar el código anterior tres veces más, filtrando por el título del resto de libros en la primer función “filter()” para obtener un plot de wordcloud por cada libro, como los siguientes. Es curioso observar que aparentemente el único Libro Sagrado que le da una relevancia a la palabra “libertad” (“Free”) y “placer” (“Pleasure”) es El Dhammapada, del Budismo; o que, por ejemplo, tiene un gran peso la palabra “infidels” con una connotación negativa para referirse a los no creyentes, en el libro del Islam, El Corán.

Análisis de sentimientos de Libros Sagrados con R — Wordcloud de sentimientos negativos y positivos en La Biblia
Análisis de sentimientos de Libros Sagrados con R — Wordcloud de sentimientos negativos y positivos en El Dhammapada
Análisis de sentimientos de Libros Sagrados con R— Wordcloud de sentimientos negativos y positivos en El Corán
Análisis de sentimientos de Libros Sagrados con R — Wordcloud de sentimientos negativos y positivos en El Libro de Mormón

¿Realmente cuál de los cuatro Libros Sagrados es más positivo?

Puedes responder a esta pregunta basándote en el porcentaje de sentimientos negativos y positivos de las palabras de los textos que cada libro expresa.

# SENTIMIENTOS NEGATIVOS Y POSITIVOS EN PORCENTAJEbngNegative <- get_sentiments("bing") %>% 
filter(sentiment == "negative")
bngPositive <- get_sentiments("bing") %>%
filter(sentiment == "positive")
termCount <- cleanTerms %>%
group_by(book) %>%
summarize(words = n())
negTermCount<-cleanTerms %>%
semi_join(bngNegative) %>%
group_by(book) %>%
summarize(negativewords = n()) %>%
left_join(termCount, by = c("book")) %>%
mutate(neg_words_percent = round(100*negativewords/words,2)) %>%
ungroup
posTermCount<-cleanTerms %>%
semi_join(bngPositive) %>%
group_by(book) %>%
summarize(positivewords = n()) %>%
left_join(termCount, by = c("book")) %>%
mutate(pos_words_percent = round(100*positivewords/words,2)) %>%
ungroup
allSentiments<-merge(negTermCount,posTermCount)# PLOT SENTIMIENTOS NEGATIVOS Y POSITIVOS EN PORCENTAJE EN CADA LIBRO SAGRADOggplot(melt(allSentiments[,c(1,4,6)]),
aes(x=book, value, fill=variable, width = 0.5)) +
geom_bar(stat = "identity",position = position_dodge(width=0.5)) +
labs(x= "Holy Book",y= "percentage of terms") +
ggtitle("Negative and Positive word sentiments", "In percentage") +
scale_fill_manual("",values = c("#cf0a00","#1a954d"),
labels= c("Negative Sentiments",
"Positive Sentiments")) +
scale_y_continuous(label=function(y){return(paste0(y, "%"))})

Obtendrás como resultado un plot como el siguiente, donde ¡oh vaya sorpresa!, podrás observar que ninguno de los cuatro Libros Sagrados realmente expresa sentimientos mayormente positivos que negativos. El único de ellos, que casi alcanza un equilibrio es el Dhammapada, del Budismo.

Análisis de sentimientos de Libros Sagrados con R — Plot de porcentaje de sentimientos negativos y positivos en cada Libro Sagrado

Top 10 de sentimientos expresados en los textos de cada Libro Sagrado

Puedes también visualizar el top 10 de las palabras mayormente expresadas con su asociación a su sentimiento correspondiente, ya sea negativo o positivo.

# TOP 10 SENTIMIENTOSbookTerms <- vocabulary %>%
group_by(book,word) %>%
summarize(count=length(word)) %>%
inner_join(get_sentiments("bing"), by = c(word = "word"))
totalWords<- bookTerms %>%
group_by(book) %>%
summarize(total = sum(count))
bookTerms <- left_join(bookTerms,totalWords)topSentiments<-bookTerms %>%
count(book,sentiment, word, wt = count, sort = TRUE) %>%
mutate(n = ifelse(sentiment == "negative", -n, n)) %>%
group_by(book) %>%
top_n(n=10,wt=abs(n)) %>%
arrange(book,n) %>%
ungroup () %>%
mutate(order = row_number())
ggplot(topSentiments, aes(order, n, fill = sentiment)) +
geom_bar(stat = "identity") +
facet_wrap(~ book, scales = "free") +
xlab("sentiment word") +
ylab("sentiment score * # of occurrences") +
theme_bw() +
coord_flip() +
scale_x_continuous(
breaks = topSentiments$order,
labels = topSentiments$word,
expand = c(0,0)) +
ggtitle("Top 10 sentiments", "In each Holy Book\n") +
coord_flip() +
facet_wrap(~book,scales = "free",ncol=1)+
scale_fill_manual("",values = c("#cf0a00","#1a954d"),labels= c("Negative\nSentiments","Positive\nSentiments")) +
theme_bw() +
theme(legend.position="none",
panel.border = element_blank(),
strip.text.x = element_text(size=11,hjust=0,face="plain"),
)

Como puedes ver, con el plot obtenido, en este punto descubrirás que hay algunas ideas en las que claramente convergen algunos de los libros, por ejemplo, tanto La Biblia como El corán hablan con relevancia de un “cielo” (“heaven”), mientras que El Dhammapada, El Corán y El libro de Mormón tienen muy presente la palabra “muerte” (“death”).

Análisis de sentimientos de Libros Sagrados con R — Plot de top 10 de palabras asociadas a un sentimiento negativo o positivo en cada Libro Sagrado

Top 10 de sentimientos expresados en los textos de cada Libro Sagrado — Gráfica de Radar

También puedes visualizar las palabras negativas y positivas más comunes por separado, para tener una mejor idea de ellas. Una buena idea sería realizar el plot de un Radar Chart, para lo cual puedes usar el package “ggradar”.

# SENTIMIENTOS PRESENTES MÁS COMUNES CON GGRADARcommonNegTerms<-bookTerms %>%
group_by(book) %>%
mutate(countpercent=count/sum(count)) %>%
ungroup() %>%
group_by(word) %>%
mutate(wordimp= sum(countpercent)) %>%
filter(sentiment=="negative") %>%
group_by(book) %>%
top_n(n=10,wt=wordimp) %>%
arrange(book,wordimp) %>%
select(book,word,countpercent) %>%
dcast(book~word)
commonNegTerms[is.na(commonNegTerms)]<-0
x<-ggradar(commonNegTerms, grid.min = 0,
grid.mid = 0.015,
grid.max = 0.04,
axis.label.offset = 1.1,
axis.label.size = 4,
grid.label.size = 0,
group.line.width = 1,
group.point.size = 1.5,
background.circle.colour = "#ffbbcc",
legend.text.size = 12,
plot.legend = FALSE,
plot.title = "Most common Negative sentiments \n in each Holy Book")+
theme(legend.position = "bottom",
plot.title=element_text(hjust=0.4,face = "plain"))+
scale_colour_manual(values = rep(c("#fd8529","#3a76b0","#5b59d6","#56c9c4"), 100))
commonPosTerms<-bookTerms %>%
group_by(book) %>%
mutate(countpercent=count/sum(count)) %>%
ungroup() %>%
group_by(word) %>%
mutate(wordimp= sum(countpercent)) %>%
filter(sentiment=="positive") %>%
group_by(book) %>%
top_n(n=10,wt=wordimp) %>%
arrange(book,wordimp) %>%
select(book,word,countpercent) %>%
dcast(book~word)
commonPosTerms[is.na(commonPosTerms)]<-0
y<-ggradar(commonPosTerms, grid.min = 0,
grid.mid = 0.025,
grid.max = 0.06,
axis.label.offset = 1.1,
axis.label.size = 4,
grid.label.size = 0,
group.line.width = 1,
group.point.size = 1.5,
background.circle.colour = "#ffbbcc",
legend.text.size = 12,
plot.legend = FALSE,
plot.title = "Most common Positive sentiments \n in each Holy Book")+
theme(legend.position = "bottom",
plot.title=element_text(hjust=0.4,face = "plain"),
axis.title = element_text(face = "plain"))+
scale_colour_manual(values = rep(c("#fd8529","#3a76b0","#5b59d6","#56c9c4"), 100))
tmp <- arrangeGrob(x + theme(legend.position = "none"), y +
theme(legend.position = "none"), layout_matrix = matrix(c(1, 2), nrow = 2))
g <- ggplotGrob(y + theme(legend.position="right"))$grobs
legend <- g[[which(sapply(g, function(x) x$name) == "guide-box")]]
grid.arrange(tmp, legend, ncol=2, widths=c(9,6))

Ahora obtendrás como resultado el siguiente plot donde de forma separada por un gráfico de radar de sentimientos negativos y otro de sentimientos positivos, podrás ver a detalle las palabras que tienen dicha asociación en cada libro.

Análisis de sentimientos de Libros Sagrados con R — Plot de top 10 de palabras asociadas a un sentimiento negativo o positivo en cada Libro Sagrado con ggradar

¿Qué palabras son únicas en cada Libro Sagrado?

Puedes descubrir también qué palabras son únicas en cada Libro Sagrado, palabras que no se encontrarán en cualquiera de los demás libros. Puedes obtener digamos el top 20 de palabras, usando “Tf-Idf” (Term frequency-Inverse document frequency), que funciona para determinar la importancia de una palabra para un documento en comparación con su existencia en otros documentos.

# PALABRAS ÚNICAS CON TF-IDFbookTerms2<- cleanTerms %>%
count(book, word, sort = TRUE) %>%
ungroup()
bookTerms2 <- left_join(bookTerms2,
bookTerms2 %>%
group_by(book) %>%
summarize(total = sum(n)))
bookTermsTfIdf <- bookTerms2 %>%
bind_tf_idf(word, book, n)
bookTermsTfIdf <- anti_join(bookTermsTfIdf , bookTermsTfIdf [duplicated(bookTermsTfIdf[2]),], by="word")plotTfIdf <- bookTermsTfIdf %>%
arrange(desc(tf_idf)) %>%
mutate(word = factor(word, levels = rev(unique(word))))
uniqueWords <- plotTfIdf %>%
group_by(book) %>%
top_n(20) %>%
ungroup
# PLOT TOP 20 PALABRAS ÚNICASggplot(uniqueWords, aes(word, tf_idf, fill = book)) +
geom_bar(stat = "identity", show.legend = FALSE) +
labs(x = NULL, y = "tf-idf") +
facet_wrap(~book, ncol = 4, scales = "free") +
coord_flip()+
scale_fill_manual("",values = c("#fd8529","#3a76b0","#5b59d6","#56c9c4")) +
labs(x= "word", y= "Tf-Idf") +
ggtitle("Top 20 unique words", "In each Holy Book \n ") +
theme(
panel.background = element_blank(),
strip.text.x = element_text(size=11,hjust=0.05,face="plain")
)

Como resultado obtendrás el siguiente plot, donde encontrarás las 20 palabras únicas de cada libro. Encontrarás palabras muy particulares de cada religión, como en el caso de El Dhammapada, del Budismo, por ejemplo, es el único que habla de “renacimiento” (“rebirth”). O podrás encontrar nombres hebreos de personas y lugares muy característicos que se encuentran únicamente en La Biblia, por ejemplo.

Análisis de sentimientos de Libros Sagrados con R — Plot de top 20 de palabras únicas en cada Libro Sagrado con Tf-Idf

Asociaciones y relaciones entre palabras en cada Libro Sagrado

Por último, otra visualización gráfica que puedes realizar podría ser una red semántica por libro, con bigramas (secuencia de palabras adyacentes), de esta manera también debería reflejar algunas ideas muy únicas en cada uno de los textos que componen a los Libros Sagrados.

holyBooksBigrams <- allHolybooks %>%
unnest_tokens(bigram, text, token = "ngrams", n = 2)
holyBooksBigrams<- filter(holyBooksBigrams, nchar(holyBooksBigrams$bigram)>2)separatedBigrams <- holyBooksBigrams %>%
separate(bigram, c("word1", "word2"), sep = " ")
filteredBigrams <- separatedBigrams %>%
filter(!word1 %in% stop_words$word) %>%
filter(!word2 %in% stop_words$word)
countsBigram <- filteredBigrams %>%
count(book,word1, word2, sort = TRUE)
countsBigram<- countsBigram[,c(2,3,4,1)]countsBigramPlot<- countsBigram %>%
group_by(book) %>%
top_n(25,wt=n)%>%
filter (n>2) %>%
ungroup()
set_graph_style()plotGraph<- function(df,book,colorname){

set.seed(123)

bigramPlot <- df[df$book==book,] %>%
graph_from_data_frame()

gh<-df[df$book==book,]

names(gh)<-c("word","word","n","book")
tt<- rbind(gh[,c(1,4)],gh[,c(2,4)])
pk<-tt[match(unique(tt$word), tt$word),]

V(bigramPlot)$class<-pk$book

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

p<- ggraph(bigramPlot, layout = "fr") +
geom_edge_link(aes(edge_alpha = n),arrow = a) +
geom_node_point(size = 1,colour = colorname) +
geom_node_text(aes(label = name), vjust = 1, hjust = 1) +
ggtitle(book, "Red semántica") +
th_foreground(foreground = 'grey', border = F)+
theme(legend.position="none",
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
plot.margin=unit(c(0.2,0.2,0.2,0.2), "cm"))

return (p)
}
bigram1<-plotGraph(countsBigramPlot,"Dhammapada",colorname="#FB7020")
bigram2<-plotGraph(countsBigramPlot,"The Bible",colorname="#2E61A0")
bigram3<-plotGraph(countsBigramPlot,"The Quran",colorname="#49C0B7")
bigram4<-plotGraph(countsBigramPlot,"The Book of Mormon",colorname="#493FCC")
grid.arrange(bigram1, bigram2, bigram3, bigram4, ncol=2)

Como verás solo utilizaste los 25 bigramas principales para crear el siguiente plot. Por upuesto, es posible crear relaciones más complejas. La opacidad de las flechas tendiendo hacia un color más oscuro señala las relaciones más fuertes entre las palabras.

Análisis de sentimientos de Libros Sagrados con R — Plot of the 25 main bigrams in each Holy Book

Muchas gracias por tu amable lectura. Del mismo modo que con la mayoría de mis artículos, te comparto un poco más estéticos los plots generados con plotly en un flexdashboard que armé: https://rpubs.com/cosmoduende/holy-books-sentiment-data-analysis

Y aquí puedes encontrar el código completo: https://github.com/cosmoduende/r-holy-books-sentiment-data-analysis

¡Te agradezco haber llegado hasta el final, te deseo que tengas muy felices análisis, que puedas poner en práctica todo, y te sorprendas y diviertas tanto como yo con los resultados!

Otros artículos que he escrito

Si te ha gustado este artículo, te agradeceré mucho tus claps. Además te invito a visitar también otros artículos que he escrito, que podrían ser de tu interés:

Gracias y hasta la próxima.

Aprendiz constante, amante de la tecnología. #G3ekArmy, Web Developer & Data Enthusiast. Coordinador académico & Instructor en KMMX. Organizador de #KotlinCDMX.

Get the Medium app