【问题标题】:igraph invalid vertex Idigraph 无效的顶点 ID
【发布时间】:2016-01-24 06:03:05
【问题描述】:

我正在尝试使用以下代码运行 igraph 的快速贪婪社区检测算法:

G = Graph()

L = []
V = []
for row in cr:

    try:
        l = []
        source = int((row[0]).strip())
        target = int((row[1]).strip())
        weight = int((row[2]).strip())
        l.append(source)
        l.append(target)

        if l not in L:
            L.append(l)

        if source not in V:
            V.append(source)

        if target not in V:
            V.append(target)
    except ValueError:
        print "Value Error"
        continue

    if weight == 1:
        continue

G.add_vertices(max(V))
G.add_edges(L)
cl = G.community_fastgreedy(weights=weight).as_clustering(10);

但这是我得到的错误: igraph._igraph.InternalError:type_indexededgelist.c:272 处的错误:无法添加边,顶点 ID 无效

我发现了这个:Cannot add edges, Invalid vertex ID in IGraph 所以我尝试添加所有顶点,然后添加所有边,但仍然出现错误。

上面的代码是否与以下代码相同:

tupleMapping = []
for row in cr:
    if int(row[2]) < 10:
        continue

    l = [row[0], row[1], row[2]]
    tupleMapping.append(tuple(l))

g = Graph.TupleList(tupleMapping)
cl = g.community_fastgreedy().as_clustering(20)

我不必明确地说 G.community_fastgreedy(weights=weight) 对吧?

我还有另一个问题;当我尝试通过以下方式添加更多集群时:

cl = g.community_fastgreedy().as_clustering(10)
cl = g.community_fastgreedy().as_clustering(20)

我得到两个大集群,其余集群由一个元素组成。当我尝试将集群大小设置为 5/10/20 时会发生这种情况,有什么方法可以让集群更加平均分配吗?我的数据集需要 2 个以上的集群。

这是我试图从 csv 文件中读取的数据的一个小 sn-p,以便我可以生成一个图表,然后运行社区检测算法: 202,580,11 87,153,7 227,459,6 263,524,11

谢谢。

【问题讨论】:

    标签: python-2.7 cluster-analysis igraph hierarchical-clustering


    【解决方案1】:

    没错,第二个代码也是如此。在第一个例子中,问题是当你添加边时,你引用了 igraph 的内部顶点 ID,它总是从 0 开始,一直到N-1。没关系您自己的顶点名称是整数,您需要将它们转换为 igraph 顶点 ID。

    igraph.Graph.TupleList() 方法在这里更方便。但是,您需要指定元组的第三个元素是权重。您可以通过weights = Trueedge_attrs = ['weight'] 参数来实现:

    import igraph
    
    data = '''1;2;34
    1;3;41
    1;4;87
    2;4;12
    4;5;22
    5;6;33'''
    
    L = set([])
    
    for row in data.split('\n'):
        row = row.split(';')
        L.add(
            (row[0].strip(), row[1].strip(), int(row[2].strip()))
        )
    
    G = igraph.Graph.TupleList(L, edge_attrs = ['weight'])
    

    然后您可以创建字典以在 igraph 顶点 ID 和您的原始名称之间进行转换:

    vid2name = dict(zip(xrange(G.vcount()), G.vs['name']))
    name2vid = dict((name, vid) for vid, name in vid2name.iteritems())
    

    但是,第一个并不是那么需要,因为您始终可以使用G.vs[vid]['name']

    对于 fastgreedy,我认为您应该指定权重,至少文档没有说明它是否会自动考虑名为 weight 的属性(如果存在此类属性)。

    fg = G.community_fastgreedy(weights = 'weight')
    fg_clust_10 = fg.as_clustering(10)
    fg_clust_20 = fg.as_clustering(20)
    

    如果 fastgreedy 只给你 2 个大集群,我只能建议尝试其他社区检测方法。实际上,您可以尝试所有在合理时间内运行的方法(这取决于图表的大小),然后比较它们的结果。另外因为你有一个加权图,你可以看看moduland method family,它没有在 igraph 中实现,但有很好的文档,你可以设置相当复杂的设置。

    编辑: OP 的 cmets 表明原始数据描述了一个有向图。 fastgreedy 算法无法考虑方向,如果在有向图上调用会出错。这就是为什么在我的示例中我创建了一个无向的igraph.Graph() 对象。如果你想运行其他方法,其中一些可能能够处理有向网络,你应该首先创建一个有向图:

    G = igraph.Graph.TupleList(L, directed = True, edge_attrs = ['weight'])
    G.is_directed()
    # returns True
    

    要运行 fastgreedy,请将图转换为无向图。由于您有边的权重属性,因此您需要指定当同一对顶点之间的相反方向的 2 条边折叠到一个无向边时 igraph 应该做什么。你可以对权重做很多事情,比如取平均值、取大的或小的等。例如,使组合边具有原始边的平均权重:

    uG = G.as_undirected(combine_edges = 'mean')
    fg = uG.community_fastgreedy(weights = 'weight')
    

    重要提示:请注意,在此操作中,以及添加或删除顶点或边时,igraph 会重新索引顶点和边,因此如果您知道顶点 id x 对应于您的原始 id y,则重新索引这将不再有效,您需要重新创建 name2vidvid2name 字典。

    【讨论】:

    • 谢谢,太好了!现在我得到了 2 个大型集群,2 个中型集群,其余集群具有单个元素。我没有意识到你必须指定一个重量,但它肯定会对结果产生影响。该图是定向的,但我不知道如何合并它。我从文档中看到您添加了directed = 'true',但是您在前面的步骤中执行了一些指定方向的操作。您能否举例说明如何使此代码适用于有向图?或者我可以问一个不同的问题。
    • 我发现 fastgreedy 只适用于无向图。您对如何处理有向图有什么建议吗?谢谢。
    • 您仍然可以使用 fastgreedy,但它不考虑方向性,因此您会丢失附加信息。一旦你初始化了igraph.Graph() 对象,你就可以决定它是一个有向网络还是无向网络。这里我们将它初始化为无向图,正是因为 fastgreedy 需要一个无向图。如果您使用能够考虑方向的其他方法,例如 spinglass,您应该创建一个有向网络:igraph.Graph.TupleList(L, directed = True, ...)。您还可以使用as_directed()as_undirected() 方法在有向图和无向图之间进行转换。
    • 谢谢!这很有帮助。如果你对有向图或无向图进行快速搜索,你会得到相同的结果吗?
    • 如果有点不清楚,一方面,如果我只是directed=true,那会从源-> 目标生成一个箭头吗?总是这样吗?如果它是双向的,我需要有两个条目吗? 1 -> 2 和 2 -> 1(顶点 1 和 2)
    猜你喜欢
    • 2013-12-19
    • 1970-01-01
    • 2015-02-17
    • 1970-01-01
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多