图机器学习(Graph Machine Learning)- 第一章 图的基本概念 -图的性质 Graph properties-基准和资源库Benchmark and Repositories

本文深入探讨了图的性质,包括集成度量如距离、路径长度、聚类系数和特征路径长度,以及隔离度量如传递性和模块性。此外,还介绍了中心性度量,如度中心性、接近中心性和中介中心性,这些度量在理解网络中节点重要性方面至关重要。文章通过具体示例和代码展示了如何使用networkx库计算这些属性,并强调了这些度量在实际网络分析中的应用。
摘要由CSDN通过智能技术生成

第一章 图的基本概念2 -图的性质 Graph properties-基准和资源库Benchmark and Repositories

  • 本专栏是Claudio Stamile , Aldo Marzullo , Enrico Deusebio,Graph Machine Learning,Packt ,2021.的读书笔记。
  • 官方代码可以从 GitHub上下载。


前言

正如我们已经了解到的,图是一种用来描述实体之间关系的数学模型。然而,每个复杂的网络都具有固有的性质。这些属性可以通过特定的度量来度量,每个度量可以描述图的一个或几个局部和全局方面。

例如,在Twitter等社交网络的图中,用户(由图中的节点表示)彼此连接。然而,有些用户比其他人(有影响力的人)联系更紧密。在Reddit社交图谱上,具有相似特征的用户倾向于组成社区。

我们已经提到了图的一些基本特征,如图中的节点和边的数量,它们构成了图本身的大小。这些特性已经很好地描述了网络的结构。

例如考虑Facebook图:它可以用节点和边的数量来描述。这些数字可以很容易地将其与一个小得多的网络(例如,办公室的社会结构)区分开来,但无法描述更复杂的动态特征(例如,相似的节点是如何连接的)。

为此,我们可以考虑更高级的图形派生度量,它们可以分为以下四大类:

  • 集成度量(Integration metrics):度量节点之间如何相互连接。
  • 隔离指标(Segregation metrics):量化网络中相互连接的节点组(称为社区或模块)的存在。
  • 中心性度量(Centrality metrics):评估网络中各个节点的重要性。
  • 弹性指标(Resilience metrics):衡量网络在面临故障或其他不利条件时能够维持和调整其操作性能的程度。

当表示整个网络的度量时,这些度量被定义为全局的。另一方面,局部度量度量单个网络元素(节点或边)的值。在加权图中,每个属性都可能或不可能解释边的权值,从而导致加权和非加权度量。

在下一节中,我们将描述一些最常用的度量全局和局部属性的指标。为了简单起见,除非在文本中另有说明,否则我们度量是的全局未加权。在一些情况下,这是通过平均节点的局部非加权属性获得的。

import networkx as nx
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

default_edge_color = 'gray'
default_node_color = '#407cc9'
enhanced_node_color = '#f5b042'
enhanced_edge_color = '#cc2f04'
# 本节常用的两个函数
# draw a simple graph
def draw_graph(G, node_names={}, filename=None, node_size=50):
    pos_nodes = nx.spring_layout(G)
    nx.draw(G, pos_nodes, with_labels=False, node_size=node_size, edge_color='gray')
    
    pos_attrs = {}
    for node, coords in pos_nodes.items():
        pos_attrs[node] = (coords[0], coords[1] + 0.08)
        
    nx.draw_networkx_labels(G, pos_attrs, labels=node_names, font_family='serif')
    
    plt.axis('off')
    axis = plt.gca()
    axis.set_xlim([1.2*x for x in axis.get_xlim()])
    axis.set_ylim([1.2*y for y in axis.get_ylim()])
    
    if filename:
        plt.savefig(filename, format="png")


# draw enhanced path on the graph
def draw_enhanced_path(G, path_to_enhance, node_names={}, filename=None):
    path_edges = list(zip(path,path[1:]))
    pos_nodes = nx.spring_layout(G)

    plt.figure(figsize=(5,5),dpi=300)
    pos_nodes = nx.spring_layout(G)
    nx.draw(G, pos_nodes, with_labels=False, node_size=50, edge_color='gray')
    
    pos_attrs = {}
    for node, coords in pos_nodes.items():
        pos_attrs[node] = (coords[0], coords[1] + 0.08)
        
    nx.draw_networkx_labels(G, pos_attrs, labels=node_names, font_family='serif')
    nx.draw_networkx_edges(G,pos_nodes,edgelist=path_edges, edge_color='#cc2f04', style='dashed', width=2.0)
    
    plt.axis('off')
    axis = plt.gca()
    axis.set_xlim([1.2*x for x in axis.get_xlim()])
    axis.set_ylim([1.2*y for y in axis.get_ylim()])
    
    if filename:
        plt.savefig(filename, format="png")

