Assignment_7

Community Detection (Marriages between characters in the Game of Thrones Novels)

Walid Medani https://walidmedani.github.io/networks-blog/
2022-03-24

Game of Thrones Marriages

plot.igraph(gotmarr.ig, 
            vertex.label.cex=1)

Network Size

vcount(gotmarr.ig)
[1] 18
ecount(gotmarr.ig)
[1] 61

Attributes

is_bipartite(gotmarr.ig)
[1] FALSE
is_directed(gotmarr.ig)
[1] FALSE
is_weighted(gotmarr.ig)
[1] TRUE
vertex_attr_names(gotmarr.ig)
[1] "color"        "na"           "region"       "vertex.names"
[5] "name"        
edge_attr_names(gotmarr.ig)
[1] "na"     "weight"

Community Detection

Fast and greedy

#Run clustering algorithm: fast_greedy
got.fg<-cluster_fast_greedy(gotmarr.ig)
#Retrieve list of nodes in communities
igraph::groups(got.fg)
$`1`
[1] "Arryn" "Tully" "Vale" 

$`2`
[1] "Martell"    "Crownlands" "Essos"      "Targaryen"  "Dorne"     

$`3`
[1] "Baratheon" "Reach"     "Tyrell"   

$`4`
[1] "Stormlands" "Riverlands" "Frey"      

$`5`
[1] "Lannister"   "Westerlands"

$`6`
[1] "Stark" "North"
plot(got.fg,gotmarr.ig)

Walktrap

nodes.by.gp<-function(network.nodes, groupvar){
  network.nodes%>%
  select(-name)%>%
  group_by_(groupvar) %>%
  mutate(n=n())%>%
  summarise_all(mean, na.rm=TRUE)%>%
  as.matrix()%>%
  print(digits=2)
}


got.wt<-walktrap.community(gotmarr.ig)
igraph::groups(got.wt)
$`1`
[1] "Arryn"      "Tully"      "Vale"       "Stormlands" "Riverlands"
[6] "Frey"      

$`2`
[1] "Martell"    "Crownlands" "Essos"      "Targaryen"  "Dorne"     

$`3`
[1] "Baratheon" "Reach"     "Tyrell"   

$`4`
[1] "Stark" "North"

$`5`
[1] "Lannister"   "Westerlands"
gotmarr.nodes$comm.wt<-got.wt$membership
nodes.by.gp(gotmarr.nodes,"comm.wt")
     comm.wt degree degree.wt bonpow betweenness close constraint n
[1,]       1    5.5        23  -1.31         4.5  0.58       0.41 6
[2,]       2    5.2        22  -0.79         9.3  0.57       0.62 5
[3,]       3    6.0        22  -0.96         8.9  0.59       0.45 3
[4,]       4    6.0        36  -0.29         6.9  0.59       0.53 2
[5,]       5    5.5        25  -0.15         1.4  0.58       0.57 2
plot(got.wt,gotmarr.ig)

Label Propagation

got.lab<-walktrap.community(gotmarr.ig)
igraph::groups(got.lab)
$`1`
[1] "Arryn"      "Tully"      "Vale"       "Stormlands" "Riverlands"
[6] "Frey"      

$`2`
[1] "Martell"    "Crownlands" "Essos"      "Targaryen"  "Dorne"     

$`3`
[1] "Baratheon" "Reach"     "Tyrell"   

$`4`
[1] "Stark" "North"

$`5`
[1] "Lannister"   "Westerlands"
gotmarr.nodes$comm.lab<-got.lab$membership
nodes.by.gp(gotmarr.nodes,"comm.lab")
     comm.lab degree degree.wt bonpow betweenness close constraint
[1,]        1    5.5        23  -1.31         4.5  0.58       0.41
[2,]        2    5.2        22  -0.79         9.3  0.57       0.62
[3,]        3    6.0        22  -0.96         8.9  0.59       0.45
[4,]        4    6.0        36  -0.29         6.9  0.59       0.53
[5,]        5    5.5        25  -0.15         1.4  0.58       0.57
     comm.wt n
[1,]       1 6
[2,]       2 5
[3,]       3 3
[4,]       4 2
[5,]       5 2
plot(got.lab,gotmarr.ig)

Edge betweeness

got.edge<-edge.betweenness.community(gotmarr.ig)
igraph::groups(got.edge)
$`1`
[1] "Arryn"

$`2`
[1] "Tully"

$`3`
[1] "Vale"

$`4`
[1] "Baratheon"

$`5`
[1] "Lannister"

$`6`
[1] "Martell"

$`7`
[1] "Reach"

$`8`
[1] "Stark"

$`9`
[1] "Stormlands"

$`10`
[1] "Tyrell"

