import networkx as nx
import matplotlib.pyplot as plt
#networkx自带的“风筝”网络图,命名为G_kite
G_kite=nx.krackhardt_kite_graph()
fig, ax1 = plt.subplots(figsize=(13, 4))#调整画布尺寸
plt.subplot(121)
nx.draw_networkx(G_kite)
#删除5-7节点对应的边,6-7节点对应的边,命名为G_kite_cut
G_kite_cut=nx.krackhardt_kite_graph()
G_kite_cut.remove_edge(5,7)
G_kite_cut.remove_edge(6,7)
plt.subplot(122)
nx.draw_networkx(G_kite_cut)
#判断是否是连通图
print('风筝网络图是否是连通图:',nx.is_connected(G_kite))
print('修剪后的风筝网络图是否是连通图:',nx.is_connected(G_kite_cut))
print('风筝网络图连通片数目:',nx.number_connected_components(G_kite))
print('修剪后的风筝网络图连通片数目:',nx.number_connected_components(G_kite_cut))
print('修剪后的风筝网络图连通片情况为:',list(nx.connected_components(G_kite_cut)))
print('修剪后的风筝网络图最大连通片为:',max(nx.connected_components(G_kite_cut), key=len))
print('风筝网络图的密度:',nx.density(G_kite))#结果为0.4
富人俱乐部系数:某一类人群形成网络的密度
度数大于k的节点的连接情况
$\text{rich club coefficient}=\frac{M_{>k}}{\frac{1}{2}N_{>k}(N_{>k}-1)}$
分子为度数大于$k$节点网络实际边数,分母为度数大于$k$节点网络可能的最大边数
网络中度值高的节点之间的连接,往往表示出比度值低的节点之间的连接更加紧密的趋势
上述定义在随机网络中也能检测出富人俱乐部现象。Colizza et al. 2006, Nature Physics 提出了标准化富人俱乐部系数。
print('风筝网络图的平均最短路径:',round(nx.average_shortest_path_length(G_kite),3))#返回图G所有节点间平均最短路径长度,保留三位小数
print('风筝网络图的直径:',nx.diameter(G_kite))#返回图G的直径(最长最短路径的长度)
# print('风筝网络图的平均最短路径:',round(nx.average_shortest_path_length(G_kite_cut),3))#报错,说明计算的是连通图的最短路径
真实的情况:
“虽然饱受议论,米尔格伦带来不少新奇的发现。经过多次改良实验,米尔格伦发现信件或包裹在人们心目中的价值是影响人们决定继续传递它的重要因素。他成功将送达率提升至35%, 以至于后来更上升为97%。”“不仅如此,米尔格伦还发现了漏斗效应, 他发现大部分的传递都是由那些极少数的明星人物完成的。在一个5%的飞行员实验中,他发现2/3成功的传递是由同一些“明星”来完成的。” 【百度百科】
不要人云亦云。大胆假设,小心求证。
Milgram实验:
https://baike.baidu.com/item/%E7%B1%B3%E5%B0%94%E6%A0%BC%E5%85%B0%E5%A7%86/10644763?fr=aladdin
Stanley Milgram与Paul Milgrom
import networkx as nx
import matplotlib.pyplot as plt
fig, ax1 = plt.subplots(figsize=(13, 4))#调整画布尺寸
plt.subplot(121)
nx.draw_networkx(G_kite)
print(G_kite[0])#获取邻居节点
print('0节点的邻节点为:',list(G_kite[0]))#将邻居节点装进一个列表中
#绘制0节点邻居形成的网络图
G_neibor0=nx.subgraph(G_kite,list(G_kite[0]))
plt.subplot(122)
nx.draw_networkx(G_neibor0,with_labels=True)
plt.show()
#获取邻节点网络的另一种方式
ego=nx.ego_graph(G_kite,0,center=False)#center参数表示是否加入中心节点,此处为0节点
nx.draw_networkx(ego,with_labels=True)
#计算风筝网络图0节点的聚类系数
print('风筝网络图中0节点的聚类系数:',round(nx.clustering(G_kite,0),3))
#计算0节点邻居形成的网络图密度
print('0节点邻居之间形成的网络图的密度:',round(nx.density(G_neibor0),3))
#计算0-9节点聚类系数
print('风筝网络图0-9节点的聚类系数依次为:',[round(i,3) for i in nx.clustering(G_kite).values()])
#计算图的平均聚类系数
print('风筝网络图的平均聚类系数:',round(nx.average_clustering(G_kite),3))
#计算图的横截性
print('风筝网络图的聚类系数:',round(nx.transitivity(G_kite),3))
#计算平均度,方法1
import pandas as pd
import numpy as np
kite_D=pd.DataFrame(G_kite.degree())#获取各个节点的度
kite_D.columns=['node','degree']#重命名列名,默认为0,1
print('风筝网络图的平均度:',np.mean(kite_D['degree']))
print('\n')
#方法2:通过info函数直接获取
print(nx.info(G_kite))
一般而言,介于二者之间$1<\alpha<2$。
大规模网络的一个通有特性是稀疏性:网络中实际存在的边数要远远小于最大可能的边数。
幂律分布
一个幂律分布的数据:数据
import pandas as pd
import matplotlib.pyplot as plt
# 读取边数据
powerlawdata=pd.read_csv('data//powerlawdata.csv')
powerlawdata.head()
plt.scatter(powerlawdata['msgcount'],powerlawdata['freq'],alpha=0.6)
plt.show()
plt.plot(powerlawdata['msgcount'],powerlawdata['freq'],alpha=0.6)
plt.show()
plt.loglog(powerlawdata['msgcount'],powerlawdata['freq'],alpha=0.6)
plt.show()
美国的财富分布可视化分析。
#绘制度分布图形的python代码
import pandas as pd
print('风筝网络图各节点的度:',G_kite.degree())
kite_D=pd.DataFrame(G_kite.degree())#将展示形式变为Dataframe
kite_D.columns=['node','degree']#重命名列名,默认为0,1
kite_D
G_club=nx.karate_club_graph()#Zachary的空手道俱乐部数据
import matplotlib.pyplot as plt
import pandas as pd
club_D=pd.DataFrame(G_club.degree())#将展示形式变为Dataframe
club_D.columns=['node','degree']#重命名列名,默认为0,1
fig, ax1 = plt.subplots(figsize=(13, 4))#调整画布尺寸
plt.subplot(121)
plt.hist(kite_D['degree'],density=True)
# 添加x轴和y轴标签
plt.xlabel('Degree')
plt.ylabel('Density')
plt.title('Degree distribution of G_kite')
plt.subplot(122)
plt.hist(club_D['degree'],density=True)
plt.xlabel('Degree')
plt.ylabel('Density')
plt.title('Degree distribution of G_club')
plt.show()# 显示图形
EAV_G=pd.DataFrame([nx.average_neighbor_degree(G_club)]).T
EAV_G1=EAV_G.reset_index().rename(columns={'index':'node',0:'AND'})#返回各个节点的余平均度(AND, Average Neighbour Degree)
Degree_G=pd.DataFrame(nx.degree(G_club))
Degree_G.columns=['node','degree']#返回各个节点的度
EAV_D=Degree_G.merge(EAV_G1)#进行组合,命名为EAV_D
#pd.concat([EAV_G1,Degree_G],axis=1)
print('各个节点的度和余平均度:')
print(EAV_D)
print('平均度为:',round(EAV_D['degree'].mean(),2),'; 平均余度为:',round(EAV_D['AND'].mean(),2))
print('各个度的余平均度:')
print(round(EAV_D.groupby('degree')['AND'].mean(),3).reset_index(name='AND'))
思考:如果换做是中位数、众数呢?
Scott Feld (1991). Why your friends have more friends than you do.
$e_{jk}$ 网络中随机选取的一条边的两个端点的度分别为$j$和$k$的概率。(就是前面讲的 $P(j,k)$)
$q_k$ 网络中随机选取的一条边的端点的度为$k$的概率。(就是前面讲的 $P(k)$)
$e_{jk}=q_jq_k\ \forall j,k$,则网络不具有相关性,否则具有相关性。(就是 $P(j,k)=P(j)P(k)$)
对$e_{jk}$可视化
print('各边节点度情况',list(nx.node_degree_xy(G_club))) #对于无向图每个边会计算两次,因为没有指定的方向(nx.node_degree_xy(G_kite)))
nx.draw_networkx(G_club,with_labels=True)
# 统计每一种节点度的组合在所有边中占的比例
G_edge=pd.DataFrame(nx.node_degree_xy(G_club))
G_edge.columns=['degree_of_node1','degree_of_node2']
G_degree=G_edge.groupby(by=['degree_of_node1','degree_of_node2']).size().reset_index(name='count')
G_degree['percentage']=round(G_degree['count']/G_degree['count'].sum(),3)
G_degree
pt = G_degree.pivot_table(index='degree_of_node1', columns='degree_of_node2', values='percentage')
import seaborn as sns
sns.set_context({"figure.figsize":(8,8)})
sns.heatmap(data=pt,cmap="RdBu_r")#色带YlGnBu
#相关性不是很明显,节点太少
print('度相关系数:',round(nx.degree_pearson_correlation_coefficient(G_club),3))
print('度同配系数:',round(nx.degree_assortativity_coefficient(G_club),3)) #归一化的相关系数
#两者等价
fig, ax1 = plt.subplots(figsize=(13, 4))#调整画布尺寸
plt.subplot(121)
G1 = nx.Graph()
G1.add_nodes_from([0, 1], color="red")
G1.add_nodes_from([2, 3,4], color="blue")
G1.add_edges_from([(0, 1), (2, 3),(3,4)])
node_color1=[G1.nodes[v]['color'] for v in G1]#获得G1中各个节点的设置值
nx.draw_networkx(G1,with_labels=True, node_color=node_color1)
plt.subplot(122)
G2 = nx.Graph()
G2.add_nodes_from([1, 3], color="red")
G2.add_nodes_from([0, 2,4], color="blue")
G2.add_edges_from([(0, 1), (2, 3),(1,4)])
node_color2=[G2.nodes[v]['color'] for v in G2]#获得G2中各个节点的设置值
nx.draw_networkx(G2,with_labels=True, node_color=node_color2)
print('第一张图属性同配系数:',round(nx.attribute_assortativity_coefficient(G1, "color"),3))
print('第二张图属性同配系数:',round(nx.attribute_assortativity_coefficient(G2, "color"),3))