1、图的性质

1.1 集成度量 Integration metrics

在本节中,将描述一些最常用的集成指标。

1.1.1 距离,路径,最短路径 Distance, path, and shortest path

图中距离的概念通常与从给定的源节点到达目标节点所需遍历的边数有关。

特别是,考虑一个源节点 i i i和一个目标节点 j j j。连接节点 i i i与节点 j j j的边集合称为路径。在研究复杂网络时,我们通常感兴趣的是寻找两个节点之间的最短路径。源节点 i i i和目标节点 j j j之间的最短路径是与 i i i j j j之间的所有可能路径相比,边数最少的路径。网络的直径是指在所有可能的最短路径中,最长最短路径所包含的边数。

networkx Python库的shortest_path函数允许用户快速计算图中两个节点之间的最短路径。考虑下面的代码,其中使用networkx创建了一个七节点图:

从下图中可以看出,从Tokyo有不同的路线到Dublin,然而,其中一个是最短的(最短路径上的边被突出显示):

G = nx.Graph()
nodes = {1:'Dublin',2:'Paris',3:'Milan',4:'Rome',5:'Naples',6:'Moscow',7:'Tokyo'}
G.add_nodes_from(nodes.keys())
G.add_edges_from([(1,2),(1,3),(2,3),(3,4),(4,5),(5,6),(6,7),(7,5)])

源节点(例如,‘Dublin’,由1标识)和目标节点(如用7标识的Tokyo)之间的最短路径可以由以下命令得到:

path = nx.shortest_path(G,source=1,target=7)
print(path)
[1, 3, 4, 5, 7]
draw_enhanced_path(G, path, node_names=nodes,filename='shortest_path.png')

在这里插入图片描述

1.2 特征路径长度 Characteristic path lenght

特征路径长度定义为所有可能的节点对之间所有最短路径长度的平均值。如果 l i l_i li是节点 i i i到所有其他节点的平均路径长度,则特征路径长度计算如下:

1 q ( q − 1 ) ∑ i ∈ V l i \frac{1}{q(q-1)} \sum_{i \in V}l_i q(q1)1iVli

其中 V V V是图中节点的集合, q = ∣ V ∣ q=|V| q=V是序(order)。这是最常用的衡量信息在网络中传播效率的方法之一。具有较短特征路径长度的网络可以促进信息的快速传递,降低成本。特征路径长度可通过networkx计算,计算函数如下:

nx.average_shortest_path_length(G)
2.1904761904761907

然而,特征路径长度这个度量不能总是被定义,因为不可能在不相连(disconnected)的图中计算所有节点之间的路径。因此,网络效率(network efficiency)也得到了广泛的应用。

1.3 全局和局部效率 Global and Local Efficiency

全局效率(Global efficiency) 是所有节点对的逆最短路径长度的平均值。这样的指标可以被看作是衡量信息在网络中交换的效率的指标。

假设 l i j l_{ij} lij是节点 i i i和节点 j j j之间的最短路径。网络效率的定义如下:

1 q ( q − 1 ) ∑ i ∈ V l i j \frac{1}{q(q-1)} \sum_{i \in V}l_{ij} q(q1)1iVlij

当一个图是完全连通时,效率是最大的,而对于完全不连通的图,效率是最小的。直观上看,路径越短,度量值越低。

计算节点的局部效率(local efficiency) 可以只考虑除节点本身外的节点邻域。

在networkx中使用以下命令计算全局效率和局部效率。

G = nx.Graph()
nodes = {1:'Dublin',2:'Paris',3:'Milan',4:'Rome',5:'Naples',6:'Moscow',7:'Tokyo'}
G.add_nodes_from(nodes.keys())
G.add_edges_from([(1,2),(1,3),(2,3),(3,4),(4,5),(5,6),(6,7),(7,5)])

print(nx.global_efficiency(G))
print(nx.local_efficiency(G))
0.611111111111111
0.6666666666666667

