1.目标及步骤
- 步骤1:网上搜索实证网络;
- 步骤2:将收集的实证网络可视化(工具推荐:python+networkx);
- 步骤3:计算所收集到的网络性质(包括:度分布,聚类系数,网络直径,度关联性,权重分析)
- 步骤4: 分析
数据集说明:本项目数据源自2021年美赛数学建模D题所给予数据集的influence_data.csv。【 因为这个项目的目标是实证网络,所以我选取了其中的一份数据,这是一份42770*8的数据,,此数据描述的是一定时期内,各个音乐流派中的音乐家的追随关系,由于音乐家的追随方向实际上是影响一个音乐流派的发展方向,对此我们可以搭建网络探究各个音乐流派之间发展的影响】
2.理论基础 - 网络性质
2.1度分布
2.1.1性质
度(degree)是指网络(图)中一个点的与其他点的连接数量,度分布(Degree Distribution)就是整个网络中,各个点的度数量的概率分布。例如: 度分布P(k)是指,网络中度为k的节点的出现概率;对于有向图来说又分为入度分布和出度分布。如果网络中总共有n个节点,其中有nk个度为k的节点,那么
定义P(k)为网络中度为k的节点在整个网络中所占的比率
2.1.2数值/结果分析
- 规则网络:由于每个节点具有相同的度,所以其度分布集中在一个单一尖峰上,是一种Delta分布。
- 完全随机网络:度分布具有Poisson分布的形式,每一条边的出现概率是相等的,大多数节点的度是基本相同的,并接近于网络平均度<k>,远离峰值<k>,度分布则按指数形式急剧下降。把这类网络称为均匀网络
- 无标度网络:具有幂指数形式的度分布:P(k)∝k?γ 。 ?指数度分布网络: P(k)∝e?k/к,式中к>0为一常数
2.1.3代码
import matplotlib.pyplot as plt
import networkx as nx
import numpy as np
adj = np.loadtxt('adj.txt', dtype=np.int)
G = nx.from_numpy_matrix(adj)
degree = nx.degree_histogram(G)
x = range(len(degree))
y = [z / float(sum(degree)) for z in degree]
plt.ylabel("Frequency", size=14)
plt.xticks(fontproperties='Times New Roman', size=13)
plt.yticks(fontproperties='Times New Roman', size=13)
plt.loglog(x, y, '.')
plt.show()
2.2聚类系数
2.2.1性质 - 无向网络
假设节点vi与ki个节点直接连接,那么对于无向网络来说,这ki个节点间可能存在的最大边数为ki(ki-1)/2,而实际存在的边数为Mi,由此我们定义节点vi的集聚系数为
2.2.2性质 - 有向网络
对于有向网络来说,这ki个节点间可能存在的最大弧数为ki(ki-1),此时vi的集聚系数为
将该集聚系数对整个网络作平均,可得网络的平均集聚系数为
2.2.3结果分析
显然,0≤C≤1。 C=0:所有节点都是孤立节点,没有边连接。 C=1:网络为所有节点两两之间都有边连接的完全图
2.2.4代码
2.3网络直径
2.3.1性质
网络直径:网络的直径D定义为所有距离dij中的最大值,指网络中任意两个节点间距离的最大值,一般用链路数来度量,即
2.3.2代码
2.4度关联性
2.4.1性质
度中心性分为节点度中心性和网络度中心性。前者指的是节点在其与之直接相连的邻居节点当中的中心程度,而后者则侧重节点在整个网络的中心程度,表征的是整个网络的集中或集权程度,即整个网络围绕一个节点或一组节点来组织运行的程度。节点vi的度中心性CD(vi)定义为
在所有含N节点的网络中,假设网络Goptimal使得下式达到最大值
式中,ui为网络Goptimal的各个节点,u max表示网络Goptimal中拥有最大度中心性的节点
2.4.2结果分析
是整个网络的集中或集权程度,即整个网络围绕一个节点或一组节点来组织运行的程度
2.4.3代码
3.实证网络过程
3.1数据来源
本项目数据源自2021年美赛数学建模D题所给予数据集的influence_data.csv,此数据描述的是一定时期内,各个音乐流派中的音乐家的追随关系,由于音乐家的追随方向实际上是影响一个音乐流派的发展方向,对此我们可以搭建网络探究各个音乐流派之间发展的影响。流派数据大小为42771*8(42771含列名influencer_id、influencer_name、influencer_main_genre、influencer_active_start、follower_id、follower_name、follower_main_genre、follower_active_start)
表1 字段描述 字段名称 字段类型 字段说明 influencer_id 整型 影响者唯一编号 influencer_name 字符型 影响者音乐家姓名 influencer_main_genre 字符型 影响者所在流派 influencer_active_start 字符型 影响者出道时间 follower_id 整型 追随者唯一编号 follower_name 字符型 追随者音乐家姓名 follower_main_genre 字符型 追随者所在流派 follower_active_start 字符型 追随者出道时间
3.2数据处理
3.2.1获取音乐流派类型
获取音乐流派类型作为网络节点,创建数组k用来存储音乐类型,挨行遍历42770行,如果是k数组中没有的音乐流派数据类型,就追加数组,否则就舍弃,从而达到获取不同的音乐类型效果
代码👇
为避免后续每运行一次代码都跑一边类型,所以存储音乐流派类型👇
3.2.2无向图绘制
网络的初步搭建,依据音乐流派类型作为节点,循环遍历每个节点作为边 代码👇
结果 👇 *
3.2.3获取有向边权重
创建全零的二维数组weight,当我判断每一行的键是由哪两个流派所影响存在时,进行权重的累计并存储,其中可利用excel进行验证 代码👇
结果👇
验证👇
存储后的权重读取代码👇
3.2.4绘制有向图
根据节点、权重可视化绘制有向图 代码👇
结果👇
3.3指标分析
3.3.1度分布
由于本实证网络是有向完全图,是符合规则网络【由于每个节点具有相同的度,所以其度分布集中在一个单一尖峰上,是一种Delta分布】 代码👇
结果👇
3.3.2网络直径
指网络中任意两个节点间距离的最大值,一般用链路数来度量,因为是完全图,所以每两个节点都相连,所以网络直径为1 代码👇
结果👇
3.3.3度中心性
每一个节点的度中心性均相等 代码👇
结果👇
3.3.4度聚类系数
C=1:网络为所有节点两两之间都有边连接的完全图 代码👇
结果👇
3.3.5权重以及入度分析
线越宽代表联系越紧密,点越大表示出现的次数越多 代码👇
结果👇 Pop/rock影响力大 Pop/Rock与R&B强关联
4.完整代码
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
file = "influence_data.csv"
influence=pd.read_csv(file,sep=',',encoding='utf-8')
influencer_genre=influence['influencer_main_genre'].values
follower_genre=influence['follower_main_genre'].values
dict={'Pop/Rock':0,'Country':0,'Classical':0,'Electronic':0,'Comedy/Spoken':0,'Easy Listening':0,'R&B;':0,'Stage & Screen':0,'Reggae':0,'Blues':0,'New Age':0,'Latin':0,'Vocal':0,'Jazz':0,'International':0,'Folk':0,'Religious':0,'Unknown':0,'Avant-Garde':0,'Children\'s':0}
keys=list(dict.keys())
weight = pd.read_csv("weight.csv", sep=',', header=None)
columns = []
for col in range(len(weight.columns)):
columns.append(col)
print (weight[0][0])
weight_plus=np.zeros([20])
G=nx.MultiDiGraph()
plt.figure(dpi=150)
for k in range(20):
for j in range(20):
G.add_weighted_edges_from([(keys[k], keys[j],weight[k][j])])
for n in range(20):
for i in range(20):
weight_plus[n] = weight[n][n]+weight[n][i]
line = '#EEAEEE #EEAEEE 0.8 0.8 0.8 0.8 #EEAEEE 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8 0.8'
colors = (line.split(' '))
nx.draw(G, edge_color='#9370DB',node_color=colors,with_labels=True,pos=nx.circular_layout(G),
node_size=[v*0.1 for v in weight_plus],
width=[float(v['weight']/200) for (r, c, v) in G.edges(data=True)])
plt.show()
print(nx.diameter(G))
print(nx.degree_centrality(G))
5. ★,°:.☆( ̄▽ ̄)/$:.°★ 。撒花撒花,噜噜啦啦~~~
|