提高社交网络分析R的处理性能

时间:2016-11-12 06:52:33

标签: r performance

我正在使用R中的igraph包进行社交网络分析,我正在处理近200万个顶点和边缘。还计算近800万个顶点和边的分离度。通常,执行需要2到3个小时,这太高了。我需要一些输入和建议来改善这种性能。以下是我正在使用的示例代码:

g <- graph.data.frame( ids, directed = F) # ids contains approximately 2 million records
distances(graph = g, v = t_ids$ID_from[x], to = t_ids$ID_to[x], weights = NA)
# t_ids contains approximately 8 million records for which degrees of separation is to be calculated using Shortest Path Algorithms

提前感谢!

1 个答案:

答案 0 :(得分:1)

我不这么认为,但我很高兴被证明是错的。

您应该研究优化正在运行的代码的其他方法。

如果你的数据是固定的,你可以计算一次距离,保存(可能相当大)的距离矩阵,并询问它的分离程度。

如果您的分析确实需要所有x个顶点之间的距离,那么您应该通过缩短t_ids$ID_from[x]来考虑在代码中进行优化。只获得您需要的距离。我怀疑你已经这样做了。

distances()实际上计算得相当快。在10'000个节点(相当于4,99 * 10 ^ 6个无向距离),我的蹩脚机器在几秒钟内获得了一个完整的700MB大距离矩阵。

我首先考虑了您在distances()中可以选择的不同算法,但现在我怀疑它们会对您有所帮助。我对不同的算法进行了速度测试,看看我是否可以向你推荐它们,但它们似乎都或多或少地以相同的速度运行(结果是使用自动算法计算时间的关系在上面的代码中):

  sample automatic unweighted  dijkstra bellman-ford   johnson
1     10         1  0.9416667 0.9750000    1.0750000 1.0833333
2    100         1  0.9427083 0.9062500    0.8906250 0.8958333
3   1000         1  0.9965636 0.9656357    0.9977090 0.9873998
4   5000         1  0.9674200 0.9947269    0.9691149 1.0007533
5  10000         1  1.0070885 0.9938136    0.9974223 0.9953602

我认为不能从中得出任何结论,但它是在Erdős-Rényi模型上运行的。您的网络结构可能有利于一种算法而不是另一种算法,但它们仍然可以为您提供接近您希望的性能提升的任何算法。

代码在这里:

# igrpah
library(igraph)

# setup:
samplesizes <- c(10, 100, 1000, 5000, 10000)
reps <- c(100, 100, 15, 3, 1)
algorithms = c("automatic", "unweighted", "dijkstra", "bellman-ford", "johnson")
df <- as.data.frame(matrix(ncol=length(algorithms), nrow=0), stringsAsFactors = FALSE)
names(df) <- algorithms

# any random graph
g <- erdos.renyi.game(10000, 10000, "gnm")

# These are the different algorithms used by distances:
m.auto <- distances(g, v=V(g), to=V(g), weights=NA, algorithm="automatic")
m.unwg <- distances(g, v=V(g), to=V(g), weights=NA, algorithm="unweighted")
m.dijk <- distances(g, v=V(g), to=V(g), weights=NA, algorithm="dijkstra")
m.belm <- distances(g, v=V(g), to=V(g), weights=NA, algorithm="bellman-ford")
m.john <- distances(g, v=V(g), to=V(g), weights=NA, algorithm="johnson")

# They produce the same result:
sum(m.auto == m.unwg & m.auto == m.dijk & m.auto == m.belm & m.auto == m.john) == length(m.auto)


# Use this function will be used to test the speed of distances() run using different algorithms
test_distances <- function(alg){
       m.auto <- distances(g, v=V(g), to=V(g), weights=NA, algorithm=alg)
       (TRUE)
}

# Build testresults
for(i.sample in 1:length(samplesizes)){
       # Create a random network to test
       g <- erdos.renyi.game(samplesizes[i.sample], (samplesizes[i.sample]*1.5), type = "gnm", directed = FALSE, loops = FALSE)

       i.rep <- reps[i.sample]

       for(i.alg in 1:length(algorithms)){
              df[i.sample,i.alg] <- system.time( replicate(i.rep, test_distances(algorithms[i.alg]) ) )[['elapsed']]
       }
}

# Normalize benchmark results
dfn <- df

dfn[,1:length(df[,])] <- df[,1:length(df[,])] / df[,1]
dfn$sample <- samplesizes
dfn <- dfn[,c(6,1:5)]
dfn