在下图中,描述了两个图例。可以看出,左边的完全连通图比右边的圆形图具有更高的效率水平。在全连通图中,每个节点都可以从图中的任何其他节点到达,信息在网络中快速交换。然而,在圆形图中,需要遍历几个节点才能到达目标节点,这样效率会降低:

# higher efficiency
G = nx.complete_graph(n=7)
nodes = {0:'Dublin',1:'Paris',2:'Milan',3:'Rome',4:'Naples',5:'Moscow',6:'Tokyo'}

ge = round(nx.global_efficiency(G),2)

# place the text box in axes coords
ax = plt.gca()
ax.text(-.4, -1.3, "Global Efficiency:{}".format(ge), fontsize=14, ha='left', va='bottom');

draw_graph(G,node_names=nodes,filename='efficiency.png')

在这里插入图片描述

# lower efficiency
G = nx.cycle_graph(n=7)
nodes = {0:'Dublin',1:'Paris',2:'Milan',3:'Rome',4:'Naples',5:'Moscow',6:'Tokyo'}

le = round(nx.global_efficiency(G),2)

# place the text box in axes coords
ax = plt.gca()
ax.text(-.4, -1.3, "Global Efficiency:{}".format(le), fontsize=14, ha='left', va='bottom');

draw_graph(G, node_names=nodes,filename='less_efficiency.png')

在这里插入图片描述

1.4 隔离度量 Segregation metrics

在本节中,将描述一些最常见的隔离指标。

1.4.1聚类系数Clustering coefficient

聚类系数(Clustering coefficient) 衡量节点聚集的程度。

局部聚类系数定义为:
C i = 包 含 节 点 i 的 三 角 形 数 目 以 节 点 i 为 中 心 的 连 通 三 元 组 的 数 目 C_i = \frac{包含节点i的三角形数目}{以节点i为中心的连通三元组的数目} Ci=ii

  • 若节点i有 k i k_i ki个邻节点,包含节点i的三角形至多可能有 k i ( k i − 1 ) / 2 k_i(k_i -1)/2 ki(ki1)/2个。

  • 以节点i为中心的连通三元组表示包括节点i的3个节点并且至少存在从节点i到其他两个节点的两条边,那么以节点i为中心的连通三元组的数目实际上就是包含节点i的三角形的最大可能的数目,即 k i ( k i − 1 ) / 2 k_i(k_i -1)/2 ki(ki1)/2

全局聚类系数定义为图中所有节点的聚类系数的平均值,即
C = 1 ∣ V ∣ ∑ i ∈ V C i C = \frac{1}{|V|} \sum_{i \in V}C_i C=V1iVCi

G = nx.Graph()
nodes = {1:'Dublin',2:'Paris',3:'Milan',4:'Rome',5:'Naples',6:'Moscow',7:'Tokyo'}
G.add_nodes_from(nodes.keys())
G.add_edges_from([(1,2),(1,3),(2,3),(3,4),(4,5),(5,6),(6,7),(7,5)])

在networkx中,使用以下命令计算全局聚类系数:

nx.average_clustering(G)
0.6666666666666667

在networkx中,使用以下命令计算局部聚类系数:

nx.clustering(G)
{1: 1.0,
 2: 1.0,
 3: 0.3333333333333333,
 4: 0,
 5: 0.3333333333333333,
 6: 1.0,
 7: 1.0}

以上输出是一个Python字典,其中包含每个节点(由相应的键标识)对应的值。

如下图所示,可以很容易地识别出两个节点集群。通过计算每个单个节点的聚类系数可以看出,Rome的值最小。Tokyo和Moscow,以及Paris和Dublin在各自的组内连接得很好(注意,每个节点的大小与每个节点的聚类系数成比例)。

cc = nx.clustering(G)
node_size=[(v + 0.1) * 200 for v in cc.values()]
draw_graph(G, node_names=nodes, node_size=node_size,filename='clustering.png')

1.4.2传递性 Transitivity

聚类系数的一个常见变种被称为传递性(Transitivity),简单地定义为观察到的闭三元组(closed triplets)(具有三个节点和两条边的完全子图)的数量与图中最大可能的闭三元组数量的比值。传递性可以使用networkx计算,如下所示

nx.transitivity(G)
0.5454545454545454

1.4.3 模块性 Modularity

模块性的设计目的是为了将网络划分为高度互联的节点聚集在一起的集合,通常称为模块、社区、组或集群。其主要思想是,具有高模块化的网络将呈现模块内部密集连接和模块之间稀疏连接。

