Los modelos de grafos aleatorios exponenciales (exponential random graph models, ERGMs) o modelos \(p^*\) se especifican de manera análoga a los modelos lineales generalizados (generalized linear models, GLMs).
Wasserman, S., & Pattison, P. (1996). Logit models and logistic regressions for social networks: I. An introduction to Markov graphs and \(p^*\). Psychometrika, 61(3), 401–425. https://doi.org/10.1007/BF02294547
Frank, O., & Strauss, D. (1986). Markov graphs. Journal of the American Statistical Association, 81(395), 832–842. https://doi.org/10.2307/2289017
https://cran.r-project.org/web/packages/ergm/vignettes/ergm.pdf
Un Modelo de Grafos Aleatorios Exponenciales (ERGM,
por sus siglas en inglés) se define como:
\[
p(\mathbf{y} \mid \boldsymbol{\theta}) = \frac{1}{\kappa} \,
\exp{\left\{ \boldsymbol{\theta}^{\textsf{T}} \,
\boldsymbol{\mathsf{g}}(\mathbf{y}) \right\}},
\]
donde:
Este modelo permite capturar dependencias complejas en la estructura de la red, incorporando tanto patrones locales como atributos externos de los nodos.
Los coeficientes \(\boldsymbol{\theta}\) indican el magnitud y la dirección del efecto de los estadísticos \(\boldsymbol{\mathsf{g}}(\mathbf{y})\) sobre la probabilidad de que la red observada adopte una estructura específica.
La probabilidad del grafo completo puede reescribirse en escala logit, utilizando las probabilidades condicionales de observar una arista entre dos nodos mientras se mantiene fija el resto de la red:
\[ \text{logit}\,\textsf{Pr}(y_{i,j}=1 \mid \mathbf{y}_{-(i,j)}) = \boldsymbol{\theta}^{\textsf{T}} \, \boldsymbol{\delta}_{i,j}(\mathbf{y}), \]
donde:
Este enfoque permite descomponer la probabilidad global de la red en términos de las dependencias locales capturadas por las estadísticas de cambio.
Aquí está el texto mejorado con la notación de \(\boldsymbol{\theta}\) colocada debajo del \(\text{arg max}\):
El estimador de máxima verosimilitud (Maximum Likelihood Estimator, MLE) de \(\boldsymbol{\theta}\) se define como:
\[ \hat{\boldsymbol{\theta}}_{\text{MLE}} = \underset{\boldsymbol{\theta}}{\text{arg max}} \, \ell(\boldsymbol{\theta}) = \underset{\boldsymbol{\theta}}{\text{arg max}} \, \left( \boldsymbol{\theta}^{\textsf{T}} \, \boldsymbol{\mathsf{g}}(\mathbf{y}) - \psi(\boldsymbol{\theta}) \right), \]
donde \(\psi(\boldsymbol{\theta}) = \log \kappa(\boldsymbol{\theta})\) es el término de normalización logarítmica, que depende de todos los posibles valores de la red \(\mathbf{y}\).
Sin embargo, \(\psi(\boldsymbol{\theta})\) no puede calcularse explícitamente, ya que requiere una suma sobre \(2^{\binom{n}{2}}\) términos (uno por cada configuración posible de la red), lo cual es computacionalmente impracticable para redes de tamaño moderado o grande.
El paquete ergm
implementa una aproximación al
estimador de máxima verosimilitud utilizando
Métodos de Monte Carlo basados en cadenas de Markov
(Markov Chain Monte Carlo, MCMC), que permiten estimar \(\psi(\boldsymbol{\theta})\) de manera
eficiente simulando una muestra representativa de redes en lugar de
evaluar todas las configuraciones posibles.
Geyer, C. J., & Thompson, E. A. (1992). Constrained Monte Carlo maximum likelihood for dependent data. Journal of the Royal Statistical Society: Series B (Methodological), 54(3), 657–683. https://doi.org/10.1111/j.2517-6161.1992.tb01443.x
Hunter, D. R., & Handcock, M. S. (2006). Inference in curved exponential family models for networks. Journal of Computational and Graphical Statistics, 15(3), 565–583. https://doi.org/10.1198/106186006X133069
Para cada par de vértices, la presencia o ausencia de una arista es independiente del estado de las demás aristas. Esto se expresa como:
\[ p(\mathbf{y} \mid \boldsymbol{\theta}) = \frac{1}{\kappa} \, \exp{\left\{ \sum_{i<j} \theta_{i,j} \, y_{i,j} \right\}}, \]
donde \(\theta_{i,j}\) representa el efecto específico para cada par de nodos \(i\) y \(j\).
Si asumimos \(\theta_{i,j} \equiv \theta\), es decir, homogeneidad relacional a través de toda la red, el modelo se simplifica a:
\[ p(\mathbf{y} \mid \boldsymbol{\theta}) = \frac{1}{\kappa} \, \exp{\left\{ \theta \, S(\mathbf{y}) \right\}}, \]
donde \(S(\mathbf{y}) = \sum_{i<j} y_{i,j}\) es el número total de aristas en el grafo. Esto implica que los log-odds de observar \(\mathbf{y}\) son proporcionales al número de aristas en la red.
Bajo estas suposiciones, el modelo es equivalente a:
\[ y_{i,j} \mid \theta \stackrel{\text{iid}}{\sim} \textsf{Bernoulli}(\textsf{expit}(\theta)), \quad i < j, \]
donde \(\textsf{expit}(x) = 1 / (1 + \exp(-x))\) es la función logística inversa, que invierte la relación de \(\textsf{logit}(x) = \log(x / (1-x))\).
En este contexto, el estadístico \(S(\mathbf{y})\) corresponde al término
edges
en el paquete ergm
, lo que modela la
densidad general de conexiones en la red.
Se examinan las relaciones matrimoniales y comerciales como mecanismos fundamentales para la estructuración y consolidación del poder entre las familias élite de Florencia durante el Renacimiento.
Mediante un enfoque histórico-social, Padgett explora cómo estas conexiones moldearon la formación de alianzas estratégicas, fortalecieron la perpetuación de jerarquías sociales y dinamizaron las relaciones políticas en un periodo crucial de transformación social y económica.
Padgett, J. F. (1994). Marriage and Elite Structure in Renaissance Florence, 1282-1500. Ponencia presentada en la reunión de la Social Science History Association, Atlanta, Georgia.
# paquetes
suppressMessages(suppressWarnings(library(ergm)))
# datos
data(florentine)
flomarriage
## Network attributes:
## vertices = 16
## directed = FALSE
## hyper = FALSE
## loops = FALSE
## multiple = FALSE
## bipartite = FALSE
## total edges= 20
## missing edges= 0
## non-missing edges= 20
##
## Vertex attribute names:
## priorates totalties vertex.names wealth
##
## No edge attributes
# clase
class(flomarriage)
## [1] "network"
# gráfico
par(mfrow = c(1,1), mar = 0.2*c(1,1,1,1))
set.seed(42)
plot(flomarriage, label = network.vertex.names(flomarriage))
Al representar los tamaños de los vértices en proporción a la riqueza, se evidencia una posible relación entre la riqueza y la sociabilidad, sugiriendo que los nodos más ricos tienden a ser más sociables o estar mejor conectados en la red.
# formulación del modelo
ergm_model<- formula(flomarriage ~ edges)
summary(ergm_model)
## edges
## 20
# ajuste del modelo
set.seed(42)
ergm_fit <- ergm(formula = ergm_model)
## Starting maximum pseudolikelihood estimation (MPLE):
## Obtaining the responsible dyads.
## Evaluating the predictor and response matrix.
## Maximizing the pseudolikelihood.
## Finished MPLE.
## Evaluating log-likelihood at the estimate.
summary(ergm_fit)
## Call:
## ergm(formula = ergm_model)
##
## Maximum Likelihood Results:
##
## Estimate Std. Error MCMC % z value Pr(>|z|)
## edges -1.6094 0.2449 0 -6.571 <1e-04 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Null Deviance: 166.4 on 120 degrees of freedom
## Residual Deviance: 108.1 on 119 degrees of freedom
##
## AIC: 110.1 BIC: 112.9 (Smaller is better. MC Std. Err. = 0)
Al ajustar un modelo ERGM, el resumen incluye una tabla con las siguientes columnas:
Interpretación general:
# estadístico
ergm_fit$nw.stats
## edges
## 20
# coeficiente
coefficients(ergm_fit)
## edges
## -1.609438
# error estándar
sqrt(vcov(ergm_fit))
## edges
## edges 0.2449487
# z value
-1.6094/0.2449
## [1] -6.571662
# H0: par = 0
2*pnorm(q = -6.571662)
## [1] 4.975671e-11
# Null model loglik
ergm_fit$null.lik
## 'log Lik.' -83.17766 (df=0)
# Null Deviance
-2*as.numeric(ergm_fit$null.lik)
## [1] 166.3553
# Model 1 loglik
ergm_fit$mle.lik
## 'log Lik.' -54.06735 (df=1)
# Residual Deviance
-2*as.numeric(ergm_fit$mle.lik)
## [1] 108.1347
# AIC = -2*loglik + 2*k
-2*as.numeric(ergm_fit$mple.lik) + 2*1
## [1] 110.1347
# BIC = -2loglik + log(n*(n-1)/2)*k
-2*as.numeric(ergm_fit$mple.lik) + log(16*15/2)*1
## [1] 112.9222
# más componentes
names(ergm_fit)
## [1] "coefficients" "iterations" "MCMCtheta" "gradient"
## [5] "hessian" "covar" "failure" "mple.lik"
## [9] "mple.lik.null" "nw.stats" "call" "network"
## [13] "ergm_version" "info" "MPLE_is_MLE" "drop"
## [17] "offset" "estimable" "etamap" "formula"
## [21] "reference" "constraints" "obs.constraints" "estimate"
## [25] "estimate.desc" "control" "null.lik" "mle.lik"
# probabilidad
expit <- function(x) 1/(1+exp(-x))
expit(-1.609438)
## [1] 0.1666667
# densidad de la red
A <- as.matrix.network.adjacency(x = flomarriage)
g <- igraph::graph_from_adjacency_matrix(adjmatrix = A, mode = "undirected")
igraph::edge_density(graph = g)
## [1] 0.1666667
El modelo NULL
corresponde al modelo de Erdős-Rényi con
\(\theta = 0.5\).
La probabilidad condicional en escala logit (log-odds) de que una arista esté presente entre dos actores, manteniendo fija el resto de la red, se calcula como: \[ \text{logit}\,\textsf{Pr}(y_{i,j}=1 \mid \mathbf{y}_{-(i,j)}) = -1.609438 \cdot (\text{cambio en el número de aristas}) = -1.609438 \cdot 1 = -1.609438. \]
En escala natural, la probabilidad correspondiente
se obtiene aplicando la función logística inversa (\(\text{expit}\)):
\[
\textsf{Pr}(y_{i,j}=1 \mid \mathbf{y}_{-(i,j)}) =
\text{expit}(-1.609438) = \frac{1}{1 + \exp(1.609438)} = 0.1666667.
\]
Esto indica que la probabilidad de que exista una arista entre dos nodos en este modelo es aproximadamente 16.67%.
# anova
anova(ergm_fit)
## Analysis of Deviance Table
##
## Model 1: flomarriage ~ edges
## Df Deviance Resid. Df Resid. Dev Pr(>|Chisq|)
## NULL 120 166.35
## Model 1: 1 58.221 119 108.14 2.343e-14 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Model 1 Deviance
166.3553 - 108.1347
## [1] 58.2206
# H0: Null model
pchisq(q = 58.221, df = 1, lower.tail = F)
## [1] 2.34265e-14
El modelo Bernoulli resulta ser significativo.
Se busca incorporar estadísticos de orden superior que capturen aspectos de la estructura global del grafo. Estos incluyen el número de \(k\)-estrellas, denotado como \(S_k(\mathbf{y})\), que representa un subgrafo compuesto por \(k+1\) vértices y \(k\) aristas, y el número de triángulos, \(T(\mathbf{y})\). Específicamente:
El modelo propuesto tiene la siguiente forma:
\[
p(\mathbf{y} \mid \boldsymbol{\theta}) = \frac{1}{\kappa} \,
\exp{\left\{ \sum_{k=1}^{n-1} \theta_k \, S_k(\mathbf{y}) + \theta_T \,
T(\mathbf{y}) \right\}},
\]
donde \(n\) es el orden del grafo (número de nodos). Este enfoque permite modelar dependencias complejas en la red mediante la inclusión de términos que reflejan tanto la densidad (\(S_1(\mathbf{y})\)) como la tendencia a formar estructuras locales más cohesionadas (\(T(\mathbf{y})\) y \(S_k(\mathbf{y})\) para \(k \geq 2\)).
Comúnmente, se ajustan modelos que incluyen los estadísticos \(S_1(\mathbf{y})\), \(S_2(\mathbf{y})\), \(S_3(\mathbf{y})\) y \(T(\mathbf{y})\).
En este caso, el estado de cualquier triángulo que contenga la díada \(y_{i,j}\) depende del estado de las díadas \(y_{i,k}\) y \(y_{j,k}\). Por lo tanto, las díadas no son probabilísticamente independientes entre sí.
A diferencia del modelo de Bernoulli, este enfoque genera grafos con dependencias estructurales entre las aristas. Específicamente, introduce una dependencia Markoviana, donde dos aristas son dependientes siempre que compartan un vértice, dadas todas las demás aristas posibles.
Sin embargo, este modelo puede enfrentar problemas de degeneración, lo que significa que la distribución de probabilidad asigna una cantidad excesivamente grande de su masa a un pequeño conjunto de configuraciones posibles, lo que limita su capacidad para representar estructuras de red diversas.
En el paquete ergm
, los términos kstar
y
triangle
se utilizan para modelar, respectivamente, las
\(k\)-estrellas y los triángulos,
capturando estas dependencias locales de forma explícita.
# formulación del modelo
ergm_model <- formula(flomarriage ~ edges + triangles)
summary(ergm_model)
## edges triangle
## 20 3
# ajuste del modelo
set.seed(42)
ergm_fit <- ergm(formula = ergm_model)
## Starting maximum pseudolikelihood estimation (MPLE):
## Obtaining the responsible dyads.
## Evaluating the predictor and response matrix.
## Maximizing the pseudolikelihood.
## Finished MPLE.
## Starting Monte Carlo maximum likelihood estimation (MCMLE):
## Iteration 1 of at most 60:
## Warning: 'glpk' selected as the solver, but package 'Rglpk' is not available;
## falling back to 'lpSolveAPI'. This should be fine unless the sample size and/or
## the number of parameters is very big.
## 1
## Optimizing with step length 1.0000.
## The log-likelihood improved by 0.0237.
## Convergence test p-value: 0.0001. Converged with 99% confidence.
## Finished MCMLE.
## Evaluating log-likelihood at the estimate. Fitting the dyad-independent submodel...
## Bridging between the dyad-independent submodel and the full model...
## Setting up bridge sampling...
## Using 16 bridges: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 .
## Bridging finished.
##
## This model was fit using MCMC. To examine model diagnostics and check
## for degeneracy, use the mcmc.diagnostics() function.
summary(ergm_fit)
## Call:
## ergm(formula = ergm_model)
##
## Monte Carlo Maximum Likelihood Results:
##
## Estimate Std. Error MCMC % z value Pr(>|z|)
## edges -1.6507 0.3179 0 -5.192 <1e-04 ***
## triangle 0.1082 0.5184 0 0.209 0.835
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Null Deviance: 166.4 on 120 degrees of freedom
## Residual Deviance: 108.1 on 118 degrees of freedom
##
## AIC: 112.1 BIC: 117.7 (Smaller is better. MC Std. Err. = 0.006221)
# probabilidades
expit(-1.6862)
## [1] 0.1562762
expit(-1.5296)
## [1] 0.1780522
La probabilidad condicional en escala logit (log-odds) de que una arista \(y_{i,j}\) esté presente entre dos actores, manteniendo fija el resto de la red, se define como:
\[ \text{logit}\,\textsf{Pr}(y_{i,j}=1 \mid \mathbf{y}_{-(i,j)}) = -1.6862 \cdot (\text{cambio en el número de aristas}) + 0.1566 \cdot (\text{cambio en el número de triángulos}). \]
En escala de probabilidad natural, estas log-odds se transforman mediante la función logística inversa (\(\text{expit}\)):
Esto muestra que la probabilidad de que exista una arista aumenta ligeramente cuando contribuye a la formación de un triángulo, reflejando la influencia positiva de la estadística de triángulos sobre la estructura de la red.
# anova
anova(ergm_fit)
## Analysis of Deviance Table
##
## Model 1: flomarriage ~ edges + triangles
## Df Deviance Resid. Df Resid. Dev Pr(>|Chisq|)
## NULL 120 166.35
## Model 1: 2 58.274 118 108.08 2.218e-13 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
El modelo resulta ser significativo.
Sampson (1969) documentó las interacciones sociales entre un grupo de monjes durante su residencia en un claustro, con un interés particular en las relaciones de afecto positivo.
En el estudio, cada monje seleccionó sus tres principales opciones (o cuatro, en caso de empate) de relaciones de “agrado”. Se considera que existe una arista dirigida del monje A al monje B si A incluyó a B entre sus principales elecciones. Este enfoque permite capturar la estructura de las preferencias sociales dentro del grupo.
Sampson, S. F. (1968). A novitiate in a period of change: An experimental and case study of relationships. Tesis doctoral no publicada, Departamento de Sociología, Cornell University.
# datos
data(samplk)
samplk3
## Network attributes:
## vertices = 18
## directed = TRUE
## hyper = FALSE
## loops = FALSE
## multiple = FALSE
## bipartite = FALSE
## total edges= 56
## missing edges= 0
## non-missing edges= 56
##
## Vertex attribute names:
## cloisterville group vertex.names
##
## No edge attributes
# gráfico
par(mfrow = c(1,1), mar = 0.2*c(1,1,1,1))
set.seed(42)
plot(samplk3, vertex.cex = 2)
# formulación del modelo
ergm_model <- formula(samplk3 ~ edges + mutual)
summary(ergm_model)
## edges mutual
## 56 15
# ajuste del modelo
set.seed(42)
ergm_fit <- ergm(formula = ergm_model)
## Starting maximum pseudolikelihood estimation (MPLE):
## Obtaining the responsible dyads.
## Evaluating the predictor and response matrix.
## Maximizing the pseudolikelihood.
## Finished MPLE.
## Starting Monte Carlo maximum likelihood estimation (MCMLE):
## Iteration 1 of at most 60:
## 1 Optimizing with step length 1.0000.
## The log-likelihood improved by 0.0003.
## Convergence test p-value: < 0.0001. Converged with 99% confidence.
## Finished MCMLE.
## Evaluating log-likelihood at the estimate. Fitting the dyad-independent submodel...
## Bridging between the dyad-independent submodel and the full model...
## Setting up bridge sampling...
## Using 16 bridges: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 .
## Bridging finished.
##
## This model was fit using MCMC. To examine model diagnostics and check
## for degeneracy, use the mcmc.diagnostics() function.
summary(ergm_fit)
## Call:
## ergm(formula = ergm_model)
##
## Monte Carlo Maximum Likelihood Results:
##
## Estimate Std. Error MCMC % z value Pr(>|z|)
## edges -2.1489 0.2210 0 -9.724 <1e-04 ***
## mutual 2.2849 0.4786 0 4.774 <1e-04 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Null Deviance: 424.2 on 306 degrees of freedom
## Residual Deviance: 267.7 on 304 degrees of freedom
##
## AIC: 271.7 BIC: 279.1 (Smaller is better. MC Std. Err. = 0.3338)
# probabilidades
expit(0.1449)
## [1] 0.5361618
expit(-2.1707)
## [1] 0.1024127
# anova
anova(ergm_fit)
## Analysis of Deviance Table
##
## Model 1: samplk3 ~ edges + mutual
## Df Deviance Resid. Df Resid. Dev Pr(>|Chisq|)
## NULL 306 424.21
## Model 1: 2 156.51 304 267.70 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
El modelo resulta ser significativo.
La plausibilidad de que una arista conecte dos vértices no solo depende del estado de las aristas (\(0\) o \(1\)), sino también de los atributos de los vértices (variables exógenas).
En un ERGM, los atributos de los vértices pueden
integrarse mediante la siguiente formulación:
\[
\boldsymbol{\mathsf{g}}(\mathbf{y}, \mathbf{x}) = \sum_{i<j} y_{i,j}
\, h(\mathbf{x}_i, \mathbf{x}_j),
\]
donde: - \(h(\mathbf{x}_i,
\mathbf{x}_j)\): Es una función simétrica que
evalúa cómo interactúan los atributos \(\mathbf{x}_i\) y \(\mathbf{x}_j\).
- \(\mathbf{x}_i\): Es el vector de
atributos observados del vértice \(i\).
Efectos principales:
ergm
mediante: nodecov
o
nodemain
.Efectos de segundo orden (homofilia, coincidencia de atributos):
ergm
mediante: match
.Efectos de segundo orden (homofilia, diferencia de atributos):
ergm
mediante: nodematch
o
absdiff
.Esta flexibilidad permite que los modelos ERGM incorporen patrones relacionales que dependen de características individuales, como la homofilia o la influencia de atributos nodales en las conexiones de la red.
La riqueza parecía estar asociada con un mayor grado en esta red:
# atributos
(wealth <- flomarriage %v% 'wealth')
## [1] 10 36 55 44 20 32 8 42 103 48 49 3 27 10 146 48
# descripción
summary(wealth)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 3.00 17.50 39.00 42.56 48.25 146.00
# gráfico
par(mfrow = c(1,1), mar = 0.2*c(1,1,1,1))
set.seed(42)
plot(flomarriage, label = network.vertex.names(flomarriage), vertex.cex = wealth/25)
# formulación del modelo
ergm_model <- formula(flomarriage ~ edges + nodemain('wealth'))
summary(ergm_model)
## edges nodecov.wealth
## 20 2168
# nodecov.wealth
A <- as.matrix.network.adjacency(x = flomarriage)
B <- outer(X = wealth, Y = wealth, FUN = "+")
sum(A*B)/2
## [1] 2168
# ajuste del modelo
set.seed(42)
ergm_fit <- ergm(formula = ergm_model)
## Starting maximum pseudolikelihood estimation (MPLE):
## Obtaining the responsible dyads.
## Evaluating the predictor and response matrix.
## Maximizing the pseudolikelihood.
## Finished MPLE.
## Evaluating log-likelihood at the estimate.
summary(ergm_fit)
## Call:
## ergm(formula = ergm_model)
##
## Maximum Likelihood Results:
##
## Estimate Std. Error MCMC % z value Pr(>|z|)
## edges -2.594929 0.536056 0 -4.841 <1e-04 ***
## nodecov.wealth 0.010546 0.004674 0 2.256 0.0241 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Null Deviance: 166.4 on 120 degrees of freedom
## Residual Deviance: 103.1 on 118 degrees of freedom
##
## AIC: 107.1 BIC: 112.7 (Smaller is better. MC Std. Err. = 0)
# probabilidades
expit(-2.531653)
## [1] 0.07366876
expit(0.484503)
## [1] 0.6188106
La probabilidad condicional en escala logit
(log-odds) de que una arista \(y_{i,j}\) esté presente entre dos actores,
manteniendo fija el resto de la red, se calcula como:
\[
\text{logit}\,\textsf{Pr}(y_{i,j}=1 \mid \mathbf{y}_{-(i,j)}) =
-2.594929 \cdot (\text{cambio en el número de aristas}) + 0.010546 \cdot
(\text{suma de la riqueza de los dos nodos}).
\]
Para una arista entre dos nodos con la mínima riqueza
(\(3+3\)):
El log-odds condicional es:
\[
-2.594929 + 0.010546 \cdot (3+3) = -2.531653.
\]
En escala natural, la probabilidad correspondiente es:
\[
\text{expit}(-2.531653) = \frac{1}{1 + \exp(2.531653)} \approx 0.0737.
\]
Para una arista entre dos nodos con la máxima riqueza
(\(146+146\)):
El log-odds condicional es:
\[
-2.594929 + 0.010546 \cdot (146+146) = 0.484503.
\]
En escala natural, la probabilidad correspondiente es:
\[
\text{expit}(0.484503) = \frac{1}{1 + \exp(-0.484503)} \approx 0.6188.
\]
La probabilidad de que exista una arista aumenta significativamente con la suma de la riqueza de los dos nodos involucrados. Para nodos con riqueza mínima, la probabilidad de conexión es de aproximadamente 7.37%, mientras que para nodos con riqueza máxima asciende a 61.88%, lo que resalta el impacto positivo de este atributo en la formación de aristas.
# anova
anova(ergm_fit)
## Analysis of Deviance Table
##
## Model 1: flomarriage ~ edges + nodemain("wealth")
## Df Deviance Resid. Df Resid. Dev Pr(>|Chisq|)
## NULL 120 166.35
## Model 1: 2 63.247 118 103.11 1.846e-14 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
El modelo resulta significativo.
Red de amistades entre estudiantes de una institución educativa, analizada como parte del estudio AddHealth.
La comunidad escolar está ubicada en una zona rural del oeste de los Estados Unidos, con un alumnado predominantemente hispano y nativo americano.
El análisis se centra en la homofilia dentro de las amistades, examinando cómo los estudiantes tienden a formar vínculos basados en atributos discretos como el grado académico y la raza.
Resnick, M. D., Bearman, P. S., Blum, R. W., et al. (1997). Protecting adolescents from harm: Findings from the National Longitudinal Study on Adolescent Health. Journal of the American Medical Association, 278, 823–832. https://doi.org/10.1001/jama.1997.03550100049038
# datos
data(faux.mesa.high)
(mesa <- faux.mesa.high)
## Network attributes:
## vertices = 205
## directed = FALSE
## hyper = FALSE
## loops = FALSE
## multiple = FALSE
## bipartite = FALSE
## total edges= 203
## missing edges= 0
## non-missing edges= 203
##
## Vertex attribute names:
## Grade Race Sex
##
## No edge attributes
# grado
table(mesa %v% 'Grade')
##
## 7 8 9 10 11 12
## 62 40 42 25 24 12
# raza
table(mesa %v% 'Race')
##
## Black Hisp NatAm Other White
## 6 109 68 4 18
# sexo
table(mesa %v% 'Sex')
##
## F M
## 99 106
# gráfico
par(mfrow = c(1,1), mar = 0.2*c(1,1,1,1))
set.seed(42)
plot(mesa, vertex.col = 'Grade', vertex.cex = 1.2)
legend('bottomleft', fill = 7:12, legend = paste('Grade', 7:12), cex = 0.8, bty = "n")
El término nodefactor
en un modelo ERGM se utiliza para
evaluar cómo un atributo categórico de los vértices influye en la
formación de aristas en la red. Este término es especialmente útil
cuando se desea capturar diferencias en la propensión a
conectarse de los nodos según los valores de un atributo
específico:
edges
, ya que la suma de estas estadísticas es igual al
número total de aristas en la red. Esto debe
considerarse al diseñar el modelo para evitar problemas de
identificabilidad.El término nodematch
en un modelo ERGM
mide la homofilia, es decir, la
tendencia de los nodos a conectarse con otros que
comparten el mismo valor de un atributo específico. Es
útil para evaluar cómo los valores compartidos de un
atributo categórico influyen en la formación de aristas
en la red.
nodematch(.)
incluye una única
estadística que mide el número total de
aristas entre nodos que comparten el mismo valor del atributo,
como Race
, sin distinguir entre categorías
específicas.nodematch(., diff=TRUE)
incluye
varias estadísticas, una por cada categoría del
atributo, contando las aristas entre nodos con ese valor
específico.El término match
en un modelo
ERGM mide la homofilia, es decir, la
tendencia de los nodos conectados por una arista a
compartir el mismo valor de un atributo categórico. Es
útil para evaluar si ciertos atributos promueven
vínculos dentro de la red.
match
: Evalúa la homofilia
general, contando el número total de aristas
donde los nodos comparten un valor específico del atributo. Genera una
única estadística.nodematch
: Similar a
match
, pero más flexible:
diff
: Igual que
match
, genera una única
estadística.diff = TRUE
: Genera
estadísticas separadas para cada categoría del
atributo, permitiendo analizar la homofilia por valor
específico.# formulación del modelo
ergm_model <- formula(mesa ~ edges + nodefactor('Grade') + nodematch('Grade', diff=T) + nodefactor('Race') + nodematch('Race', diff=T))
summary(ergm_model)
## edges nodefactor.Grade.8 nodefactor.Grade.9
## 203 75 65
## nodefactor.Grade.10 nodefactor.Grade.11 nodefactor.Grade.12
## 36 49 28
## nodematch.Grade.7 nodematch.Grade.8 nodematch.Grade.9
## 75 33 23
## nodematch.Grade.10 nodematch.Grade.11 nodematch.Grade.12
## 9 17 6
## nodefactor.Race.Hisp nodefactor.Race.NatAm nodefactor.Race.Other
## 178 156 1
## nodefactor.Race.White nodematch.Race.Black nodematch.Race.Hisp
## 45 0 53
## nodematch.Race.NatAm nodematch.Race.Other nodematch.Race.White
## 46 0 4
¡Cuidado! Hay varios 0s.
# ajuste del modelo
set.seed(42)
ergm_fit <- ergm(formula = ergm_model)
## Observed statistic(s) nodematch.Race.Black and nodematch.Race.Other are at their smallest attainable values. Their coefficients will be fixed at -Inf.
## Starting maximum pseudolikelihood estimation (MPLE):
## Obtaining the responsible dyads.
## Evaluating the predictor and response matrix.
## Maximizing the pseudolikelihood.
## Finished MPLE.
## Evaluating log-likelihood at the estimate.
summary(ergm_fit)
## Call:
## ergm(formula = ergm_model)
##
## Maximum Likelihood Results:
##
## Estimate Std. Error MCMC % z value Pr(>|z|)
## edges -8.0538 1.2561 0 -6.412 < 1e-04 ***
## nodefactor.Grade.8 1.5201 0.6858 0 2.216 0.026663 *
## nodefactor.Grade.9 2.5284 0.6493 0 3.894 < 1e-04 ***
## nodefactor.Grade.10 2.8652 0.6512 0 4.400 < 1e-04 ***
## nodefactor.Grade.11 2.6291 0.6563 0 4.006 < 1e-04 ***
## nodefactor.Grade.12 3.4629 0.6566 0 5.274 < 1e-04 ***
## nodematch.Grade.7 7.4662 1.1730 0 6.365 < 1e-04 ***
## nodematch.Grade.8 4.2882 0.7150 0 5.997 < 1e-04 ***
## nodematch.Grade.9 2.0371 0.5538 0 3.678 0.000235 ***
## nodematch.Grade.10 1.2489 0.6233 0 2.004 0.045111 *
## nodematch.Grade.11 2.4521 0.6124 0 4.004 < 1e-04 ***
## nodematch.Grade.12 1.2987 0.6981 0 1.860 0.062824 .
## nodefactor.Race.Hisp -1.6659 0.2963 0 -5.622 < 1e-04 ***
## nodefactor.Race.NatAm -1.4725 0.2869 0 -5.132 < 1e-04 ***
## nodefactor.Race.Other -2.9618 1.0372 0 -2.856 0.004296 **
## nodefactor.Race.White -0.8488 0.2958 0 -2.869 0.004112 **
## nodematch.Race.Black -Inf 0.0000 0 -Inf < 1e-04 ***
## nodematch.Race.Hisp 0.6912 0.3451 0 2.003 0.045153 *
## nodematch.Race.NatAm 1.2482 0.3550 0 3.517 0.000437 ***
## nodematch.Race.Other -Inf 0.0000 0 -Inf < 1e-04 ***
## nodematch.Race.White 0.3140 0.6405 0 0.490 0.623947
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Null Deviance: 28958 on 20889 degrees of freedom
## Residual Deviance: 1798 on 20868 degrees of freedom
##
## AIC: 1836 BIC: 1987 (Smaller is better. MC Std. Err. = 0)
##
## Warning: The following terms have infinite coefficient estimates:
## nodematch.Race.Black nodematch.Race.Other
Algunos coeficientes dan como resultado -Inf
dado
que:
mixingmatrix(object = mesa, attrname = "Race")
## Black Hisp NatAm Other White
## Black 0 8 13 0 5
## Hisp 8 53 41 1 22
## NatAm 13 41 46 0 10
## Other 0 1 0 0 0
## White 5 22 10 0 4
## Note: Marginal totals can be misleading for undirected mixing matrices.
# anova
anova(ergm_fit)
## Analysis of Deviance Table
##
## Model 1: mesa ~ edges + nodefactor("Grade") + nodematch("Grade", diff = T) +
## nodefactor("Race") + nodematch("Race", diff = T)
## Df Deviance Resid. Df Resid. Dev Pr(>|Chisq|)
## NULL 20889 28958.3
## Model 1: 19 27161 20870 1797.7 < 2.2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
El modelo resulta ser significativo.
En ciertas ocasiones, los algoritmos computacionales de
ergm
emplean Métodos de Monte
Carlo basados en Cadenas de Markov (Markov Chain Monte
Carlo, MCMC) para estimar y ajustar el modelo.
El término degree(1)
cuenta el número de nodos con
exactamente un grado igual a 1 (conectados a un solo
nodo). Es útil para:
Este término ayuda a analizar cómo los nodos periféricos contribuyen a la probabilidad global de la red.
# formulación del modelo
ergm_model <- formula(flomarriage ~ edges + degree(1))
summary(ergm_model)
## edges degree1
## 20 4
# ajuste del modelo
set.seed(42)
ergm_fit <- ergm(formula = ergm_model)
## Starting maximum pseudolikelihood estimation (MPLE):
## Obtaining the responsible dyads.
## Evaluating the predictor and response matrix.
## Maximizing the pseudolikelihood.
## Finished MPLE.
## Starting Monte Carlo maximum likelihood estimation (MCMLE):
## Iteration 1 of at most 60:
## 1 Optimizing with step length 1.0000.
## The log-likelihood improved by 0.0937.
## Convergence test p-value: 0.0004. Converged with 99% confidence.
## Finished MCMLE.
## Evaluating log-likelihood at the estimate. Fitting the dyad-independent submodel...
## Bridging between the dyad-independent submodel and the full model...
## Setting up bridge sampling...
## Using 16 bridges: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 .
## Bridging finished.
##
## This model was fit using MCMC. To examine model diagnostics and check
## for degeneracy, use the mcmc.diagnostics() function.
summary(ergm_fit)
## Call:
## ergm(formula = ergm_model)
##
## Monte Carlo Maximum Likelihood Results:
##
## Estimate Std. Error MCMC % z value Pr(>|z|)
## edges -1.4679 0.3625 0 -4.050 <1e-04 ***
## degree1 0.5759 0.6483 0 0.888 0.374
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Null Deviance: 166.4 on 120 degrees of freedom
## Residual Deviance: 107.8 on 118 degrees of freedom
##
## AIC: 111.8 BIC: 117.4 (Smaller is better. MC Std. Err. = 0.02837)
# diagnósticos de convergencia
mcmc.diagnostics(ergm_fit)
## Sample statistics summary:
##
## Iterations = 14336:262144
## Thinning interval = 1024
## Number of chains = 1
## Sample size per chain = 243
##
## 1. Empirical mean and standard deviation for each variable,
## plus standard error of the mean:
##
## Mean SD Naive SE Time-series SE
## edges -1.259 4.248 0.2725 0.4169
## degree1 1.021 2.375 0.1523 0.1523
##
## 2. Quantiles for each variable:
##
## 2.5% 25% 50% 75% 97.5%
## edges -9 -4 -1 1 7.00
## degree1 -3 -1 1 3 5.95
##
##
## Are sample statistics significantly different from observed?
## edges degree1 (Omni)
## diff. -1.259259259 1.020576e+00 NA
## test stat. -3.020563893 6.698943e+00 4.517970e+01
## P-val. 0.002523045 2.099328e-11 1.110195e-09
##
## Sample statistics cross-correlations:
## edges degree1
## edges 1.0000000 -0.7580745
## degree1 -0.7580745 1.0000000
##
## Sample statistics auto-correlation:
## Chain 1
## edges degree1
## Lag 0 1.00000000 1.00000000
## Lag 1024 0.09872931 0.07393764
## Lag 2048 0.03752647 -0.02494107
## Lag 3072 0.02217604 -0.01614951
## Lag 4096 -0.13556624 -0.06972416
## Lag 5120 -0.05594634 -0.07555557
##
## Sample statistics burn-in diagnostic (Geweke):
## Chain 1
##
## Fraction in 1st window = 0.1
## Fraction in 2nd window = 0.5
##
## edges degree1
## -1.8229617 0.2473868
##
## Individual P-values (lower = worse):
## edges degree1
## 0.06830919 0.80460886
## Joint P-value (lower = worse): 0.07784152
##
## Note: MCMC diagnostics shown here are from the last round of
## simulation, prior to computation of final parameter estimates.
## Because the final estimates are refinements of those used for this
## simulation run, these diagnostics may understate model performance.
## To directly assess the performance of the final model on in-model
## statistics, please use the GOF command: gof(ergmFitObject,
## GOF=~model).
Los valores en los distintos lags representan la
autocorrelación entre las estadísticas
(edges
y degree1
) a medida que avanza la
cadena.
edges
, la autocorrelación es baja desde \(\text{lag} = 2048\) (\(< 0.05\)) y negativa en lags más altos
(\(-0.1356\) y \(-0.0559\)).degree1
, la autocorrelación es muy baja o negativa
a partir de \(\text{lag} = 2048\), lo
que sugiere buena mezcla en la cadena para ambos términos.El test de Geweke evalúa si la media de la estadística al inicio de la cadena (10%) es significativamente diferente de la media al final (50%).
edges
: \(Z = -1.823\):
Está cerca del umbral crítico (\(-1.96\)), pero el valor \(p = 0.0683\) indica que no es
significativamente diferente (\(p >
0.05\)). Hay indicios de ligera inestabilidad, pero no es
crítica.degree1
: \(Z =
0.247\): Muy cerca de 0, lo que indica que no hay diferencias
significativas entre el inicio y el final (\(p
= 0.8046\)). Esto sugiere una buena convergencia para esta
estadística.edges
está cerca del umbral.Una vez estimados los coeficientes de un ERGM, el modelo queda completamente especificado, definiendo una distribución de probabilidad sobre todas las redes posibles del mismo tamaño.
Si el modelo se ajusta correctamente a los datos observados, las redes simuladas a partir de esta distribución tendrán una mayor probabilidad de “parecerse” a los datos observados, reflejando patrones similares en términos de las estadísticas modeladas.
# librerías
suppressMessages(suppressWarnings(library(igraph)))
suppressMessages(suppressWarnings(library(ergm)))
suppressMessages(suppressWarnings(library(intergraph)))
# ajuste del modelo
set.seed(42)
ergm_model <- formula(flomarriage ~ edges + nodemain('wealth'))
ergm_fit <- ergm(formula = ergm_model)
## Starting maximum pseudolikelihood estimation (MPLE):
## Obtaining the responsible dyads.
## Evaluating the predictor and response matrix.
## Maximizing the pseudolikelihood.
## Finished MPLE.
## Evaluating log-likelihood at the estimate.
# Generar 1000 redes simuladas a partir del modelo ajustado
set.seed(123)
simulated_networks <- simulate(ergm_fit, nsim = 10000, output = "network")
# Convertir flomarriage a un objeto igraph
flomarriage_igraph <- intergraph::asIgraph(flomarriage)
# Calcular las estadísticas observadas
observed_density <- edge_density(flomarriage_igraph)
observed_transitivity <- transitivity(flomarriage_igraph, type = "global")
observed_assortativity <- assortativity(flomarriage_igraph, V(flomarriage_igraph)$wealth)
# Crear listas para almacenar las estadísticas de las redes simuladas
simulated_densities <- numeric(10000)
simulated_transitivities <- numeric(10000)
simulated_assortativities <- numeric(10000)
# Calcular las estadísticas para cada red simulada
for (i in seq_along(simulated_networks)) {
# Convertir la red simulada al formato igraph
net <- intergraph::asIgraph(simulated_networks[[i]])
# Calcular las estadísticas
simulated_densities[i] <- edge_density(net)
simulated_transitivities[i] <- transitivity(net, type = "global")
simulated_assortativities[i] <- assortativity(net, V(net)$wealth)
}
# Calcular los intervalos de confianza al 95% basados en percentiles
ci_lower <- c(
quantile(simulated_densities, 0.025),
quantile(simulated_transitivities, 0.025),
quantile(simulated_assortativities, 0.025)
)
ci_upper <- c(
quantile(simulated_densities, 0.975),
quantile(simulated_transitivities, 0.975),
quantile(simulated_assortativities, 0.975)
)
# Completar la tabla con los intervalos de confianza
resultados <- data.frame(
Estadística = c("Densidad", "Transitividad", "Asortatividad"),
Observado = c(observed_density, observed_transitivity, observed_assortativity),
Media_Simulada = c(mean(simulated_densities), mean(simulated_transitivities), mean(simulated_assortativities)),
Desviación_Simulada = c(sd(simulated_densities), sd(simulated_transitivities), sd(simulated_assortativities)),
IC_Inferior = ci_lower,
IC_Superior = ci_upper
)
# Mostrar una versión estilizada de la tabla
library(knitr)
library(kableExtra)
resultados %>%
kbl(
caption = "Resumen de las estadísticas observadas y simuladas con intervalos de confianza al 95%",
digits = 4,
col.names = c("Estadística", "Observado", "Media", "Desviación", "IC Inferior", "IC Superior")
) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE) %>%
column_spec(1, bold = TRUE) %>%
add_header_above(c(" " = 1, "Estadísticas Observadas y Simuladas" = 5))
Estadística | Observado | Media | Desviación | IC Inferior | IC Superior |
---|---|---|---|---|---|
Densidad | 0.1667 | 0.1669 | 0.0331 | 0.1083 | 0.2333 |
Transitividad | 0.1915 | 0.1736 | 0.0958 | 0.0000 | 0.3529 |
Asortatividad | -0.3024 | -0.1514 | 0.1597 | -0.4473 | 0.1828 |