1. Compute the smallest 12 eigenvalues and corresponding eigenvectors of the Laplacian of the friendship graph.
#computing adjacency matrix 
people <- sort(unique(c(data$from,data$to)))

from_factor <- factor(data$from, levels=people)
to_factor <- factor(data$to, levels=people)

A <- unclass(table(from_factor, to_factor))
A <- unclass(pmax(A, t(A)))

#computing degree matrix
degrees <- rowSums(A)
D <- diag(degrees)

#computing laplacian
L = D-unclass(A)
values <- eigen(L, symmetric=TRUE)

#12 smallest eigenvalues of laplacian 
n <- 1495
smallest_12_values <- values$values[(n-11):n]
smallest_12_vectors <- values$vectors[,(n-11):n]
round(smallest_12_values, digits=3)
 [1] 0.133 0.120 0.081 0.074 0.054 0.014 0.000 0.000 0.000 0.000 0.000 0.000
  1. How many connected components does this graph have, and what are the sizes of the connected components?
v1 <- smallest_12_vectors[,7] 
v2 <- smallest_12_vectors[,8]
v3 <- smallest_12_vectors[,9]
v4 <- smallest_12_vectors[,10]
v5 <- smallest_12_vectors[,11] 
v6 <- smallest_12_vectors[,12]  

ccs <- list(v1,v2,v3,v4,v5,v6)
lengths <- list()
i<-1
for (v in ccs) {
  lengths[i] <- length(v[abs(v)>(1e-12)])
  i = i+1
}
lengths
[[1]]
[1] 1495

[[2]]
[1] 1495

[[3]]
[1] 1495

[[4]]
[1] 1495

[[5]]
[1] 1495

[[6]]
[1] 1495
cc_matrix <- matrix(ncol=6, data = c(v1,v2,v3,v3,v5,v6))
dim(cc_matrix)
[1] 1495    6
set.seed(123)
km <- kmeans(cc_matrix, centers=6)
plot(cc_matrix, col=km$cluster, pch=19)

table(km$cluster)

  1   2   3   4   5   6 
  7 312   4 368  44 760 

Given that there are 6 zero-valued eigenvalues, it’s evident that there are 6 connected components. To find the size of the connected components, we can use the 6 corresponding eigenvectors as columns of a matrix, and perform k-means on this matrix. This will help identify the clusters within the data and thereby determine the size of each cluster. Applying the k-means algorithm gave the following results:

Component 1 Component 2 Component 3 Component 4 Component 5 Component 6
7 312 4 368 44 760