以Reddit这样的社交网络为例:与电子游戏相关的社区成员倾向于与同一社区中的其他用户进行更多的互动,谈论最近的新闻、最喜欢的主机等等。然而,他们可能会与谈论时尚的用户互动较少。与许多其他图度量不同,模块化通常是通过优化算法来计算的。

networkx中的模块化度是使用network .algorithms.community模块的模块化度函数来计算的,如下所示:

import networkx.algorithms.community as nx_comm

G = nx.Graph()
nodes = {1:'Dublin',2:'Paris',3:'Milan',4:'Rome',5:'Naples',6:'Moscow',7:'Tokyo'}
G.add_nodes_from(nodes.keys())
G.add_edges_from([(1,2),(1,3),(2,3),(3,4),(4,5),(5,6),(6,7),(7,5)])

# partitions can be provided manually
print(nx_comm.modularity(G, communities=[{1,2,3,4},{5,6,7}]))

# or automatically computed using networkx
print(nx_comm.modularity(G, nx_comm.label_propagation_communities(G)))
0.3671875
0.3671875

隔离度量有助于理解组的存在。 但是,每个节点在一个图中有它自己的重要性。 为了量化它,我们可以使用中心性度量。

1.5 中心性度量 Centrality metrics

在本节中,将描述一些最常见的中心性度量。

1.5.1度中心性 Degree centrality

最常见和简单的中心性度量之一是度中心性度量。 这与节点的度直接相关,测量某个节点 i i i上的*入射(incident)*边数,即一个节点与所有其它节点相联系的程度。

从直观上看,一个节点与另一个节点连接得越多,其度中心性值越高。注意如果一个图是有向的,则需考虑每个节点的入度中心性(in-degree centrality)出度中心性(in-degree centrality) ,它们分别与入边和出边的数量有关。在networkx中,使用以下命令计算度中心性:

G = nx.Graph()
nodes = {1:'Dublin',2:'Paris',3:'Milan',4:'Rome',5:'Naples',6:'Moscow',7:'Tokyo'}
G.add_nodes_from(nodes.keys())
G.add_edges_from([(1,2),(1,3),(2,3),(3,4),(4,5),(5,6),(6,7),(7,5)])
nx.degree_centrality(G)
{1: 0.3333333333333333,
 2: 0.3333333333333333,
 3: 0.5,
 4: 0.3333333333333333,
 5: 0.5,
 6: 0.3333333333333333,
 7: 0.3333333333333333}
dc = nx.degree_centrality(G)
node_size=[(v + 0.01) * 400 for v in dc.values()]
draw_graph(G, node_names=nodes, node_size=node_size,filename='deg_centr.png')

df = pd.DataFrame(dc,index=['Degree centrality'])
df.columns = nodes.values()
df

在这里插入图片描述

1.5.2 接近中心性(Closeness Centrality)

接近中心性度量量化一个节点与其他节点的亲密(良好连接)程度。更正式的说法是,它指的是一个节点到网络中所有其他节点的平均距离。若 l i j l_{ij} lij为节点 i i i与节点 j j j之间的最短路径,则其贴近度中心性定义如下:

1 ∑ i ∈ V , i ≠ j l i j \frac{1}{\sum_{i \in V, i \neq j}l_{ij}} iV,i=jlij1

其中 V V V是图中的节点集合。接近中心性可以在networkx中使用以下命令计算:

nx.closeness_centrality(G)
{1: 0.4,
 2: 0.4,
 3: 0.5454545454545454,
 4: 0.6,
 5: 0.5454545454545454,
 6: 0.4,
 7: 0.4}
dc = nx.closeness_centrality(G)
node_size=[(v + 0.1) * 400 for v in dc.values()]
draw_graph(G, node_names=nodes, node_size=node_size,filename='clos_centr.png')

df = pd.DataFrame(dc,index=['Closeness centrality'])
df.columns = nodes.values()
df

在这里插入图片描述

1.5.3 中介中心性(betweenness centrality)

中间度中心性度量评估一个节点在其他节点之间充当桥梁的程度。即使连接得很差,节点也可以战略性地连接起来,帮助保持整个网络的连接。

中介中心性的思想是:如果一个成员位于其他成员的多条最短路径上,那么该成员就是核心成员,就具有较大的中介中心性。

