R: igraph, обнаружение сообщества, edge.метод betweenness, количество / список членов каждого сообщества?
у меня относительно большой граф с вершинами: 524 ребра: 1125, реальных транзакций. Края направлены и имеют вес (включение опционное). Я пытаюсь исследовать различные сообщества в графе и по существу нуждаюсь в методе, который:
-вычисляет все возможные сообществ
-вычисляет оптимальное количество общин
- возвращает членов / # членов каждого (оптимального) сообщества
до сих пор я удалось собрать следующий код, который строит цветной график, соответствующий различным сообществам, однако я понятия не имею, как контролировать количество сообществ (i.e построить топ-5 сообществ с самым высоким членством) или перечислить членов определенного сообщества.
library(igraph)
edges <- read.csv('http://dl.dropbox.com/u/23776534/Facebook%20%5BEdges%5D.csv')
all<-graph.data.frame(edges)
summary(all)
all_eb <- edge.betweenness.community(all)
mods <- sapply(0:ecount(all), function(i) {
all2 <- delete.edges(all, all_eb$removed.edges[seq(length=i)])
cl <- clusters(all2)$membership
modularity(all, cl)
})
plot(mods, type="l")
all2<-delete.edges(all, all_eb$removed.edges[seq(length=which.max(mods)-1)])
V(all)$color=clusters(all2)$membership
all$layout <- layout.fruchterman.reingold(all,weight=V(all)$weigth)
plot(all, vertex.size=4, vertex.label=NA, vertex.frame.color="black", edge.color="grey",
edge.arrow.size=0.1,rescale=TRUE,vertex.label=NA, edge.width=.1,vertex.label.font=NA)
потому что метод edge betweenness работал так плохо, что я снова попытался использовать метод walktrap:
all_wt<- walktrap.community(all, steps=6,modularity=TRUE,labels=TRUE)
all_wt_memb <- community.to.membership(all, all_wt$merges, steps=which.max(all_wt$modularity)-1)
colbar <- rainbow(20)
col_wt<- colbar[all_wt_memb$membership+1]
l <- layout.fruchterman.reingold(all, niter=100)
plot(all, layout=l, vertex.size=3, vertex.color=col_wt, vertex.label=NA,edge.arrow.size=0.01,
main="Walktrap Method")
all_wt_memb$csize
[1] 176 13 204 24 9 263 16 2 8 4 12 8 9 19 15 3 6 2 1
19 кластеров - намного лучше!
Теперь скажем, у меня был "известный кластер" со списком его членов и я хотел проверить каждый из наблюдаемых кластеров на наличие членов из "известного кластера". Возврат процента найденных членов. Не удалось закончить следующее??
list<-read.csv("http://dl.dropbox.com/u/23776534/knownlist.csv")
ength(all_wt_memb$csize) #19
for(i in 1:length(all_wt_memb$csize))
{
match((V(all)[all_wt_memb$membership== i]),list)
}
2 ответов
несколько из этих вопросов можно обнаружить, внимательно изучив документацию используемых вами функций. Например, документация clusters
, в разделе" значения", описывает, что будет возвращено из функции, несколько из которых отвечают на ваши вопросы. Документация в стороне, вы всегда можете использовать str
функция для анализа состава любого конкретного объекта.
это, как говорится, чтобы получить членов или количество членов в конкретном сообщество, вы можете посмотреть на
что касается "как контролировать количество сообществ" в вопросе OPs, я использую функцию cut_at для сообществ, чтобы разрезать полученную иерархическую структуру на желаемое количество групп. Надеюсь, кто-то может подтвердить, что я делаю что-то вменяемое. А именно, рассмотрим следующее:
#Generate graph
adj.mat<- matrix(,nrow=200, ncol=200) #empty matrix
set.seed(2)
##populate adjacency matrix
for(i in 1:200){adj.mat[i,sample(rep(1:200), runif(1,1,100))]<-1}
adj.mat[which(is.na(adj.mat))] <-0
for(i in 1:200){
adj.mat[i,i]<-0
}
G<-graph.adjacency(adj.mat, mode='undirected')
plot(G, vertex.label=NA)
##Find clusters
walktrap.comms<- cluster_walktrap(G, steps=10)
max(walktrap.comms$membership) #43
[1] 6 34 13 1 19 19 3 9 20 29 12 26 9 28 9 9 2 14 13 14 27 9 33 17 22 23 23 10 17 31 9 21 2 1
[35] 33 23 3 26 22 29 4 16 24 22 25 31 23 23 13 30 35 27 25 15 6 14 9 2 16 7 23 4 18 10 10 22 27 27
[69] 23 31 27 32 36 8 23 6 23 14 19 22 19 37 27 6 27 22 9 14 4 22 14 32 33 27 26 14 21 27 22 12 20 7
[103] 14 26 38 39 26 3 14 23 22 14 40 9 5 19 29 31 26 26 2 19 6 9 1 9 23 4 14 11 9 22 23 41 10 27
[137] 22 18 26 14 8 15 27 10 5 33 21 28 23 22 13 1 22 24 14 18 8 2 18 1 27 12 22 34 13 27 3 5 27 25
[171] 1 27 13 34 8 10 13 5 17 17 25 6 19 42 31 13 30 32 15 30 5 11 9 25 6 33 18 33 43 10
Теперь обратите внимание, что есть 43 группы, но мы хотим более грубые сокращения, следовательно, изучите дендрограмму:
plot(as.hclust(walktrap.comms), label=F)
и вырезать на его основе. Я произвольно выбрал 6 путей, но тем не менее, теперь у вас есть более грубые кластеров
cut_at(walktrap.comms, no=6)
[1] 4 2 5 4 5 5 3 5 3 4 3 5 5 3 5 5 3 1 5 1 1 5 1 6 1 1 1 4 6 5 5 2 3 4 1 1 3 5 1 4 6 6 3 1 5 5 1 1 5 4 3 1
[53] 5 2 4 1 5 3 6 3 1 6 6 4 4 1 1 1 1 5 1 4 3 3 1 4 1 1 5 1 5 2 1 4 1 1 5 1 6 1 1 4 1 1 5 1 2 1 1 3 3 3 1 5
[105] 3 3 5 3 1 1 1 1 3 5 2 5 4 5 5 5 3 5 4 5 4 5 1 6 1 3 5 1 1 1 4 1 1 6 5 1 3 2 1 4 2 1 2 3 1 1 5 4 1 3 1 6
[157] 3 3 6 4 1 3 1 2 5 1 3 2 1 5 4 1 5 2 3 4 5 2 6 6 5 4 5 3 5 5 4 4 2 4 2 3 5 5 4 1 6 1 2 4