$`11`
[1] "Crownlands"

$`12`
[1] "Essos"

$`13`
[1] "Riverlands"

$`14`
[1] "Westerlands"

$`15`
[1] "Frey"

$`16`
[1] "North"

$`17`
[1] "Targaryen"

$`18`
[1] "Dorne"
gotmarr.nodes$comm.edge<-got.edge$membership
nodes.by.gp(gotmarr.nodes,"comm.edge")
      comm.edge degree degree.wt bonpow betweenness close constraint
 [1,]         1      3        10 -1.113        0.67  0.50       0.51
 [2,]         2      5         5 -1.042        2.31  0.53       0.48
 [3,]         3      5        34 -1.085        2.51  0.57       0.36
 [4,]         4      7        10 -0.757       10.86  0.63       0.38
 [5,]         5      5        22 -0.086        0.89  0.55       0.65
 [6,]         6      3         8 -0.699        0.75  0.52       0.74
 [7,]         7      9        46 -1.442       15.76  0.68       0.32
 [8,]         8      9        33  0.057       13.56  0.68       0.40
 [9,]         9      4        10 -1.941        0.62  0.57       0.41
[10,]        10      2        11 -0.685        0.00  0.45       0.66
[11,]        11      6        17 -0.514        1.80  0.59       0.50
[12,]        12      4        10 -0.956        2.15  0.55       0.70
[13,]        13      6        32 -1.171        2.85  0.61       0.46
[14,]        14      6        28 -0.214        1.97  0.61       0.49
[15,]        15     10        48 -1.513       17.98  0.68       0.24
[16,]        16      3        39 -0.628        0.31  0.50       0.65
[17,]        17     12        73 -1.256       42.02  0.77       0.18
[18,]        18      1         2 -0.500        0.00  0.45       1.00
      comm.wt comm.lab n
 [1,]       1        1 1
 [2,]       1        1 1
 [3,]       1        1 1
 [4,]       3        3 1
 [5,]       5        5 1
 [6,]       2        2 1
 [7,]       3        3 1
 [8,]       4        4 1
 [9,]       1        1 1
[10,]       3        3 1
[11,]       2        2 1
[12,]       2        2 1
[13,]       1        1 1
[14,]       5        5 1
[15,]       1        1 1
[16,]       4        4 1
[17,]       2        2 1
[18,]       2        2 1
plot(got.edge,gotmarr.ig)

Eigenvector

got.eigen<-leading.eigenvector.community(gotmarr.ig)
igraph::groups(got.eigen)
$`1`
[1] "Arryn"      "Baratheon"  "Martell"    "Stormlands" "Crownlands"
[6] "Essos"      "Targaryen"  "Dorne"     

$`2`
[1] "Tully"      "Vale"       "Riverlands" "Frey"      

$`3`
[1] "Reach"

$`4`
[1] "Stark" "North"

$`5`
[1] "Lannister"   "Westerlands"

$`6`
[1] "Tyrell"
gotmarr.nodes$comm.eigen<-got.eigen$membership
nodes.by.gp(gotmarr.nodes,"comm.eigen")
     comm.eigen degree degree.wt bonpow betweenness close constraint
[1,]          1    5.0        18  -0.97         7.4  0.57       0.55
[2,]          2    6.5        30  -1.20         6.4  0.60       0.38
[3,]          3    9.0        46  -1.44        15.8  0.68       0.32
[4,]          4    6.0        36  -0.29         6.9  0.59       0.53
[5,]          5    5.5        25  -0.15         1.4  0.58       0.57
[6,]          6    2.0        11  -0.69         0.0  0.45       0.66
     comm.wt comm.lab comm.edge n
[1,]     1.9      1.9       9.8 8
[2,]     1.0      1.0       8.2 4
[3,]     3.0      3.0       7.0 1
[4,]     4.0      4.0      12.0 2
[5,]     5.0      5.0       9.5 2
[6,]     3.0      3.0      10.0 1
plot(got.eigen,gotmarr.ig)

Modularity Scores

fastgreedy   walktrap      label       edge      eigen 
 0.5173683  0.3289444  0.3289444  0.2051354  0.4572361 

Observations

For the GOT marriages data set, the fast/greedy, walktrap, and label propagation made the most sense in identifying communities. Fast and greedy was the most successful method due to it partitioning “Baratheon”, “Reach”, and “Tyrell” as a separate community from the northern kingdoms of “Tully” and “Arryn” where there was a weak or no relationship between the factions.

Edge betweeness failed to identify any communities within the dataset, whereas the Eigenvector failed to cluster some memberships such as the Reach being distinct from the Tyrell family (rulers of the region) and has strong marriage connections with the Baratheons.