如果 L w j L_{wj} Lwj是节点 w w w与节点 j j j之间的最短路径总数, L w j ( i ) L_{wj}(i) Lwj(i)是节点 w w w与节点 j j j之间通过节点 i i i的最短路径总数,则中间度中心性定义如下:

∑ w ≠ i ≠ j L w j ( i ) L w j \sum_{w \neq i \neq j} \frac{L_{wj}(i)}{L_{wj}} w=i=jLwjLwj(i)

观察公式可以发现,通过节点的最短路径数越多,中间度中心性的值就越大。在networkx中,使用以下命令计算中间性中心性:

nx.betweenness_centrality(G)
{1: 0.0,
 2: 0.0,
 3: 0.5333333333333333,
 4: 0.6,
 5: 0.5333333333333333,
 6: 0.0,
 7: 0.0}
dc = nx.betweenness_centrality(G)
node_size=[(v + 0.1) * 400 for v in dc.values()]
draw_graph(G, node_names=nodes, node_size=node_size,filename='bet_centrality.png')

df = pd.DataFrame(dc,index=['Betweenness centrality'])
df.columns = nodes.values()
df

在这里插入图片描述

从以上图例中也说明了度中心性、接近中心性和中介中心性之间的区别。Milan和Naples的度中心性最高。Rome有最高的接近中心性,因为它与任何其他节点最接近。它还显示了最高的中介中心性,因为它在连接两个可见集群和保持整个网络连接方面起着至关重要的作用。

中心性指标允许我们度量网络中一个节点的重要性。最后,我们将提到弹性度量,它使我们能够度量图的脆弱性。

1.6 弹性指标 Resilience metrics

有几个度量网络弹性的指标。同配性是最常用的一种。

1.6.1 同配性系数 Assortativity coefficient

同配性是用来量化节点被连接到相似节点的趋势,即用作考察度值相近的节点是否倾向于互相连接。有几种方法可以衡量这种相关性。最常用的方法之一是直接连接节点(链路两端的节点)度之间的皮尔逊相关系数(Pearson correlation coefficient)。当相似度的节点之间存在相关性时,该系数为正值;当不同度的节点之间存在相关性时,该系数为负值。networkx 利用皮尔逊相关系数计算同配性的代码如下:

nx.degree_pearson_correlation_coefficient(G)
-0.6

社交网络大多是同配的。然而,所谓的影响者(著名歌手、足球运动员、时尚博主)往往会被几个标准用户关注(入射边),而他们往往彼此联系在一起,表现出一种不同配的行为。

G = nx.Graph()
nodes = {1:'user1', 2:'user2', 3:'Football player', 4:'Fahsion blogger', 5:'user3', 6:'user4',
         7:'user5', 8:'user6'}
G.add_nodes_from(nodes.keys())
G.add_edges_from([(1,3),(2,3),(7,3),(3,4),(5,4),(6,4),(8,4)])

draw_graph(G, node_names=nodes,filename='assortativity.png')

在这里插入图片描述

nx.degree_pearson_correlation_coefficient(G)
-0.7500000000000001

2、基准和资源库 Benchmark and Repositories

现在,我们已经理解了关于图和网络分析的基本概念和概念,现在是时候深入研究一些实际的示例了,这些示例将帮助我们开始将到目前为止所学的一般概念付诸实践。在本节中,我们将介绍一些通常用于研究网络特性的示例和简单问题,以及网络算法的基准性能和有效性。 我们还将提供一些有用的资源库链接,可以找到和下载网络数据集,以及一些关于如何分析和处理的技巧。

%matplotlib inline
from matplotlib import pyplot as plt
import networkx as nx
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

default_edge_color = 'gray'
default_node_color = '#407cc9'
enhanced_node_color = '#f5b042'
enhanced_edge_color = '#cc2f04'
import os
output_dir = "./figures"
def draw_graph(G, node_names={}, filename=None, node_size=50, layout = None):
    pos_nodes = nx.spring_layout(G) if layout is None else layout(G)
    nx.draw(G, pos_nodes, with_labels=False, node_size=node_size, edge_color='gray')
  
    pos_attrs = {}
    for node, coords in pos_nodes.items():
        pos_attrs[node] = (coords[0], coords[1] + 0.08)
  
    nx.draw_networkx_labels(G, pos_attrs, labels=node_names, font_family='serif')
  
    plt.axis('off')
    axis = plt.gca()
    axis.set_xlim([1.2*x for x in axis.get_xlim()])
    axis.set_ylim([1.2*y for y in axis.get_ylim()])
  
    if filename:
        plt.savefig(os.path.join(output_dir, filename), format="png")