\[ cond(S) = \frac{\sum_{i\in S, i\in V\backslash S} A_{ij}}{\min(A(S),A(V\backslash S)} \]

Each of the three sets below were found using the 7th, 30th, and 10th smallest eigenvectors respectively. After plotting, I identified the prominent bands that were not part of the main cluster and extracted those vertices.

cond <- function(s) {
  A_S <- sum(diag(D)[which(people %in% s)]) 
  V_minus_S <- sum(diag(D)[which(!(people %in% s))])
  s_i <- which(people %in% s)
  sum_Aij <- sum(A[s_i, -s_i])
  
  c <- sum_Aij / ifelse(A_S < V_minus_S, A_S, V_minus_S)
  return(c)
}
create_list <- function(l, m, c) {
  new_list <- list(length = l, members = m, conductance = c)
  return(new_list)
}

Set 1

This set corresponds to the vertices whose values in the 7th smallest eigenvector are in the range [-0.045, -0.04].

l <- 12
v7 <- smallest_12_vectors[,l-6] #first eigenvector with a non-zero e-value
plot(v7, type="p", pch=19, cex=0.5, main="7th Smallest Eigenvector", xlab="Node index", ylab="Eigenvector value")

s1 <- which(v7 < -0.04 & v7 > -0.045)
s1_length <- length(which(v7 < -0.04 & v7 > -0.045))
s1_members <- s1[1:10]
cond_s1 <- cond(s1)

create_list(s1_length, s1_members, cond_s1)
$length
[1] 199

$members
 [1]  2  6  8 13 17 21 55 60 67 71

$conductance
[1] 0.02901731

Set 2

This set corresponds to the vertices whose values in the 30th smallest eigenvector are in the range [-0.04, -0.01].

all_vectors <- values$vectors
v30 <- all_vectors[,n-29]
plot(v30, type="p", pch=19, cex=0.5, main="30th Smallest Eigenvector", xlab="Node index", ylab="Eigenvector value")

s2 <- which(v30 > -.04 & v30 < -.01)

s2_length <- length(s2)
s2_members <- s2[1:10]
cond_s2 <- cond(s2)

create_list(s2_length, s2_members, cond_s2)
$length
[1] 427

$members
 [1]  5  7 12 15 23 27 30 34 42 44

$conductance
[1] 0.02111757

Set 3

This set corresponds to the vertices whose values in the 10th smallest eigenvector are in the range [0.02, 0.03].

v10 <- all_vectors[,n-9]
plot(v10, type="p", pch=19, cex=0.5, main="10th Smallest Eigenvector", xlab="Node index", ylab="Eigenvector value")

s3 <- which(v10>0.02 & v10<0.03)

s3_length <- length(s3)
s3_members <- s3[1:10]
cond_s3 <- cond(s3)

create_list(s3_length, s3_members, cond_s3)
$length
[1] 209

$members
 [1]  2  6  8 13 17 21 55 60 67 71

$conductance
[1] 0.01179245
  1. Select a random set of 150 nodes, and compute the conductance of that set.
set.seed(123)
random_set <- sample(1:1495, 150)

cond(random_set)
[1] 0.9014746

The conductances found in sets 1,2,3 in conjunction with the plots indicate tight-knit friendships within the group and a disconnect from the rest of the graph. Comparing with the above benchmark of 0.9 confirms tight-knitness within groups given that a conductance of 0.9 indicates that vertices in our randomly sampled set share minimal internal friendships.

LS0tDQp0aXRsZTogIkZpbmRpbmcgVGlnaHQtS25pdCBHcm91cHMgb2YgRnJpZW5kcyINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQoNCmRhdGEgPC0gcmVhZF9jc3YoIkM6L1VzZXJzL2FubmFrL0Rlc2t0b3AvbWF0aDMwOC9odzQvY3MxNjhtcDYuY3N2IiwgY29sX25hbWVzID0gYygiZnJvbSIsICJ0byIpKQ0KYGBgDQoNCjIpICBDb21wdXRlIHRoZSBzbWFsbGVzdCAxMiBlaWdlbnZhbHVlcyBhbmQgY29ycmVzcG9uZGluZyBlaWdlbnZlY3RvcnMgb2YgdGhlIExhcGxhY2lhbiBvZiB0aGUgZnJpZW5kc2hpcCBncmFwaC4NCg0KYGBge3J9DQojY29tcHV0aW5nIGFkamFjZW5jeSBtYXRyaXggDQpwZW9wbGUgPC0gc29ydCh1bmlxdWUoYyhkYXRhJGZyb20sZGF0YSR0bykpKQ0KDQpmcm9tX2ZhY3RvciA8LSBmYWN0b3IoZGF0YSRmcm9tLCBsZXZlbHM9cGVvcGxlKQ0KdG9fZmFjdG9yIDwtIGZhY3RvcihkYXRhJHRvLCBsZXZlbHM9cGVvcGxlKQ0KDQpBIDwtIHVuY2xhc3ModGFibGUoZnJvbV9mYWN0b3IsIHRvX2ZhY3RvcikpDQpBIDwtIHVuY2xhc3MocG1heChBLCB0KEEpKSkNCg0KI2NvbXB1dGluZyBkZWdyZWUgbWF0cml4DQpkZWdyZWVzIDwtIHJvd1N1bXMoQSkNCkQgPC0gZGlhZyhkZWdyZWVzKQ0KDQojY29tcHV0aW5nIGxhcGxhY2lhbg0KTCA9IEQtdW5jbGFzcyhBKQ0KdmFsdWVzIDwtIGVpZ2VuKEwsIHN5bW1ldHJpYz1UUlVFKQ0KDQojMTIgc21hbGxlc3QgZWlnZW52YWx1ZXMgb2YgbGFwbGFjaWFuIA0KYGBgDQoNCmBgYHtyfQ0KbiA8LSAxNDk1DQpzbWFsbGVzdF8xMl92YWx1ZXMgPC0gdmFsdWVzJHZhbHVlc1sobi0xMSk6bl0NCnNtYWxsZXN0XzEyX3ZlY3RvcnMgPC0gdmFsdWVzJHZlY3RvcnNbLChuLTExKTpuXQ0Kcm91bmQoc21hbGxlc3RfMTJfdmFsdWVzLCBkaWdpdHM9MykNCmBgYA0KDQozKSAgSG93IG1hbnkgY29ubmVjdGVkIGNvbXBvbmVudHMgZG9lcyB0aGlzIGdyYXBoIGhhdmUsIGFuZCB3aGF0IGFyZSB0aGUgc2l6ZXMgb2YgdGhlIGNvbm5lY3RlZCBjb21wb25lbnRzPw0KDQpgYGB7cn0NCnYxIDwtIHNtYWxsZXN0XzEyX3ZlY3RvcnNbLDddIA0KdjIgPC0gc21hbGxlc3RfMTJfdmVjdG9yc1ssOF0NCnYzIDwtIHNtYWxsZXN0XzEyX3ZlY3RvcnNbLDldDQp2NCA8LSBzbWFsbGVzdF8xMl92ZWN0b3JzWywxMF0NCnY1IDwtIHNtYWxsZXN0XzEyX3ZlY3RvcnNbLDExXSANCnY2IDwtIHNtYWxsZXN0XzEyX3ZlY3RvcnNbLDEyXSAgDQoNCmNjcyA8LSBsaXN0KHYxLHYyLHYzLHY0LHY1LHY2KQ0KbGVuZ3RocyA8LSBsaXN0KCkNCmk8LTENCmZvciAodiBpbiBjY3MpIHsNCiAgbGVuZ3Roc1tpXSA8LSBsZW5ndGgodlthYnModik+KDFlLTEyKV0pDQogIGkgPSBpKzENCn0NCmxlbmd0aHMNCmBgYA0KDQpgYGB7cn0NCmNjX21hdHJpeCA8LSBtYXRyaXgobmNvbD02LCBkYXRhID0gYyh2MSx2Mix2Myx2Myx2NSx2NikpDQpkaW0oY2NfbWF0cml4KQ0KYGBgDQoNCmBgYHtyfQ0Kc2V0LnNlZWQoMTIzKQ0Ka20gPC0ga21lYW5zKGNjX21hdHJpeCwgY2VudGVycz02KQ0KcGxvdChjY19tYXRyaXgsIGNvbD1rbSRjbHVzdGVyLCBwY2g9MTkpDQpgYGANCg0KYGBge3J9DQp0YWJsZShrbSRjbHVzdGVyKQ0KYGBgDQoNCkdpdmVuIHRoYXQgdGhlcmUgYXJlIDYgemVyby12YWx1ZWQgZWlnZW52YWx1ZXMsIGl0J3MgZXZpZGVudCB0aGF0IHRoZXJlIGFyZSA2IGNvbm5lY3RlZCBjb21wb25lbnRzLiBUbyBmaW5kIHRoZSBzaXplIG9mIHRoZSBjb25uZWN0ZWQgY29tcG9uZW50cywgd2UgY2FuIHVzZSB0aGUgNiBjb3JyZXNwb25kaW5nIGVpZ2VudmVjdG9ycyBhcyBjb2x1bW5zIG9mIGEgbWF0cml4LCBhbmQgcGVyZm9ybSBrLW1lYW5zIG9uIHRoaXMgbWF0cml4LiBUaGlzIHdpbGwgaGVscCBpZGVudGlmeSB0aGUgY2x1c3RlcnMgd2l0aGluIHRoZSBkYXRhIGFuZCB0aGVyZWJ5IGRldGVybWluZSB0aGUgc2l6ZSBvZiBlYWNoIGNsdXN0ZXIuIEFwcGx5aW5nIHRoZSBrLW1lYW5zIGFsZ29yaXRobSBnYXZlIHRoZSBmb2xsb3dpbmcgcmVzdWx0czoNCg0KfCBDb21wb25lbnQgMSB8IENvbXBvbmVudCAyIHwgQ29tcG9uZW50IDMgfCBDb21wb25lbnQgNCB8IENvbXBvbmVudCA1IHwgQ29tcG9uZW50IDYgfA0KfC0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tfA0KfCA3ICAgICAgICAgICB8IDMxMiAgICAgICAgIHwgNCAgICAgICAgICAgfCAzNjggICAgICAgICB8IDQ0ICAgICAgICAgIHwgNzYwICAgICAgICAgfA0KDQo0KQ0KDQokJA0KY29uZChTKSA9IFxmcmFje1xzdW1fe2lcaW4gUywgaVxpbiBWXGJhY2tzbGFzaCBTfSBBX3tpan19e1xtaW4oQShTKSxBKFZcYmFja3NsYXNoIFMpfQ0KJCQNCg0KRWFjaCBvZiB0aGUgdGhyZWUgc2V0cyBiZWxvdyB3ZXJlIGZvdW5kIHVzaW5nIHRoZSA3dGgsIDMwdGgsIGFuZCAxMHRoIHNtYWxsZXN0IGVpZ2VudmVjdG9ycyByZXNwZWN0aXZlbHkuIEFmdGVyIHBsb3R0aW5nLCBJIGlkZW50aWZpZWQgdGhlIHByb21pbmVudCBiYW5kcyB0aGF0IHdlcmUgbm90IHBhcnQgb2YgdGhlIG1haW4gY2x1c3RlciBhbmQgZXh0cmFjdGVkIHRob3NlIHZlcnRpY2VzLg0KDQpgYGB7cn0NCmNvbmQgPC0gZnVuY3Rpb24ocykgew0KICBBX1MgPC0gc3VtKGRpYWcoRClbd2hpY2gocGVvcGxlICVpbiUgcyldKSANCiAgVl9taW51c19TIDwtIHN1bShkaWFnKEQpW3doaWNoKCEocGVvcGxlICVpbiUgcykpXSkNCiAgc19pIDwtIHdoaWNoKHBlb3BsZSAlaW4lIHMpDQogIHN1bV9BaWogPC0gc3VtKEFbc19pLCAtc19pXSkNCiAgDQogIGMgPC0gc3VtX0FpaiAvIGlmZWxzZShBX1MgPCBWX21pbnVzX1MsIEFfUywgVl9taW51c19TKQ0KICByZXR1cm4oYykNCn0NCmBgYA0KDQpgYGB7cn0NCmNyZWF0ZV9saXN0IDwtIGZ1bmN0aW9uKGwsIG0sIGMpIHsNCiAgbmV3X2xpc3QgPC0gbGlzdChsZW5ndGggPSBsLCBtZW1iZXJzID0gbSwgY29uZHVjdGFuY2UgPSBjKQ0KICByZXR1cm4obmV3X2xpc3QpDQp9DQpgYGANCg0KIyMgU2V0IDENCg0KVGhpcyBzZXQgY29ycmVzcG9uZHMgdG8gdGhlIHZlcnRpY2VzIHdob3NlIHZhbHVlcyBpbiB0aGUgN3RoIHNtYWxsZXN0IGVpZ2VudmVjdG9yIGFyZSBpbiB0aGUgcmFuZ2UgWy0wLjA0NSwgLTAuMDRdLg0KDQpgYGB7cn0NCmwgPC0gMTINCnY3IDwtIHNtYWxsZXN0XzEyX3ZlY3RvcnNbLGwtNl0gI2ZpcnN0IGVpZ2VudmVjdG9yIHdpdGggYSBub24temVybyBlLXZhbHVlDQpwbG90KHY3LCB0eXBlPSJwIiwgcGNoPTE5LCBjZXg9MC41LCBtYWluPSI3dGggU21hbGxlc3QgRWlnZW52ZWN0b3IiLCB4bGFiPSJOb2RlIGluZGV4IiwgeWxhYj0iRWlnZW52ZWN0b3IgdmFsdWUiKQ0KYGBgDQoNCmBgYHtyfQ0KczEgPC0gd2hpY2godjcgPCAtMC4wNCAmIHY3ID4gLTAuMDQ1KQ0KczFfbGVuZ3RoIDwtIGxlbmd0aCh3aGljaCh2NyA8IC0wLjA0ICYgdjcgPiAtMC4wNDUpKQ0KczFfbWVtYmVycyA8LSBzMVsxOjEwXQ0KY29uZF9zMSA8LSBjb25kKHMxKQ0KDQpjcmVhdGVfbGlzdChzMV9sZW5ndGgsIHMxX21lbWJlcnMsIGNvbmRfczEpDQpgYGANCg0KIyMgU2V0IDINCg0KVGhpcyBzZXQgY29ycmVzcG9uZHMgdG8gdGhlIHZlcnRpY2VzIHdob3NlIHZhbHVlcyBpbiB0aGUgMzB0aCBzbWFsbGVzdCBlaWdlbnZlY3RvciBhcmUgaW4gdGhlIHJhbmdlIFstMC4wNCwgLTAuMDFdLg0KDQpgYGB7cn0NCmFsbF92ZWN0b3JzIDwtIHZhbHVlcyR2ZWN0b3JzDQp2MzAgPC0gYWxsX3ZlY3RvcnNbLG4tMjldDQpgYGANCg0KYGBge3J9DQpwbG90KHYzMCwgdHlwZT0icCIsIHBjaD0xOSwgY2V4PTAuNSwgbWFpbj0iMzB0aCBTbWFsbGVzdCBFaWdlbnZlY3RvciIsIHhsYWI9Ik5vZGUgaW5kZXgiLCB5bGFiPSJFaWdlbnZlY3RvciB2YWx1ZSIpDQpgYGANCg0KYGBge3J9DQpzMiA8LSB3aGljaCh2MzAgPiAtLjA0ICYgdjMwIDwgLS4wMSkNCg0KczJfbGVuZ3RoIDwtIGxlbmd0aChzMikNCnMyX21lbWJlcnMgPC0gczJbMToxMF0NCmNvbmRfczIgPC0gY29uZChzMikNCg0KY3JlYXRlX2xpc3QoczJfbGVuZ3RoLCBzMl9tZW1iZXJzLCBjb25kX3MyKQ0KYGBgDQoNCiMjIFNldCAzDQoNClRoaXMgc2V0IGNvcnJlc3BvbmRzIHRvIHRoZSB2ZXJ0aWNlcyB3aG9zZSB2YWx1ZXMgaW4gdGhlIDEwdGggc21hbGxlc3QgZWlnZW52ZWN0b3IgYXJlIGluIHRoZSByYW5nZSBbMC4wMiwgMC4wM10uDQoNCmBgYHtyfQ0KdjEwIDwtIGFsbF92ZWN0b3JzWyxuLTldDQpwbG90KHYxMCwgdHlwZT0icCIsIHBjaD0xOSwgY2V4PTAuNSwgbWFpbj0iMTB0aCBTbWFsbGVzdCBFaWdlbnZlY3RvciIsIHhsYWI9Ik5vZGUgaW5kZXgiLCB5bGFiPSJFaWdlbnZlY3RvciB2YWx1ZSIpDQpgYGANCg0KYGBge3J9DQpzMyA8LSB3aGljaCh2MTA+MC4wMiAmIHYxMDwwLjAzKQ0KDQpzM19sZW5ndGggPC0gbGVuZ3RoKHMzKQ0KczNfbWVtYmVycyA8LSBzM1sxOjEwXQ0KY29uZF9zMyA8LSBjb25kKHMzKQ0KDQpjcmVhdGVfbGlzdChzM19sZW5ndGgsIHMzX21lbWJlcnMsIGNvbmRfczMpDQoNCmBgYA0KDQo1LiAgU2VsZWN0IGEgcmFuZG9tIHNldCBvZiAxNTAgbm9kZXMsIGFuZCBjb21wdXRlIHRoZSBjb25kdWN0YW5jZSBvZiB0aGF0IHNldC4NCg0KYGBge3J9DQpzZXQuc2VlZCgxMjMpDQpyYW5kb21fc2V0IDwtIHNhbXBsZSgxOjE0OTUsIDE1MCkNCg0KY29uZChyYW5kb21fc2V0KQ0KYGBgDQoNClRoZSBjb25kdWN0YW5jZXMgZm91bmQgaW4gc2V0cyAxLDIsMyBpbiBjb25qdW5jdGlvbiB3aXRoIHRoZSBwbG90cyBpbmRpY2F0ZSB0aWdodC1rbml0IGZyaWVuZHNoaXBzIHdpdGhpbiB0aGUgZ3JvdXAgYW5kIGEgZGlzY29ubmVjdCBmcm9tIHRoZSByZXN0IG9mIHRoZSBncmFwaC4gQ29tcGFyaW5nIHdpdGggdGhlIGFib3ZlIGJlbmNobWFyayBvZiAwLjkgY29uZmlybXMgdGlnaHQta25pdG5lc3Mgd2l0aGluIGdyb3VwcyBnaXZlbiB0aGF0IGEgY29uZHVjdGFuY2Ugb2YgMC45IGluZGljYXRlcyB0aGF0IHZlcnRpY2VzIGluIG91ciByYW5kb21seSBzYW1wbGVkIHNldCBzaGFyZSBtaW5pbWFsIGludGVybmFsIGZyaWVuZHNoaXBzLg0K