La Matriz de Markov recibe su nombre de un matematico Ruso quien la introdujo en el anio 1907: Andrei Markov. La cadena de Markov es un tipo especial de proceso estocastico discreto de la teoria de la probabilidad en el que la probabilidad que ocurra un evento depende solo del evento inmediato anterior y no le afectan los que sucedieron con anterioridad.
Existen muchas aplicaciones en la vida real para este modelo. A continuacion se hara una matriz de Markov a partir de la relacion que existe entre las actices americanas, basandonos en referencias hechas en wikipedia.
Cargamos las librerias que seran de utilidad:
library(rvest)
library(tidyverse)
library(stringr)
library(parallel)
Primero vamos a leer de la pagina de Wikipedia todos los links que existen y para obtener solo los links de las actrices se van a hacer unas filtraciones. Solo usaremos los tags de html donde hace referencia a todos los links, se quitaran todos los comentarios, imagenes, etc.
actrices <-
read_html("https://en.wikipedia.org/wiki/List_of_American_film_actresses") %>%
html_nodes("a") %>%
html_attr('href') %>%
data_frame() %>%
rename(links='.') %>%
filter(str_detect(links,"/wiki/")) %>%
filter(!str_detect(links,"#")) %>%
filter(!str_detect(links,"image")) %>%
filter(!str_detect(tolower(links),"file"))%>%
filter(!str_detect(links,"https:")) %>%
filter(!str_detect(links,":")) %>%
filter(!str_detect(links, "List")) %>%
filter(!str_detect(links, "Main")) %>%
filter(!str_detect(links, "foundation"))
Vista previa de las primeras 10 actrices del set de datos:
actrices[1:10,1]
Matriz vacia para meter todas las referencias en las actrices.
matriz_actrices <- matrix(rep(0,3779136), nrow= 1944)
colnames(matriz_actrices) <- c(unlist(actrices[,1], use.names=FALSE))
rownames(matriz_actrices) <- c(unlist(actrices[,1], use.names=FALSE))
matriz_actrices[10:13,10:13]
/wiki/Jean_Acker /wiki/Bettye_Ackerman /wiki/Amy_Adams /wiki/Brooke_Adams_(actress)
/wiki/Jean_Acker 0 0 0 0
/wiki/Bettye_Ackerman 0 0 0 0
/wiki/Amy_Adams 0 0 0 0
/wiki/Brooke_Adams_(actress) 0 0 0 0
Para mostrar el funcionamiento del algoritmo se va a aplicar para una sola actriz:
actrices[12,1]
Obteniendo todos los links dentro de una sola actriz: Amy Adams. Usamos la funcion paste para contatenar los strings. Luego se hace una filtracion para poder reducir considerablemente la cantidad de links que se deben comparar.
links_AmyAdams <-
read_html(paste("https://en.wikipedia.org",actrices[12,1],sep = ""))%>%
html_nodes("a") %>%
html_attr('href') %>%
data_frame() %>%
rename(links='.') %>%
filter(str_detect(links,"/wiki/")) %>%
filter(!str_detect(links,"#")) %>%
filter(!str_detect(links,"image")) %>%
filter(!str_detect(tolower(links),"file"))%>%
filter(!str_detect(links,"https:")) %>%
filter(!str_detect(links, "film")) %>%
filter(!str_detect(links, "List")) %>%
filter(!str_detect(links, "Award")) %>%
filter(!str_detect(links, "Wikipedia")) %>%
filter(!str_detect(links, ":")) %>%
filter(!str_detect(links, "serie")) %>%
filter(!str_detect(links, "Film"))
links_AmyAdams[1:10,1]
Cantidad de links de referencia en la pagina de Wikipedia de Amy Adams:
nrow(links_AmyAdams)
[1] 764
Vamos a definir una matriz (de una sola fila, para Amy Adams) de las relaciones que existen entre los links de Amy Adams y el resto de actrices.
Para cada link en la pagina de Amy Adams se ira comparando con todas las actrices americanas, cuando encuentra a cual pertenece ese link se ira guardando en la matriz para Amy Adams y se pasa al siguiente link de inmediato, con el proposito de minimizar tiempo:
for(i in 1:nrow(links_AmyAdams)){
for(j in 1:nrow(actrices)){
if(!is.na(match(links_AmyAdams[i,1],actrices[j,1]))){
vector_AmyAdams[1,j] <- vector_AmyAdams[1,j] + 1
break
}
}
}
Colocaremos los nombres de las actrices en la matriz
colnames(vector_AmyAdams) <- c(unlist(actrices[,1], use.names=FALSE))
rownames(vector_AmyAdams) <- c("Amy_Adams")
Ahora vamos a comprobar que el proceso anterior se realizo de manera correcta. Veamos el caso del Meryl Streep. Cuantos links hacia Meryl existen en la pagina de Amy Adams?
links_AmyAdams %>%
filter(links == "/wiki/Meryl_Streep")
Por lo que nos podemos dar cuenta que existen 11 links de Meryl Streep en la pagina de Amy Adams. Ahora comprobando el valor en la matriz de Amy Adams:
vector_AmyAdams[,"/wiki/Meryl_Streep"]
[1] 11
Ahora colocaremos las probabilidades en la matriz y veremos un extracto de la matriz:
vector_AmyAdams[1,] <- vector_AmyAdams[1,] / sum(vector_AmyAdams[1,])
vector_AmyAdams[1,11:14]
/wiki/Bettye_Ackerman /wiki/Amy_Adams /wiki/Brooke_Adams_(actress) /wiki/Edie_Adams
0.000000000 0.006802721 0.000000000 0.000000000
Comprobando que estas probabilidades sumen 1:
sum(vector_AmyAdams[1,])
[1] 1
Ahora vamos a correr el mismo algoritmo para todas las actrices dentro de la matriz:
for (k in 1:nrow(actrices)){
links_actriz <-
read_html(paste("https://en.wikipedia.org",actrices[k,1],sep = ""))%>%
html_nodes("a") %>%
html_attr('href') %>%
data_frame() %>%
rename(links='.') %>%
filter(str_detect(links,"/wiki/")) %>%
filter(!str_detect(links,"#")) %>%
filter(!str_detect(links,"image")) %>%
filter(!str_detect(tolower(links),"file"))%>%
filter(!str_detect(links,"https:")) %>%
filter(!str_detect(links, "film")) %>%
filter(!str_detect(links, "List")) %>%
filter(!str_detect(links, "Award")) %>%
filter(!str_detect(links, "Wikipedia")) %>%
filter(!str_detect(links, ":")) %>%
filter(!str_detect(links, "serie")) %>%
filter(!str_detect(links, "Film"))
for(i in 1:nrow(links_actriz)){
for(j in 1:nrow(actrices)){
if(!is.na(match(links_actriz[i,1],actrices[j,1]))){
matriz_actrices[k,j] <- matriz_actrices[k,j] + 1
break
}
}
}
}
View(links_AmyAdams)
matriz_actrices %>% View()
En la siguiente imagen se muestra un screenshot de matriz_actrices %>% View()
:
Creamos una matriz donde iran las probabilidades:
matriz_prob <- matriz_actrices
Asignando una probabilidad a las actrices:
for (l in 1944){
for(i in 1944){
matriz_prob[l,i] <- matriz_actrices[l,i] / rowSums(matriz_actrices[l,])
}
}