# draw enhanced path on the graph
def draw_enhanced_path(G, path_to_enhance, node_names={}, filename=None, layout=None):
    path_edges = list(zip(path,path[1:]))
    pos_nodes = nx.spring_layout(G) if layout is None else layout(G)
    
    plt.figure(figsize=(5,5),dpi=300)
    pos_nodes = nx.spring_layout(G)
    nx.draw(G, pos_nodes, with_labels=False, node_size=50, edge_color='gray')
  
    pos_attrs = {}
    for node, coords in pos_nodes.items():
        pos_attrs[node] = (coords[0], coords[1] + 0.08)
  
    nx.draw_networkx_labels(G, pos_attrs, labels=node_names, font_family='serif')
    nx.draw_networkx_edges(G,pos_nodes,edgelist=path_edges, edge_color='#cc2f04', style='dashed', width=2.0)
  
    plt.axis('off')
    axis = plt.gca()
    axis.set_xlim([1.2*x for x in axis.get_xlim()])
    axis.set_ylim([1.2*y for y in axis.get_ylim()])
  
    if filename:
        plt.savefig(os.path.join(output_dir, filename), format="png")

2.1 简单图的例子

我们从一些非常简单的网络例子开始。networkx已经提供了一些已经实现的图形,可以随时使用和使用。

让我们先创建一个完全连通的无向图,如下所示:

complete = nx.complete_graph(n=7)

完全连通无向图共有 n ( n − 1 ) 2 \frac{n(n-1)}{2} 2n(n1)条边吗,聚类系数 C = 1 C=1 C=1。尽管完全连通图本身并不是很有趣,但它们代表了可能出现在更大的图中的基本构建块。

在一个较大的图中,包含n个节点的全连通子图通常称为大小为n的团(clique)

定义 无向图中的团(clique) C C C 定义为其顶点的子集,即 $C \subseteq V $,使得子集中每两个不同的顶点相邻。这可以视作,团C是图G的一个完全子图。

团是图论中的一个基本概念,也常用于需要对关系进行编码的数学问题中。此外,在构造更复杂的图时,它们也代表了最简单的单元。另一方面,在较大的图中寻找给定大小n的团的任务(团问题)是非常有趣的,可以证明它是计算机科学中经常研究的一个不确定多项式时间完备(np-完备) 问题。

其他一些简单的networkx 图如下:

  • 棒棒糖图(lollipop graph) 由一个大小为n的团和一个m个节点的分枝组成。
  • 哑铃图(barbell graph) 由两个大小为m1和m2的团由一个节点的分支连接而成的,它类似于我们之前用来描述一些全局和局部性质的样本图。
lollipop = nx.lollipop_graph(m=7, n=3)
barbell = nx.barbell_graph(m1=7, m2=4)
plt.figure(figsize=(15,6))
plt.subplot(1,3,1)
draw_graph(complete)
plt.title("Complete")
plt.subplot(1,3,2)
plt.title("Lollipop")
draw_graph(lollipop)
plt.subplot(1,3,3)
plt.title("Barbell")
draw_graph(barbell)
plt.savefig(os.path.join(output_dir, "SimpleGraphs.png"))

在这里插入图片描述

#重新标记图的节点。
complete = nx.relabel_nodes(nx.complete_graph(n=7), lambda x: x + 0) 
lollipop = nx.relabel_nodes(nx.lollipop_graph(m=7, n=3), lambda x: x+100)
barbell = nx.relabel_nodes(nx.barbell_graph(m1=7, m2=4), lambda x: x+200)

这些简单的图形是基本的构建块,可以通过组合它们来生成更复杂的网络。使用networkx合并子图非常容易,只需几行代码就可以完成,如下代码片段所示,其中三个图被合并到一个单独的图中,并加入一些随机边来连接它们:

def get_random_node(graph):
    return np.random.choice(graph.nodes)
allGraphs = nx.compose_all([complete, barbell, lollipop])
allGraphs.add_edge(get_random_node(lollipop), get_random_node(lollipop))
allGraphs.add_edge(get_random_node(complete), get_random_node(barbell))

