简体   繁体   English

用于 networkx pagerank 的详细 output

[英]Verbose output for networkx pagerank

Suppose i create the following directed Graph using networkx and perform the pagerank algorithm on it假设我使用 networkx 创建以下有向图并对其执行 pagerank 算法

adj_lists={
  'A': 'B C'.split(' '),
  'B': 'C',
  'C': 'A',
  'D': 'C'
}
G=nx.DiGraph()
for k in adj_lists.keys():
  G.add_node(k)

for k in adj_lists.keys():
  G.add_edges_from([(k, t) for t in adj_lists[k]])

nx.pagerank(G, alpha=1)

Is ist possible to get a verbose output telling me the devolopment of each node's value or even to generate a list which shows their progress?是否有可能得到一个详细的 output 告诉我每个节点的价值的发展,甚至生成一个显示其进度的列表? I am thinking about something like this:我正在考虑这样的事情:

[
  {'A:0.25, 'B':0.25, 'C':0.25, 'D':0.25},
  {'A:0.25, 'B':0.125, 'C':0.625, 'D':0},
  {'A:0.625, 'B':0.3125, 'C':0.4375, 'D':0},
  ...
]

I've made a direct modification of networkx.pagerank algorithm to store the values of each iteration in a list.我对networkx.pagerank算法进行了直接修改,以将每次迭代的值存储在列表中。

import networkx as nx
from networkx.utils import not_implemented_for

def verbose_pagerank(
    G,
    alpha=0.85,
    personalization=None,
    max_iter=100,
    tol=1.0e-6,
    nstart=None,
    weight="weight",
    dangling=None,
):
    if len(G) == 0:
        return {}

    if not G.is_directed():
        D = G.to_directed()
    else:
        D = G

    # Create a copy in (right) stochastic form
    W = nx.stochastic_graph(D, weight=weight)
    N = W.number_of_nodes()

    # Choose fixed starting vector if not given
    if nstart is None:
        x = dict.fromkeys(W, 1.0 / N)
    else:
        # Normalized nstart vector
        s = float(sum(nstart.values()))
        x = {k: v / s for k, v in nstart.items()}

    if personalization is None:
        # Assign uniform personalization vector if not given
        p = dict.fromkeys(W, 1.0 / N)
    else:
        s = float(sum(personalization.values()))
        p = {k: v / s for k, v in personalization.items()}

    if dangling is None:
        # Use personalization vector if dangling vector not specified
        dangling_weights = p
    else:
        s = float(sum(dangling.values()))
        dangling_weights = {k: v / s for k, v in dangling.items()}
    dangling_nodes = [n for n in W if W.out_degree(n, weight=weight) == 0.0]

    # power iteration: make up to max_iter iterations
    iterprogress = []
    for i in range(max_iter):
        xlast = x
        iterprogress.append(x)
        x = dict.fromkeys(xlast.keys(), 0)
        danglesum = alpha * sum(xlast[n] for n in dangling_nodes)
        for n in x:
            # this matrix multiply looks odd because it is
            # doing a left multiply x^T=xlast^T*W
            for nbr in W[n]:
                x[nbr] += alpha * xlast[n] * W[n][nbr][weight]
            x[n] += danglesum * dangling_weights.get(n, 0) + (1.0 - alpha) * p.get(n, 0)
        # check convergence, l1 norm
        err = sum([abs(x[n] - xlast[n]) for n in x])
        if err < N * tol:
            iterprogress.append(x)
            return iterprogress
    raise nx.PowerIterationFailedConvergence(max_iter)

Then use the function verbose_pagerank the same as you did with nx.pagerank然后像使用 nx.pagerank 一样使用nx.pagerank verbose_pagerank

adj_lists={
  'A': 'B C'.split(' '),
  'B': 'C',
  'C': 'A',
  'D': 'C'
}
G=nx.DiGraph()
for k in adj_lists.keys():
  G.add_node(k)

for k in adj_lists.keys():
  G.add_edges_from([(k, t) for t in adj_lists[k]])

pr = verbose_pagerank(G, alpha=1)
for i in pr:
    print(i)

Output: Output:

{'A': 0.25, 'B': 0.25, 'C': 0.25, 'D': 0.25}
{'A': 0.25, 'B': 0.125, 'C': 0.625, 'D': 0.0}
{'A': 0.625, 'B': 0.125, 'C': 0.25, 'D': 0.0}
...
{'A': 0.40000057220458984, 'B': 0.20000028610229492, 'C': 0.39999914169311523, 'D': 0.0}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM