加快从2.92M数据点创建图表

时间:2014-09-12 23:20:43

标签: python ruby graph cluster-analysis networkx

我在3.0GB CSV文件中有2.92M数据点,我需要循环两次以创建一个我要加载到NetworkX中的图形。按目前的速度生成此图表需要几天时间。我怎样才能加快速度呢?

similarity = 8

graph = {}
topic_pages = {}

CSV.foreach("topic_page_node_and_edge.csv") do |row|
                topic_pages[row[0]] = row[1..-1]
end

CSV.open("generate_graph.csv", "wb") do |csv|
        i = 0
        topic_pages.each do |row|
                i+=1
                row = row.flatten
                topic_pages_attributes = row[1..-1]
                graph[row[0]] = []
                topic_pages.to_a[i..-1].each do |row2|
                        row2 = row2.flatten
                        topic_pages_attributes2 = row2[1..-1]
                        num_matching_attributes = (topic_pages_attributes2 & topic_pages_attributes).count
                        if num_matching_attributes >= similarity or num_matching_attributes == topic_pages_attributes2.count or num_matching_attributes == topic_pages_attributes.count
                                graph[row[0]].push(row2[0])
                        end
                end
                csv << [row[0], graph[row[0]]].flatten
        end
end

2 个答案:

答案 0 :(得分:2)

  1. <强>基准即可。例如,使用Python附带的cProfile。您的代码很容易出现代价高昂的低效问题,而且在密集型应用程序中,它们的性能成本可能会高达10倍。

    漂亮的代码,例如

    (topic_pages_attributes2 & topic_pages_attributes).count
    

    可能成为运行时的主要因素,可以通过使用更传统的代码轻松减少。

  2. 使用更有效的语言。例如在benchmarksgame.alioth中,在许多密集问题上,最快的 Python 3程序比最快的C程序(Ruby为67x,JRuby为33x)的中位数要慢63倍。是的,即使使用经过优化的Python代码,性能差距也可能很大。但如果你没有优化你的代码,它可能会更大;通过使用更有效的语言并仔细优化代码,您可以获得100x-1000x的加速。

  3. 考虑更明智的问题表达方式。例如,不是迭代每个节点,而是迭代每个边缘一次。在您的情况下,这可能意味着建立一个倒排索引,主题 - &gt;页面。这与文本搜索引擎的工作方式非常相似,也是在群集上计算此类操作的常用方法:可以在单独的节点上拆分各个主题。此方法受益于数据中的稀疏性。 这可以大大降低算法的运行时间。

    您有大约3个Mio文档。从您的总数据大小来看,它们平均可能少于100个主题?你的成对比较方法需要3个^ 2比较,这就是你的伤害。如果更热门的主题每个只使用30.000个文档,那么你可能只计算30k ^ 2 *个主题。假设你有100个非常受欢迎的话题(罕见的话题并不重要),这将是100倍的加速。

  4. 简化您的问题。例如, first 通过排序合并所有完全相同主题的文档。为了使其更有效,还要消除仅出现一次的所有主题。但可能只有大约10.000-100,000个不同的文档。使用排序可以轻松解决此步骤,并且可以使您的问题更容易900-90000倍(假设超出值范围)。

  5. 这些数字中的一些可能过于乐观 - 例如,IO根本没有被考虑在内,如果您的问题是I / O限制,使用C / Java可能没有多大帮助。可能有一些非常受欢迎的主题可能会受到C中讨论的方法的影响。对于D),您需要O(n log n)时间来对数据进行排序;但是有很好的实现可用。但它绝对是你应该做的简化。这些文件也将在您的最终数据中形成完全相关的集团,这可能也会影响其他分析。

答案 1 :(得分:0)

从磁盘上加载数据所花费的时间最多。将读取数据并行化为多个线程/进程,然后创建图形。

您也可以在不同的机器中创建子集图,并在以后合并它们。