在这里插入图片描述
其他简单的图(可以合并和使用)也可以参考 https://networkx.org/documentation/stable/reference/generators.html#module-networkx.generators.classic

2.2 生成图模型 Generative graph models

尽管创建简单的子图并将它们合并是生成越来越复杂的新图的一种方法,但网络也可以通过概率模型(probabilistic models) 和/或 ** 生成模型(generative models)**来生成,从而让图自行增长。这些图通常与真实网络共享有趣的属性,并且长期以来一直被用于创建基准和合成图,特别是在可用数据量不像今天这样庞大的时候。在这里,我们展示了一些随机生成图的例子,简要地描述了它们背后的模型。

Watts and Strogatz (1998)

这个模型被作者用来研究小世界网络(small-world networks) 的行为——也就是说,在某种程度上类似于普通社会网络的网络。图的生成是首先置换环中的n个节点,并将每个节点与它的k个邻居连接起来。这样一个图的每条边被重新连接到一个随机选择的节点的概率是p。通过p的范围,Watts和Strogatz模型允许从一个规则网络(p=0)转变为一个完全随机网络(p=1)。在这两者之间,图表展示了小世界特征;也就是说,他们倾向于将这种模式带向社会。 这些图可以很容易地用下面的命令创建:

graph = nx.watts_strogatz_graph(n=20, k=5, p=0.2)

Barabási-Albert (1999)

Albert和Barabási提出的模型是基于生成模型,允许通过使用优惠附件模式创建随机的无标度网络,在一个网络是由逐步添加新的节点,并将它们附加到现有的节点,与偏爱节点拥有更多的邻居。从数学上讲,该模型的基本思想是,一个新节点附着在现有节点i上的概率取决于第i个节点的度,公式如下:

p i = k i ∑ k i p_i = \frac{k_i}{\sum{k_i}} pi=kiki

因此,边缘数量较多的节点(枢纽)倾向于发展更多的边缘,而链接较少的节点则不会发展其他链接(外围)。由该模型生成的网络显示出节点之间的连通性(即度)的幂律分布。这种行为在真实的网络中也存在(例如万维网(WWW)网络和行动者协作网络),有趣的是,影响新连接创建的是节点的受欢迎程度(它已经有多少边),而不是节点的固有属性。最初的模型随后被扩展(这是networkx上可用的版本),也允许优先连接新边或重新连接现有边。

最初的模型随后被扩展(这是networkx上可用的版本),也允许优先连接新边或重新连接现有边。

BA_graph_small = nx.extended_barabasi_albert_graph(n=20,m=1,p=0,q=0)
draw_graph(BA_graph_small, layout=nx.circular_layout)

在这里插入图片描述
我们展示了一个针对小型网络的Barabasi-Albert模型的例子,在这个例子中,你已经可以观察到枢纽的出现(如左图所示),以及节点度的概率分布,它表现出无标度幂律行为(如右图所示)。networkx代码如下所示:

n = 1E5
bag = nx.extended_barabasi_albert_graph(n,m=1,p=0,q=0)
degree = dict(nx.degree(bag)).values()
bins = np.round(np.logspace(np.log10(min(degree)), np.log10(max(degree)), 10))
from collections import Counter
cnt = Counter(np.digitize(np.array(list(degree)), bins))
plt.figure(figsize=(15,6))
plt.subplot(1,2,1)
draw_graph(BA_graph_small, layout=nx.circular_layout)
plt.subplot(1,2,2)
x, y = list(zip(*[(bins[k-1], v/n) for k, v in cnt.items()]))
plt.plot(x, y, 'o'); plt.xscale("log"); plt.yscale("log")
plt.xlabel("Degree k")
plt.ylabel("P(k)")
plt.savefig(os.path.join(output_dir, "Barabasi_Albert.png"))

在这里插入图片描述

plt.figure(figsize=(15, 6))
plt.hist(degree, bins=bins)
plt.xscale("log")
plt.yscale("log")

在这里插入图片描述


总结

在本章中,我们介绍了一些基本的机器学习概念,并介绍如何将它们应用到图上。我们定义了基本的图机器学习术语,特别是图表示学习 。我们也介绍了一些主流的图机器学习算法的分类。最后,提供了实际的例子,以开始理解如何将理论应用于实际问题。

在下一章中,我们将回顾主要的基于图的机器学习算法。我们将分析他们的特点,并看看他们如何在实践中使用。

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值