Se quiere caracterizar aspectos fundamentales de la estructura social de una red representada por medio de un grafo \(G=(V,E)\):
El grado (degree) \(d_v\) de un vértice \(v\in V\) se define como \(d_v = |\left\{\{v,u\}\in E:u\in V \right\}|\), i.e., \(d_v\) corresponde al número de aristas incidentes en \(v\).
A partir de la matriz de adyacencia \(\mathbf{Y}=[y_{i,j}]\) se tiene que el grado del individuo \(i\) se puede calcular mediante \[ d_i = \sum_{i:i\neq j} y_{i,j} = \sum_{j:j \neq i} y_{i,j}\,,\qquad \text{para}\,\,i=1,\ldots,n\,. \]
El grado de un vértice es la combinación de la sociabilidad y la popularidad.
¿Cómo se adaptan estos conceptos en el caso de los digrafos?
En redes ponderadas, la fuerza (strength) \(s_v\) de un vértice \(v\in V\) se define como \[ s_v = \sum_{u\in V:\{v,u\}\in E} w_{\{v,u\}}\,, \] i.e., la suma de los pesos de las aristas incidentes en \(v\).
Red de interacción de personajes de la temporada 1 de la serie de HBO Juego de Tronos.
Esto datos fueron recolectados para estudiar la dinámica de los Siete Reinos de Juego de Tronos.
Los personajes están conectados mediante aristas ponderadas por el número de interacciones de los personajes.
Una descripción completa de los datos se puede encontrar aquí.
Disponible este enlace de GitHub.
suppressMessages(suppressWarnings(library(igraph)))
# datos
setwd("C:/Users/User/Dropbox/UN/networks/")
dat_nodes <- read.csv("got-s1-nodes.csv")
dat_edges <- read.csv("got-s1-edges.csv")
# grafo
got <- graph_from_data_frame(d = dat_edges[,c(1,2)], vertices = dat_nodes$Id, directed = "F")
E(got)$weight <- dat_edges$Weight
# orden
vcount(got)
## [1] 126
# tamaño
ecount(got)
## [1] 549
# dirigida?
is_directed(got)
## [1] FALSE
# ponderada?
is_weighted(got)
## [1] TRUE
# matriz de adyacencia
Y <- as_adjacency_matrix(got, sparse = F)
# grado
head(
cbind(
degree(graph = got),
apply(X = Y, MARGIN = 1, FUN = sum),
apply(X = Y, MARGIN = 2, FUN = sum)), n = 5)
## [,1] [,2] [,3]
## ADDAM_MARBRAND 3 3 3
## AEGON 2 2 2
## AERYS 13 13 13
## ALLISER_THORNE 8 8 8
## ARYA 28 28 28
# grado
d <- degree(graph = got)
head(sort(d, decreasing = T), n = 10)
## NED TYRION CATELYN ROBERT ROBB CERSEI
## 57 41 36 36 30 29
## ARYA JOFFREY JON LITTLEFINGER
## 28 27 26 26
Top 10 de Juego de tronos (temporada 1) de acuerdo con el grado.
# fuerza
wd <- strength(got)
head(sort(wd, decreasing = T), n = 10)
## NED TYRION CATELYN ROBERT DAENERYS JON
## 1290 709 584 563 535 535
## CERSEI ROBB SANSA LITTLEFINGER
## 444 424 422 383
Top 10 de Juego de tronos (temporada 1) de acuerdo con la fuerza.
# diseño
set.seed(123)
l <- layout_with_dh(got)
# visualización
par(mfrow = c(1,2), mar = c(4, 3, 3, 1))
# usando el grado
plot(got, layout = l, vertex.size = 1.5*sqrt(d), vertex.label = NA, vertex.color = adjustcolor("royalblue",0.2), vertex.frame.color = "royalblue", edge.color = adjustcolor("gray",0.4))
title(sub = "Grado", line = -1)
# usando la fuerza
plot(got, layout = l, vertex.size = 0.3*sqrt(wd), vertex.label = NA, vertex.color = adjustcolor("royalblue",0.2), vertex.frame.color = "royalblue", edge.color = adjustcolor("gray",0.4))
title(sub = "Fuerza", line = -1)
title(main = "Juego de Tronos: Temporada 1 ", outer = T, line = -2)
La distribución del grado (degree distribución) de \(G\) es la colección de frecuencia relativas \(f_0, f_1,\ldots\), donde \[ f_d = \frac{|\{v\in V:d_v = d\}|}{|V|}\,,\qquad \text{para}\,\,d=0,1,\ldots\,, \] i.e., la fracción de vértices en \(V\) tales que \(d_v = d\).
La distribución de fuerza (strength distribution) se define de manera análoga.
En algunas redes se tiene que una gran porción de vértices tiene grado bajo y una pequeña fracción tiene grado alto. Esta pequeña fracción de vértices se conoce como centros (hubs).
En estos casos la distribución del grado tiene una cola larga a la derecha. Esto se traduce en un decaimiento aproximadamente lineal en la frecuencia logarítmica en función del grado logarítmico.
La distribución de la ley de potencias (power law distribution) señala que la distribución del grado \(d\) es de la forma \[ f_d = \mathrm{c}\,d^{-\alpha}\,,\qquad \mathrm{c}>0\,,\qquad \alpha>1\,, \] lo que en escala log corresponde a \[ \log f_d = \log \mathrm{c} - \alpha\log d\,. \] \(\mathrm{c}\) se denomina constante de normalización y \(\alpha\) exponente de la ley de potencias (similar a la distribución de Pareto).
Las redes que satisfacen este tipo de distribución del grado se denominan libres de escala (scale free) dado que \[ f_{a\,d} = \mathrm{c}\, (a\,d)^{-\alpha} = a^{-\alpha}\,f_d\,. \] En una red libre de escala, algunos nodos están altamente conectados, es decir, poseen un gran número de enlaces a otros nodos, aunque el grado de conexión de casi todos los nodos es bastante bajo.
Red de interacción de proteínas de levadura.
Las interacciones proteína-proteína prometen revelar aspectos del sistema regulatorio que subyace a la función celular.
Los nodos corresponden a proteínas y solo se consideran aquellas interacciones que tienen una confianza “moderada” y “alta”.
Una descripción completa de los datos se puede encontrar aquí.
Disponible en el paquete igraphdata
de R.
Von Mering, C., Krause, R., Snel, B., Cornell, M., Oliver, S. G., Fields, S., & Bork, P. (2002). Comparative assessment of large-scale data sets of protein–protein interactions. Nature, 417(6887), 399-403.
# datos
data(yeast)
yeast <- upgrade_graph(yeast)
# la representación de datos internos a veces cambia entre versiones
# orden
vcount(yeast)
## [1] 2617
# tamaño
ecount(yeast)
## [1] 11855
# dirigida?
is_directed(yeast)
## [1] FALSE
# ponderada?
is_weighted(yeast)
## [1] FALSE
# grado
d <- degree(yeast)
# distribución de grado
dd <- degree_distribution(yeast)
# visualización
par(mfrow = c(1,2))
plot(NA, NA, type = "n", xlim = c(0,120), ylim = c(0,0.08), xlab = "Grado", ylab = "Densidad", main = "Distribución de grado")
hist(d, freq = F, col = "lightskyblue", border = "royalblue", add = T)
plot((0:max(d))[dd != 0], dd[dd != 0], log = "xy", pch = 16, col = adjustcolor("royalblue", 0.5), xlab = "Log-grado", ylab = "Log-densidad", main = "Distribución de grado (log-log)")
# grado promedio de los vecinos (GPV) más cercados de orden 1
mnd <- knn(graph = yeast, vids = V(yeast))$knn
mean(d[as.numeric(neighbors(graph = yeast, v = 1))])
## [1] 38.65
# visualización: GPV vs. grado
plot(x = d, y = mnd, log = "xy", pch = 16, col = adjustcolor("yellow3", 0.5), xlab = "Log-grado", ylab = "Log-grado promedio de los vecinos")
Los vértices de grados superiores tienden a vincularse con vértices similares en este sentido.
Mientras que los vértices de grados inferiores tienden a relacionarse tanto con vértices de grados inferiores como superiores.
Las medidas de centralidad están diseñadas para cuantificar la “importancia” de los nodos de una red.
Existen versiones normalizadas de todas las medidas para facilitar la comparación entre grafos y otras medidas. La normalización se logra multiplicando por una constante apropiada.
Existen versiones para redes dirigidas y ponderadas.
Un vértice se considera “importante” si está “cerca” de muchos otros vértices: \[ c_{\textsf{C}}(v) = \frac{1}{\sum_{u\in V} \textsf{d}(v,u)} \] donde \(\textsf{d}(v,u)\) es la distancia geodésica entre los vértices \(u\) y \(v\) de \(V\).
Un vértice se considera “importante” si se encuentra “entre” otros pares de vértices.
Los vértices que se encuentran en muchos caminos son más críticos para el proceso de comunicación: \[ c_{\textsf{B}}(v) = \sum_{s,t\in V:s\neq t\neq v} \frac{\sigma(s,t\mid v)}{\sigma(s,t)} \] donde \(\sigma(s,t\mid v)\) es el número total de caminos más cortos entre \(s\) y \(t\) que pasan por \(v\), y \(\sigma(s,t)\) es el número total de caminos más cortos entre \(s\) y \(t\) (independientemente de si pasan por \(v\) o no).
Un vértice se considera “importante” si sus vecinos son a su vez “centrales”: \[ c_{\textsf{E}}(v) = \alpha\sum_{\{u,v\}\in E} c(u) \] donde \(\mathbf{c}=(c(1),\ldots,c(n))\) es una solución al problema de vectores propios dado por \(\mathbf{Y}\mathbf{c}=\alpha^{-1}\mathbf{c}\), con \(\mathbf{Y}\) la matriz de adyacencia, \(\alpha^{-1}\) es el valor propio más grande de \(\mathbf{Y}\), y \(\mathbf{c}\) es el vector propio correspondiente.
La convención es reportar los valores absolutos de las entradas de \(\mathbf{c}\).
Red de blogs de SIDA, pacientes y sus redes de apoyo.
Un enlace dirigido de un blog a otro indica que el primero tiene un enlace al segundo en su página web.
Una descripción completa de los datos se puede encontrar aquí.
Disponible en el paquete sand
de R.
Miller, H. J. (2007). Societies and cities in the age of instant access. In Societies and cities in the age of instant access (pp. 3-28). Springer, Dordrecht.
# install.packages(sand)
suppressMessages(suppressWarnings(library(sand)))
# data
data(aidsblog)
aidsblog <- upgrade_graph(aidsblog)
# la representación de datos internos a veces cambia entre versiones
# orden
vcount(aidsblog)
## [1] 146
# tamaño
ecount(aidsblog)
## [1] 187
# dirigida?
is_directed(aidsblog)
## [1] TRUE
# ponderada?
is_weighted(aidsblog)
## [1] FALSE
Para digrafos, los centros (hubs) son “importantes” por la cantidad de vértices “centrales” a los que señalan. Mientras que las autoridades (authorities) son “importantes” por la cantidad de vértices “centrales” que los señalan.
Específicamente, dada una matriz de adyacencia \(\mathbf{Y}\) de una red dirigida, estas medidas se calculan por medio de la centralidad propia que se obtienen de las matrices \(\mathbf{M}_{\textsf{H}}=\mathbf{Y}\mathbf{Y}^{\textsf{T}}\) y \(\mathbf{M}_{\textsf{A}}=\mathbf{Y}^{\textsf{T}}\mathbf{Y}\), respectivamente.
# centros y autoridades
hs <- igraph::hub_score(graph = aidsblog, scale = T)$vector
as <- igraph::authority_score(graph = aidsblog, scale = T)$vector
# ´visualización
set.seed(123)
l <- layout_with_kk(aidsblog)
par(mfrow = c(1,2), mar = c(4, 3, 3, 1))
plot(aidsblog, layout = l, vertex.label = NA, vertex.size=15*sqrt(hs), main = "Centros")
plot(aidsblog, layout = l, vertex.label = NA, vertex.size=15*sqrt(as), main = "Autoridades")