Linked, de Barabasi, capítulo I
No sé si seguir leyendo libros. Sus autores los llenan de letras. Y es un lujo poder disponer del tiempo de leerlas todas.
Uno de esos libros llenos de letras es Linked, de Barabasi. Es un libro estupendo y recomendable. Pero podría ocupar 20 páginas si el autor fuese un poco más escueto y no se empeñase de llenarlo todo de anécdotas y colores.
Su primer capítulo trata sobre las redes sociales aleatorias, también conocidas como redes de Poisson o de Erdös-Rényi. Una de tales redes aleatorias es una colección de n nodos y enlaces entre ellos de manera que la probabilidad de que dos nodos x e y al azar estén unidos es p.
Dos propiedades matemáticas de ellas cita Barabasi. Hoy discutiré esas dos y una más.
La primera es que el grado de los nodos sigue una distribución de Poisson —y de ahí el nombre—. Efectivamente, la probabilidad de que un nodo tenga grado k tiene una distribución binomial B(n,p) y siempre que z = np sea pequeño, puede aproximarse por una distribución de Poisson de parámetro z.
El código
n.nodos <- 1000
build.network <- function( n.nodos, n.enlaces ){
rs <- matrix( sample( n.nodos, 2 * n.enlaces, replace = T),
nrow = n.enlaces, ncol = 2 )
rs <- subset( rs, ! rs[,1] == rs[,2] )
if( nrow( rs ) < n.enlaces )
return( rbind( rs , build.network( n.nodos, n.enlaces - nrow( rs ) ) ) )
rs
}
link.x.node <- function( z, n.nodos = 1000 ){
p <- z / n.nodos
n.enlaces.potenciales <- n.nodos * ( n.nodos - 1 ) / 2
# cuantos enlaces existen?
n.enlaces <- rbinom( 1, n.enlaces.potenciales, p )
kk <- build.network( n.nodos, n.enlaces )
kk <- table( table( kk ) )
cbind( z, as.numeric( names( kk )), kk )
}
node.dist <- function( z, n.iter ){
res <- replicate( n.iter, link.x.node(z, n.nodos = n.nodos) )
res <- mapply( cbind, res, 1:n.iter )
res <- data.frame( do.call( rbind, res ) )
colnames( res ) <- c( "z", "n.enlaces", "count", "iter" )
boxplot( res$count ~ res$n.enlaces )
tmp <- unique( res$n.enlaces )
lines( tmp, n.nodos * dpois( tmp, lambda = z ), col = "red" )
res
}
res <- node.dist( 5, 100 )
crea 100 redes aleatorias con n.nodos
nodos y z = 5. Luego cuenta cuántos nodos tienen grado k y, finalmente, crea una gráfica similar a
que es un diagrama de cajas del grado sobre el que se superpone el número esperado de nodos de grado k si se acepta que su distribución es de Poisson. Como puede apreciarse, coinciden. Pero ya lo sabíamos porque conocíamos de viejo la relación entre las distribuciones de Poisson y la binomial.
La segunda propiedad de este tipo de redes es más enjundiosa. Tiene que ver con lo siguiente: en una red aleatoria, ¿existirán varias componentes inconexas? ¿o todos los nodos acabarán unidos a todos los nodos?
Supongamos que existe una componente gigante G. ¿Cuál será la probabilidad q de que alguno de los nodos x no pertenezca a ella? Si $latex x$ es un nodo con k vecinos $latex x_1, \dots, x_k$, entonces
$$q = P( x \not\in G ) = P( x_1, \dots, x_k \not\in G)$$
y dizque (yo no tengo aún claro el motivo: no acabo de ver por qué son sucesos independientes)
$$P( x_1, \dots, x_k \not\in G) = \prod P( x_i \not\in G ) = q^k $$
Si un nodo no pertenece a G, tampoco lo harán ninguno de sus vecinos. De ahí q sea igual a
$$q=\sum_{k=0}^\infty q^k p_k$$
y que, en general,
$$q = \sum_{k=0}^\infty q^k z^k e^{-z} / k! = e^{-z} \sum_{k=0}^\infty (qz)^k / k! = e^{-z} e^{zq}.$$
De ahí se obtiene la ecuación $latex q = \exp^{-z( 1-q )}$ y si $latex s = 1-q$ es la probabilidad de que un nodo pertenezca a G, se obtiene $latex s = 1 - \exp^{-zs}$.
¿Tiene soluciones esta ecuación entre 0 y 1? ¿Para qué valores de z? Existe una raíz trivial s = 0: en tal caso el término de la izquierda y el de la derecha valen 0. En 1, el término de la izquierda vale 1 y el de la derecha, menos de uno.
La siguiente figura ilustra la situación:
En ella se representa el término de la izquierda,
curve( I, 0, 1, xlab = "", ylab = "" )
como una línea negra sólida y luego el término de la derecha con los valores z = 2
curve( 1 - exp( - 2 * x), add = T, lty = 2 )
y z = 0.5
curve( 1 - exp( - 0.5 * x), add = T, lty = 2 )
con líneas punteadas. Como podrá comprobar quién aún se derivan funciones, la derivada del término de la derecha en 0 es mayor o menor que uno dependiendo de si z es mayor o menor que 1 y eso obliga a que haya o no raíz de la ecuación en (0,1).
En resumen, cuando z < 1 no existe componente gigante y la red es una especie de sopa de letras. Pero si z > 1, aparece una supercomponente que contiene un porcentaje de los nodos dado por la solución de la ecuación anterior. Raíz que puede obtenerse con R así:
foo.optim <- function( x, z = 3 ) ( x - 1 + exp( -z * x) )**2
optimize( foo.optim, z = 2, interval = c(0,1))$minimum
optimize( foo.optim, z = 1.5, interval = c(0,1))$minimum
Para terminar esta larga entrada, vamos a ver si podemos fiarnos o no de Erdös. Porque una cosa es que este hombre nos diga que el tamaño de la componente grande es s y otra distinta, que lo sea.
Para eso vamos a crear muchas redes aleatorias con distintos valores de z y calcular el tamaño de la componente más grande para después compararlo con el calculado teóricamente. Y efectivamente, corriendo
library( igraph )
prop.giant.component <- function( z, n.nodos = 1000 ){
p <- z / n.nodos
n.enlaces.potenciales <- n.nodos * ( n.nodos - 1 ) / 2
n.enlaces <- round( n.enlaces.potenciales * p )
my.graph <- build.network( n.nodos, n.enlaces )
my.graph <- graph.data.frame( my.graph )
kk <- max( clusters( my.graph )$csize )
kk / n.nodos
}
# prop.giant.component( 2 )
foo <- function( z, n.iter = 100 )
replicate( n.iter, prop.giant.component( z ) )
zetas <- seq( 0.1, 5, by = 0.2)
res <- sapply( zetas, foo )
kk <- data.frame( res = as.numeric( t( res ) ), zetas = zetas )
plot( kk$zetas, kk$res, xlab = "", ylab = "" )
zetas <- unique( kk$zetas )
zetas <- zetas[ zetas > 1 ]
foo.optim <- function( x, z = 3 ) ( x - 1 + exp( -z * x) )**2
foo <- function( zeta ) optimize( foo.optim, z = zeta, interval = c(0,1))$minimum
theorical.sizes <- sapply( zetas, foo )
lines( zetas, theorical.sizes, col = "red")
se obtiene
con lo que nos damos por satisfechos y aguardamos a disponer de otro ratillo de asueto para sacarle la miga al capítulo II.