library(latentnet)
## Loading required package: network
## network: Classes for Relational Data
## Version 1.16.0 created on 2019-11-30.
## copyright (c) 2005, Carter T. Butts, University of California-Irvine
## Mark S. Handcock, University of California -- Los Angeles
## David R. Hunter, Penn State University
## Martina Morris, University of Washington
## Skye Bender-deMoll, University of Washington
## For citation information, type citation("network").
## Type help("network-package") to get started.
## Loading required package: ergm
##
## ergm: version 3.10.4, created on 2019-06-10
## Copyright (c) 2019, Mark S. Handcock, University of California -- Los Angeles
## David R. Hunter, Penn State University
## Carter T. Butts, University of California -- Irvine
## Steven M. Goodreau, University of Washington
## Pavel N. Krivitsky, University of Wollongong
## Martina Morris, University of Washington
## with contributions from
## Li Wang
## Kirk Li, University of Washington
## Skye Bender-deMoll, University of Washington
## Chad Klumb
## Based on "statnet" project software (statnet.org).
## For license and citation information see statnet.org/attribution
## or type citation("ergm").
## NOTE: Versions before 3.6.1 had a bug in the implementation of the bd()
## constriant which distorted the sampled distribution somewhat. In
## addition, Sampson's Monks datasets had mislabeled vertices. See the
## NEWS and the documentation for more details.
## NOTE: Some common term arguments pertaining to vertex attribute and
## level selection have changed in 3.10.0. See terms help for more
## details. Use 'options(ergm.term=list(version="3.9.4"))' to use old
## behavior.
##
## latentnet: version 2.10.5, created on 2020-03-20
## Copyright (c) 2020, Pavel N. Krivitsky
## Mark S. Handcock, University of California -- Los Angeles
## with contributions from
## Susan M. Shortreed
## Jeremy Tantrum
## Peter D. Hoff
## Li Wang
## Kirk Li, University of Washington
## Jake Fisher
## Jordan T. Bates
## Based on "statnet" project software (statnet.org).
## For license and citation information see statnet.org/attribution
## or type citation("latentnet").
## NOTE: BIC calculation prior to latentnet 2.7.0 had a bug in the calculation of the effective number of parameters. See help(summary.ergmm) for details.
## NOTE: Prior to version 2.8.0, handling of fixed effects for directed networks had a bug. See help("ergmm-terms") for details.
data("sampson")
network.vertex.names(samplike)
## [1] "John Bosco" "Gregory" "Basil" "Peter" "Bonaventure"
## [6] "Berthold" "Mark" "Victor" "Ambrose" "Romauld"
## [11] "Louis" "Winfrid" "Amand" "Hugh" "Boniface"
## [16] "Albert" "Elias" "Simplicius"
samplike %v% "group"
## [1] "Turks" "Turks" "Outcasts" "Loyal" "Loyal" "Loyal"
## [7] "Turks" "Loyal" "Loyal" "Loyal" "Loyal" "Turks"
## [13] "Outcasts" "Turks" "Turks" "Turks" "Outcasts" "Outcasts"
samplike.fit=ergmm(samplike ~ euclidean(d=2),verbose=TRUE)
## Generating initial values for MCMC:
## Computing geodesic distances... Finished.
## Computing MDS locations... Finished.
## Computing other initial values... Finished.
## Finding the conditional posterior mode... Finished.
## Burning in... Finished.
## Starting sampling run... Finished.
## Post-processing the MCMC output:
## Fitting the MKL locations... Finished.
## MKL MBC is not available or non-latent-cluster model.
## Performing Procrustes transformation... Finished.
#We fit samplike network data using latent space model with 2-dim Euclidean space
#if we use euclidean(d=2),we do not add any group structure in latent space model
#if we use euclidean(d=2),we do not add any group structure in latent position of vertices
#if we use euclidean(d=2,G=3),we add a group structure in latent position of vertices
#do not use d=1
#because we do not have any covariate, we only consider the intercept term.
#logit(pi_{i})=\alpha-|z_i - z_j|
#when we have covariate, we need to change them to the matrix form by using either main
#effect, homophily effect or absolute difference
#logit(pi_{i})=\alpha+\beta x_{ij}-|z_i - z_j|
samplike.fit$mcmc.pmode$Z
## [,1] [,2]
## [1,] 0.3603455 0.07665688
## [2,] -0.3362347 1.28367030
## [3,] -1.6434457 -1.60823125
## [4,] 2.4307748 -0.59872128
## [5,] 0.9203736 -0.30627673
## [6,] 1.9041286 -0.59138112
## [7,] -0.6730192 1.39097225
## [8,] 1.6677833 -1.32844644
## [9,] 1.0783131 -1.57407550
## [10,] 1.6574102 -1.33609880
## [11,] 2.7711144 0.73853083
## [12,] -0.5425823 1.59002931
## [13,] -0.6589592 -1.15220444
## [14,] 0.4301689 1.73783700
## [15,] 0.1482861 1.80861789
## [16,] -0.9999788 1.50469586
## [17,] -1.9100392 -1.31141963
## [18,] -1.4461493 -1.15082996
#Z is latent position
oneL=samplike %v% "group"
oneL[oneL=="Turks"]="T"
oneL[oneL=="Outcasts"]="O"
oneL[oneL=="Loyal"]="L"
oneL[c(1,7,15)]="W"
oneL
## [1] "W" "T" "O" "L" "L" "L" "W" "L" "L" "L" "L" "T" "O" "T" "W" "T" "O" "O"
oneLcolors=c("red","blue","black","green")[match(oneL, c("T","O","L","W"))]
plot(samplike.fit,label=oneL,vertex.col = oneLcolors,
what="pmean",main="MCMC positions",print.formula = FALSE,labels=TRUE)
#due to the invariance property of the latent space, positions can be rotated
#however, if you rotate your latent space plot, you will have same plot
#that is just the difference in representation
Model Fitting: Eigenmodel
library(sand)
## Loading required package: igraph
##
## Attaching package: 'igraph'
## The following objects are masked from 'package:network':
##
## %c%, %s%, add.edges, add.vertices, delete.edges, delete.vertices,
## get.edge.attribute, get.edges, get.vertex.attribute, is.bipartite,
## is.directed, list.edge.attributes, list.vertex.attributes,
## set.edge.attribute, set.vertex.attribute
## The following objects are masked from 'package:stats':
##
## decompose, spectrum
## The following object is masked from 'package:base':
##
## union
## Loading required package: igraphdata
##
## Statistical Analysis of Network Data with R
## Type in C2 (+ENTER) to start with Chapter 2.
data(lazega)
summary(lazega)
## This graph was created by an old(er) igraph version.
## Call upgrade_graph() on it to use with the current igraph version
## For now we convert it on the fly...
## IGRAPH NA UN-- 36 115 --
## + attr: name (v/c), Seniority (v/n), Status (v/n), Gender (v/n), Office
## | (v/n), Years (v/n), Age (v/n), Practice (v/n), School (v/n)
library(eigenmodel)
lazega=upgrade_graph(lazega)
A=get.adjacency(lazega,sparse=FALSE)
lazega.leig.fit1=eigenmodel_mcmc(A, R=2, S=10000, burn=10000)
## 5 percent done (iteration 1000) Mon Jun 22 00:12:49 2020
## 10 percent done (iteration 2000) Mon Jun 22 00:12:55 2020
## 15 percent done (iteration 3000) Mon Jun 22 00:13:00 2020
## 20 percent done (iteration 4000) Mon Jun 22 00:13:06 2020
## 25 percent done (iteration 5000) Mon Jun 22 00:13:12 2020
## 30 percent done (iteration 6000) Mon Jun 22 00:13:17 2020
## 35 percent done (iteration 7000) Mon Jun 22 00:13:23 2020
## 40 percent done (iteration 8000) Mon Jun 22 00:13:29 2020
## 45 percent done (iteration 9000) Mon Jun 22 00:13:34 2020
## 50 percent done (iteration 10000) Mon Jun 22 00:13:40 2020
## 55 percent done (iteration 11000) Mon Jun 22 00:13:46 2020
## 60 percent done (iteration 12000) Mon Jun 22 00:13:51 2020
## 65 percent done (iteration 13000) Mon Jun 22 00:13:57 2020
## 70 percent done (iteration 14000) Mon Jun 22 00:14:03 2020
## 75 percent done (iteration 15000) Mon Jun 22 00:14:08 2020
## 80 percent done (iteration 16000) Mon Jun 22 00:14:14 2020
## 85 percent done (iteration 17000) Mon Jun 22 00:14:22 2020
## 90 percent done (iteration 18000) Mon Jun 22 00:14:29 2020
## 95 percent done (iteration 19000) Mon Jun 22 00:14:35 2020
## 100 percent done (iteration 20000) Mon Jun 22 00:14:42 2020
#R=dimension
#This model is without any covariate
same.prac.op=v.attr.lazega$Practice %o% v.attr.lazega$Practice
same.prac=matrix(as.numeric(same.prac.op %in% c(1,4,9)),36,36)
same.prac=array(same.prac,dim=c(36,36,1))
lazega.leig.fit2=eigenmodel_mcmc(A,same.prac, R=2, S=10000, burn=10000)
## 5 percent done (iteration 1000) Mon Jun 22 00:14:50 2020
## 10 percent done (iteration 2000) Mon Jun 22 00:14:56 2020
## 15 percent done (iteration 3000) Mon Jun 22 00:15:03 2020
## 20 percent done (iteration 4000) Mon Jun 22 00:15:09 2020
## 25 percent done (iteration 5000) Mon Jun 22 00:15:16 2020
## 30 percent done (iteration 6000) Mon Jun 22 00:15:22 2020
## 35 percent done (iteration 7000) Mon Jun 22 00:15:28 2020
## 40 percent done (iteration 8000) Mon Jun 22 00:15:34 2020
## 45 percent done (iteration 9000) Mon Jun 22 00:15:40 2020
## 50 percent done (iteration 10000) Mon Jun 22 00:15:47 2020
## 55 percent done (iteration 11000) Mon Jun 22 00:15:53 2020
## 60 percent done (iteration 12000) Mon Jun 22 00:15:59 2020
## 65 percent done (iteration 13000) Mon Jun 22 00:16:05 2020
## 70 percent done (iteration 14000) Mon Jun 22 00:16:11 2020
## 75 percent done (iteration 15000) Mon Jun 22 00:16:17 2020
## 80 percent done (iteration 16000) Mon Jun 22 00:16:23 2020
## 85 percent done (iteration 17000) Mon Jun 22 00:16:30 2020
## 90 percent done (iteration 18000) Mon Jun 22 00:16:36 2020
## 95 percent done (iteration 19000) Mon Jun 22 00:16:42 2020
## 100 percent done (iteration 20000) Mon Jun 22 00:16:48 2020
#Model2:with a covariate for common practice
#same.prac covariate information
same.off.op=v.attr.lazega$Office %o% v.attr.lazega$Office
same.off=matrix(as.numeric(same.off.op %in% c(1,4,9)),36,36)
same.off=array(same.off,dim=c(36,36,1))
lazega.leig.fit3=eigenmodel_mcmc(A,same.off, R=2, S=10000, burn=10000)
## 5 percent done (iteration 1000) Mon Jun 22 00:16:54 2020
## 10 percent done (iteration 2000) Mon Jun 22 00:17:00 2020
## 15 percent done (iteration 3000) Mon Jun 22 00:17:06 2020
## 20 percent done (iteration 4000) Mon Jun 22 00:17:12 2020
## 25 percent done (iteration 5000) Mon Jun 22 00:17:18 2020
## 30 percent done (iteration 6000) Mon Jun 22 00:17:25 2020
## 35 percent done (iteration 7000) Mon Jun 22 00:17:31 2020
## 40 percent done (iteration 8000) Mon Jun 22 00:17:37 2020
## 45 percent done (iteration 9000) Mon Jun 22 00:17:43 2020
## 50 percent done (iteration 10000) Mon Jun 22 00:17:49 2020
## 55 percent done (iteration 11000) Mon Jun 22 00:17:56 2020
## 60 percent done (iteration 12000) Mon Jun 22 00:18:04 2020
## 65 percent done (iteration 13000) Mon Jun 22 00:18:11 2020
## 70 percent done (iteration 14000) Mon Jun 22 00:18:18 2020
## 75 percent done (iteration 15000) Mon Jun 22 00:18:24 2020
## 80 percent done (iteration 16000) Mon Jun 22 00:18:30 2020
## 85 percent done (iteration 17000) Mon Jun 22 00:18:37 2020
## 90 percent done (iteration 18000) Mon Jun 22 00:18:43 2020
## 95 percent done (iteration 19000) Mon Jun 22 00:18:48 2020
## 100 percent done (iteration 20000) Mon Jun 22 00:18:54 2020
#Model 3: with a covariate for shared office location
In order to compare the representation of the network lazega in each of the underlying
two-dimensional latent spaces inferred for these models, we extract the eigenvectors for
each fitted model.
lat.sp.1=eigen(lazega.leig.fit1$ULU_postmean)$vec[,1:2]
lat.sp.2=eigen(lazega.leig.fit2$ULU_postmean)$vec[,1:2]
lat.sp.3=eigen(lazega.leig.fit3$ULU_postmean)$vec[,1:2]
colbar=c("red","dodgerblue","goldenrod")
v.colors=colbar[V(lazega)$Office]
v.shapes=c("circle","square")[V(lazega)$Practice]
v.size=3.5*sqrt(V(lazega)$Years)
v.label=V(lazega)$Seniority
par(mfrow=c(1,3))
plot(lazega,layout=lat.sp.1,vertex.color=v.colors,vertex.shape=v.shapes, vertex.size=v.size,vertex.label=v.label)
plot(lazega,layout=lat.sp.2,vertex.color=v.colors,vertex.shape=v.shapes, vertex.size=v.size,vertex.label=v.label)
plot(lazega,layout=lat.sp.3,vertex.color=v.colors,vertex.shape=v.shapes, vertex.size=v.size,vertex.label=v.label)
#The first 2 visualization appear to be clustered into two groups distinguisher largely common office location(check color)
#The last visualization appear to be only one main cluster
#that means we can explain thie network based on not office location but practice
#If we try to explain the network usin office location, then it is less structured
#Also, we can find how nuch we can explain the network using eigenvalue
apply(lazega.leig.fit1$L_postsamp,2,mean)
## [1] 0.9993555 0.2324392
apply(lazega.leig.fit2$L_postsamp,2,mean)
## [1] 0.9097744 -0.1158853
apply(lazega.leig.fit3$L_postsamp,2,mean)
## [1] -0.1066956 0.3585928
#goodness-of-fit
##To evaluate the goodness-of-fit,you can use ROC curve
perm.index = sample(1:630)
nfolds = 5
nmiss = 630/nfolds
Avec = A[lower.tri(A)]
Avec.pred1 =numeric(length(Avec))
for(i in 1:nfolds){
#index of missing values
miss.index = seq((i-1)*nmiss+1, i*nmiss, 1)
A.miss.index = perm.index[miss.index]
#fill a new atemp appropriately with NA`s
Avec.temp = Avec
Avec.temp[A.miss.index] = rep(NA, length(A.miss.index))
Avec.temp = as.numeric(Avec.temp)
Atemp = matrix(0, 36, 36)
Atemp[lower.tri(Atemp)] = Avec.temp
Atemp = Atemp + t(Atemp)
#Now fit model and predict
Y = Atemp
model.fit1 = eigenmodel_mcmc(Y, R=2, S=10000, burn=10000)
model.pred1 = model.fit1$Y_postmean
model.pred.vec1 = model.pred1[lower.tri(model.pred1)]
Avec.pred1[A.miss.index] = model.pred.vec1[A.miss.index]
}
## 5 percent done (iteration 1000) Mon Jun 22 00:19:01 2020
## 10 percent done (iteration 2000) Mon Jun 22 00:19:07 2020
## 15 percent done (iteration 3000) Mon Jun 22 00:19:13 2020
## 20 percent done (iteration 4000) Mon Jun 22 00:19:19 2020
## 25 percent done (iteration 5000) Mon Jun 22 00:19:25 2020
## 30 percent done (iteration 6000) Mon Jun 22 00:19:30 2020
## 35 percent done (iteration 7000) Mon Jun 22 00:19:36 2020
## 40 percent done (iteration 8000) Mon Jun 22 00:19:42 2020
## 45 percent done (iteration 9000) Mon Jun 22 00:19:48 2020
## 50 percent done (iteration 10000) Mon Jun 22 00:19:54 2020
## 55 percent done (iteration 11000) Mon Jun 22 00:19:59 2020
## 60 percent done (iteration 12000) Mon Jun 22 00:20:05 2020
## 65 percent done (iteration 13000) Mon Jun 22 00:20:11 2020
## 70 percent done (iteration 14000) Mon Jun 22 00:20:17 2020
## 75 percent done (iteration 15000) Mon Jun 22 00:20:23 2020
## 80 percent done (iteration 16000) Mon Jun 22 00:20:28 2020
## 85 percent done (iteration 17000) Mon Jun 22 00:20:34 2020
## 90 percent done (iteration 18000) Mon Jun 22 00:20:40 2020
## 95 percent done (iteration 19000) Mon Jun 22 00:20:46 2020
## 100 percent done (iteration 20000) Mon Jun 22 00:20:52 2020
## 5 percent done (iteration 1000) Mon Jun 22 00:20:58 2020
## 10 percent done (iteration 2000) Mon Jun 22 00:21:04 2020
## 15 percent done (iteration 3000) Mon Jun 22 00:21:09 2020
## 20 percent done (iteration 4000) Mon Jun 22 00:21:15 2020
## 25 percent done (iteration 5000) Mon Jun 22 00:21:21 2020
## 30 percent done (iteration 6000) Mon Jun 22 00:21:27 2020
## 35 percent done (iteration 7000) Mon Jun 22 00:21:33 2020
## 40 percent done (iteration 8000) Mon Jun 22 00:21:38 2020
## 45 percent done (iteration 9000) Mon Jun 22 00:21:44 2020
## 50 percent done (iteration 10000) Mon Jun 22 00:21:50 2020
## 55 percent done (iteration 11000) Mon Jun 22 00:21:56 2020
## 60 percent done (iteration 12000) Mon Jun 22 00:22:02 2020
## 65 percent done (iteration 13000) Mon Jun 22 00:22:08 2020
## 70 percent done (iteration 14000) Mon Jun 22 00:22:14 2020
## 75 percent done (iteration 15000) Mon Jun 22 00:22:20 2020
## 80 percent done (iteration 16000) Mon Jun 22 00:22:25 2020
## 85 percent done (iteration 17000) Mon Jun 22 00:22:31 2020
## 90 percent done (iteration 18000) Mon Jun 22 00:22:37 2020
## 95 percent done (iteration 19000) Mon Jun 22 00:22:43 2020
## 100 percent done (iteration 20000) Mon Jun 22 00:22:49 2020
## 5 percent done (iteration 1000) Mon Jun 22 00:22:55 2020
## 10 percent done (iteration 2000) Mon Jun 22 00:23:00 2020
## 15 percent done (iteration 3000) Mon Jun 22 00:23:06 2020
## 20 percent done (iteration 4000) Mon Jun 22 00:23:12 2020
## 25 percent done (iteration 5000) Mon Jun 22 00:23:18 2020
## 30 percent done (iteration 6000) Mon Jun 22 00:23:24 2020
## 35 percent done (iteration 7000) Mon Jun 22 00:23:29 2020
## 40 percent done (iteration 8000) Mon Jun 22 00:23:35 2020
## 45 percent done (iteration 9000) Mon Jun 22 00:23:41 2020
## 50 percent done (iteration 10000) Mon Jun 22 00:23:47 2020
## 55 percent done (iteration 11000) Mon Jun 22 00:23:52 2020
## 60 percent done (iteration 12000) Mon Jun 22 00:23:58 2020
## 65 percent done (iteration 13000) Mon Jun 22 00:24:04 2020
## 70 percent done (iteration 14000) Mon Jun 22 00:24:10 2020
## 75 percent done (iteration 15000) Mon Jun 22 00:24:16 2020
## 80 percent done (iteration 16000) Mon Jun 22 00:24:22 2020
## 85 percent done (iteration 17000) Mon Jun 22 00:24:28 2020
## 90 percent done (iteration 18000) Mon Jun 22 00:24:34 2020
## 95 percent done (iteration 19000) Mon Jun 22 00:24:40 2020
## 100 percent done (iteration 20000) Mon Jun 22 00:24:45 2020
## 5 percent done (iteration 1000) Mon Jun 22 00:24:51 2020
## 10 percent done (iteration 2000) Mon Jun 22 00:24:57 2020
## 15 percent done (iteration 3000) Mon Jun 22 00:25:03 2020
## 20 percent done (iteration 4000) Mon Jun 22 00:25:09 2020
## 25 percent done (iteration 5000) Mon Jun 22 00:25:14 2020
## 30 percent done (iteration 6000) Mon Jun 22 00:25:20 2020
## 35 percent done (iteration 7000) Mon Jun 22 00:25:26 2020
## 40 percent done (iteration 8000) Mon Jun 22 00:25:32 2020
## 45 percent done (iteration 9000) Mon Jun 22 00:25:38 2020
## 50 percent done (iteration 10000) Mon Jun 22 00:25:43 2020
## 55 percent done (iteration 11000) Mon Jun 22 00:25:50 2020
## 60 percent done (iteration 12000) Mon Jun 22 00:25:56 2020
## 65 percent done (iteration 13000) Mon Jun 22 00:26:02 2020
## 70 percent done (iteration 14000) Mon Jun 22 00:26:08 2020
## 75 percent done (iteration 15000) Mon Jun 22 00:26:14 2020
## 80 percent done (iteration 16000) Mon Jun 22 00:26:20 2020
## 85 percent done (iteration 17000) Mon Jun 22 00:26:26 2020
## 90 percent done (iteration 18000) Mon Jun 22 00:26:32 2020
## 95 percent done (iteration 19000) Mon Jun 22 00:26:38 2020
## 100 percent done (iteration 20000) Mon Jun 22 00:26:44 2020
## 5 percent done (iteration 1000) Mon Jun 22 00:26:49 2020
## 10 percent done (iteration 2000) Mon Jun 22 00:26:55 2020
## 15 percent done (iteration 3000) Mon Jun 22 00:27:01 2020
## 20 percent done (iteration 4000) Mon Jun 22 00:27:07 2020
## 25 percent done (iteration 5000) Mon Jun 22 00:27:13 2020
## 30 percent done (iteration 6000) Mon Jun 22 00:27:18 2020
## 35 percent done (iteration 7000) Mon Jun 22 00:27:24 2020
## 40 percent done (iteration 8000) Mon Jun 22 00:27:30 2020
## 45 percent done (iteration 9000) Mon Jun 22 00:27:36 2020
## 50 percent done (iteration 10000) Mon Jun 22 00:27:42 2020
## 55 percent done (iteration 11000) Mon Jun 22 00:27:48 2020
## 60 percent done (iteration 12000) Mon Jun 22 00:27:53 2020
## 65 percent done (iteration 13000) Mon Jun 22 00:27:59 2020
## 70 percent done (iteration 14000) Mon Jun 22 00:28:05 2020
## 75 percent done (iteration 15000) Mon Jun 22 00:28:11 2020
## 80 percent done (iteration 16000) Mon Jun 22 00:28:17 2020
## 85 percent done (iteration 17000) Mon Jun 22 00:28:23 2020
## 90 percent done (iteration 18000) Mon Jun 22 00:28:28 2020
## 95 percent done (iteration 19000) Mon Jun 22 00:28:34 2020
## 100 percent done (iteration 20000) Mon Jun 22 00:28:40 2020
library(ROCR)
pred1 = prediction(Avec.pred1, Avec)
perf1 = performance(pred1, 'tpr', 'fpr')
par(mfrow=c(1,1))
plot(perf1, col='blue', lwd=3)
perf1.auc = performance(pred1, 'auc')
slot(perf1.auc, 'y.values')
## [[1]]
## [1] 0.8045927
data("karate")
karate=upgrade_graph(karate)
V(karate)
## + 34/34 vertices, named, from 4b458a1:
## [1] Mr Hi Actor 2 Actor 3 Actor 4 Actor 5 Actor 6 Actor 7 Actor 8
## [9] Actor 9 Actor 10 Actor 11 Actor 12 Actor 13 Actor 14 Actor 15 Actor 16
## [17] Actor 17 Actor 18 Actor 19 Actor 20 Actor 21 Actor 22 Actor 23 Actor 24
## [25] Actor 25 Actor 26 Actor 27 Actor 28 Actor 29 Actor 30 Actor 31 Actor 32
## [33] Actor 33 John A
A=get.adjacency(karate,sparse=F)
v.attrs=get.data.frame(karate,what="vertices")
v.attrs
## Faction name label color
## Mr Hi 1 Mr Hi H 1
## Actor 2 1 Actor 2 2 1
## Actor 3 1 Actor 3 3 1
## Actor 4 1 Actor 4 4 1
## Actor 5 1 Actor 5 5 1
## Actor 6 1 Actor 6 6 1
## Actor 7 1 Actor 7 7 1
## Actor 8 1 Actor 8 8 1
## Actor 9 2 Actor 9 9 2
## Actor 10 2 Actor 10 10 2
## Actor 11 1 Actor 11 11 1
## Actor 12 1 Actor 12 12 1
## Actor 13 1 Actor 13 13 1
## Actor 14 1 Actor 14 14 1
## Actor 15 2 Actor 15 15 2
## Actor 16 2 Actor 16 16 2
## Actor 17 1 Actor 17 17 1
## Actor 18 1 Actor 18 18 1
## Actor 19 2 Actor 19 19 2
## Actor 20 1 Actor 20 20 1
## Actor 21 2 Actor 21 21 2
## Actor 22 1 Actor 22 22 1
## Actor 23 2 Actor 23 23 2
## Actor 24 2 Actor 24 24 2
## Actor 25 2 Actor 25 25 2
## Actor 26 2 Actor 26 26 2
## Actor 27 2 Actor 27 27 2
## Actor 28 2 Actor 28 28 2
## Actor 29 2 Actor 29 29 2
## Actor 30 2 Actor 30 30 2
## Actor 31 2 Actor 31 31 2
## Actor 32 2 Actor 32 32 2
## Actor 33 2 Actor 33 33 2
## John A 2 John A A 2
karate.s=network::as.network(as.matrix(A),directed=F)
network::set.vertex.attribute(karate.s,'Faction',v.attrs$Faction)
network::set.vertex.attribute(karate.s,'color',v.attrs$color)
karate.s %v% 'Faction'
## [1] 1 1 1 1 1 1 1 1 2 2 1 1 1 1 2 2 1 1 2 1 2 1 2 2 2 2 2 2 2 2 2 2 2 2
we can see faction value is 1 or 2
karate.fit = ergmm(karate.s ~ euclidean(d=2, G=2), verbose=T)
## Generating initial values for MCMC:
## Computing geodesic distances... Finished.
## Computing MDS locations... Finished.
## Computing other initial values... Finished.
## Finding the conditional posterior mode... Finished.
## Burning in... Finished.
## Starting sampling run... Finished.
## Post-processing the MCMC output:
## Performing label-switching... Finished.
## Fitting the MKL locations... Finished.
## Fitting MBC conditional on MKL locations... Finished.
## Performing Procrustes transformation... Finished.
We fit karate network data using latent space model with 2-dim Euclidean space
because of number of faction, we add a group structure in latent position of vertices
karate.fit$mcmc.pmode$Z
## [,1] [,2]
## [1,] -1.0447232 0.72976993
## [2,] -0.5926773 1.31309443
## [3,] 0.7113302 1.66272851
## [4,] -0.5845566 0.71264067
## [5,] -1.4676213 0.14515291
## [6,] -0.7403098 -0.60881497
## [7,] -0.9822659 0.03743523
## [8,] -0.8332010 1.16203878
## [9,] 0.8154492 2.57840617
## [10,] 1.8417689 3.94521898
## [11,] -1.4504418 0.38880470
## [12,] -1.4309960 2.00660736
## [13,] -1.4692962 0.81176987
## [14,] -0.3149204 1.04292082
## [15,] 3.0879321 2.78874198
## [16,] 0.5145647 3.93651398
## [17,] -1.9486429 -0.40507666
## [18,] -1.8232886 1.55630065
## [19,] 2.0417128 2.18538884
## [20,] -1.2740561 1.71916484
## [21,] 1.3883340 3.29265917
## [22,] -2.2262300 0.20006291
## [23,] 0.1013299 2.69877504
## [24,] 2.2163109 4.23968080
## [25,] 3.3135998 2.61418833
## [26,] 3.3425219 2.40474163
## [27,] 1.8925817 2.87415218
## [28,] 3.3120627 2.92660763
## [29,] 0.9392122 2.63704475
## [30,] 2.6786600 4.11057074
## [31,] 0.9334938 2.89583995
## [32,] 2.4302593 2.80379074
## [33,] 1.6459879 2.97538751
## [34,] 1.6766565 2.91086033
oneL=karate.s %v% 'Faction'
oneL[oneL==1]='H'
oneL[oneL==2]='J'
oneL[[1]] = "Hi"
oneL[[34]] = "John"
oneL
## [1] "Hi" "H" "H" "H" "H" "H" "H" "H" "J" "J"
## [11] "H" "H" "H" "H" "J" "J" "H" "H" "J" "H"
## [21] "J" "H" "J" "J" "J" "J" "J" "J" "J" "J"
## [31] "J" "J" "J" "John"
oneLcolors = c("red", "blue", "yellow", "white")[match(oneL, c("H","J","Hi","John"))]
plot(karate.fit, label=oneL, vertex.col=oneLcolors, what="pmean",
main="MCMC position", print.formula = FALSE, labels=TRUE)
due to the invariance property of the latent space, positions can be rotated
however, if you rotate your latent space plot, you will have same plot
that is just the difference in representation.
we only consider the only include intercept + distance term (no covariates)
1.Hi and John located in each group center
2.we can check that each 2 groups are divided well in the plot
3.we can see that groups are formed according to faction
summary(karate)
## IGRAPH 4b458a1 UNW- 34 78 -- Zachary's karate club network
## + attr: name (g/c), Citation (g/c), Author (g/c), Faction (v/n), name
## | (v/c), label (v/c), color (v/n), weight (e/n)
library(eigenmodel)
karate.fit1=eigenmodel_mcmc(A,R=2,S=10000,burn=10000)
## 5 percent done (iteration 1000) Mon Jun 22 00:29:05 2020
## 10 percent done (iteration 2000) Mon Jun 22 00:29:11 2020
## 15 percent done (iteration 3000) Mon Jun 22 00:29:16 2020
## 20 percent done (iteration 4000) Mon Jun 22 00:29:21 2020
## 25 percent done (iteration 5000) Mon Jun 22 00:29:27 2020
## 30 percent done (iteration 6000) Mon Jun 22 00:29:32 2020
## 35 percent done (iteration 7000) Mon Jun 22 00:29:38 2020
## 40 percent done (iteration 8000) Mon Jun 22 00:29:44 2020
## 45 percent done (iteration 9000) Mon Jun 22 00:29:49 2020
## 50 percent done (iteration 10000) Mon Jun 22 00:29:55 2020
## 55 percent done (iteration 11000) Mon Jun 22 00:30:00 2020
## 60 percent done (iteration 12000) Mon Jun 22 00:30:06 2020
## 65 percent done (iteration 13000) Mon Jun 22 00:30:11 2020
## 70 percent done (iteration 14000) Mon Jun 22 00:30:17 2020
## 75 percent done (iteration 15000) Mon Jun 22 00:30:22 2020
## 80 percent done (iteration 16000) Mon Jun 22 00:30:28 2020
## 85 percent done (iteration 17000) Mon Jun 22 00:30:33 2020
## 90 percent done (iteration 18000) Mon Jun 22 00:30:39 2020
## 95 percent done (iteration 19000) Mon Jun 22 00:30:45 2020
## 100 percent done (iteration 20000) Mon Jun 22 00:30:50 2020
basic setting is same as problem2
Using eigen decomposition model, fit karate netwrok (intercept+Z)
lat.sp = eigen(karate.fit1$ULU_postmean)$vec[,1:2]
plot(karate, layout=lat.sp, vertex.color=oneLcolors)
1.we can check that each 2 groups are divided well in the plot
2.we can see that groups are formed according to faction
3.Unlike problem2, Hi and John located in each the corner
apply(karate.fit1$L_postsamp, 2, mean)
## [1] -0.7608995 1.2522484
there is one eigenvalue that clearly dominates the other, corresponding to the axis on which we obtain a clear separation between the two groups.#in textbook
Unlike in PCA, the eigenvalues are not of decreasing order since they were estimated using MCMC
We see that the second eigenvalue dominates the solution. Thus, the second latent variable is relatively more important than the first one # Modern Psychometrics with R