怎么导入一个真实的社交网络到我的这个sir模型里面呀,不知道怎么寻找资源和导入方法。求帮助。
import networkx as nx
import matplotlib.pyplot as plt
import random
import numpy as np
#来生成一个有N个节点,连接概率为p,邻居为k的随机网络
N = 20
p = 0.25
k = 4
#er=nx.erdos_renyi_graph(N,p)
er = nx.random_graphs.watts_strogatz_graph(N,k,p)
for i in range(N):
er.nodes[i]['state'] = 'S'
edge_color = 'g'
gama = 0.5
beta = 0.1
ps= nx.spring_layout(er) #nx.spectral_layout(er)nx.circular_layout(er)nx.shell_layout(er)nx.spring_layout(er)#布置框架
colors = {"R": 'b', "I": 'r', "S": 'g'}
states= nx.get_node_attributes(er, 'state') # 获得节点的isCore属性
color=[colors[states[i]] for i in range(N)]
#nx.draw(er,ps,node_color =color ,with_labels=True,node_size=50)
nx.draw_networkx_nodes(er,ps,node_color =color ,node_size=50)
nx.draw_networkx_edges(er,ps ,width=1,arrows=True,arrowstyle='->')
plt.show()
def centrality(G):
#计算度中心性,降序
dc = nx.algorithms.centrality.degree_centrality(G)
return sorted(dc.items(), key=lambda x: x[1],reverse = True)
def betweenness(G):
#计算介数中心性,降序
dc = nx.betweenness_centrality(G)
return sorted(dc.items(), key=lambda x: x[1],reverse = True)
def closeness(G):
#计算接近中心性,降序
dc = nx.closeness_centrality(G)
return sorted(dc.items(), key=lambda x: x[1],reverse = True)
def spread(G, beta, initial, func, gamma=0):
colors = {"R": 'b', "I": 'r', "S": 'g'}
y = []
n = len(G.nodes) # 总人数
for i in range(n): # 所有人默认为易感染
G.nodes[i]['state'] = 'S'
edge_color = 'g'
arrow_color = 'g'
s = n - initial # 易感染人数
desc_dc = func(G)
i_nodes = []
# 选择前inttial个度中心性最高的节点设为感染源
for i in range(initial):
G.nodes[desc_dc[0][0]]['state'] = 'I'
i_nodes.append(desc_dc[0][0])
desc_dc.remove(desc_dc[0])
y.append(((s, (len(i_nodes)), 0)))
# 开始传播,直到所有人被传染
r_nodes = nx.Graph()
while len(i_nodes) != 0:
print(s)
# 当前轮被传染的人数
i_temp = []
# 当前恢复人数 gamma 概率
for i in i_nodes:
if random.random() < gamma:
r_nodes.add_node(i)
i_nodes.remove(i)
G.nodes[i]['state'] = 'R'
i_nodes_temp = nx.Graph()
i_nodes_temp.add_nodes_from(i_nodes)
for i in i_nodes_temp.nodes:
# 按beta概率传染I节点的邻居节点
for node in G.neighbors(i):
r = random.random()
edge_color = 'r'
if r < beta and G.nodes[node]['state'] == 'S':
G.nodes[node]['state'] = 'I'
edge_color = 'r'
arrow_color = 'r'
i_temp.append(node)
for t in i_temp:
if t not in i_nodes:
i_nodes.append(t)
s = n - len(i_nodes) - len(r_nodes.nodes)
i = len(i_nodes)
r = len(r_nodes.nodes)
y.append((s, i, r))
states = nx.get_node_attributes(G, 'state') ############ 获得节点的属性
color = [colors[states[i]] for i in range(n)]
nx.draw(G, ps, node_color=color, with_labels=True, node_size=50)
nx.draw_networkx_edges(er, ps, width=1, arrows=True, arrowstyle='->')
plt.show()
return np.array(y)
#选择度中心性最高的5个点作为感染源
result = spread(er,0.3,5,centrality,0.1)
print(result)
plt.plot(result[:,0], 'g', label='Susceptibles')
plt.plot(result[:,1], 'r', label='Infectious')
plt.plot(result[:,2], 'b', label='Recovereds')
plt.legend(loc='right')
plt.xlabel('time')
plt.ylabel('number of people')
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
要导入一个真实的社交网络到sir模型中,可以通过网络数据集或者API调用的方式获取网络数据,然后将数据转换为图形格式存储,最后可以使用networkx库进行处理和分析。
以下是一个示例代码,以导入Facebook网络为例:
1.下载数据集
在以下网址下载Facebook数据集:https://snap.stanford.edu/data/ego-Facebook.html
2.转换数据格式
Facebook数据集是文本格式,需要将其转换为适合networkx库处理的图形格式。
可以使用以下代码将数据转换为边列表格式:
edge_list = []
with open('facebook_combined.txt') as f:
for line in f:
edge = tuple(map(int, line.strip().split()))
edge_list.append(edge)
其中,'facebook_combined.txt'为下载下来的文件名称。
3.生成图形对象
可以使用以下代码将边列表转换为networkx图形对象:
import networkx as nx
G = nx.Graph()
G.add_edges_from(edge_list)
这样就生成了一个包含了Facebook网络所有节点和边的图形对象。
4.将图形对象传入sir模型中
在原来的代码中,需要将生成的网络对象er替换为Facebook网络图形对象G,即:
#er = nx.random_graphs.watts_strogatz_graph(N,k,p)
G = nx.Graph()
G.add_edges_from(edge_list)
for i in range(N):
G.nodes[i]['state'] = 'S'
edge_color = 'g'
然后就可以使用原来的代码进行模拟。
完整代码如下:
import networkx as nx
import matplotlib.pyplot as plt
import random
import numpy as np
# 下载Facebook数据集后,将数据转换为边列表
edge_list = []
with open('facebook_combined.txt') as f:
for line in f:
edge = tuple(map(int, line.strip().split()))
edge_list.append(edge)
# 生成图形对象
G = nx.Graph()
G.add_edges_from(edge_list)
N = len(G.nodes)
p = 0.25
k = 4
for i in range(N):
G.nodes[i]['state'] = 'S'
edge_color = 'g'
gama = 0.5
beta = 0.1
# 布局
ps= nx.spring_layout(G)
colors = {"R": 'b', "I": 'r', "S": 'g'}
states= nx.get_node_attributes(G, 'state')
color=[colors[states[i]] for i in range(N)]
nx.draw_networkx_nodes(G,ps,node_color=color,node_size=50)
nx.draw_networkx_edges(G,ps,width=1,arrows=True,arrowstyle='->')
plt.show()
def centrality(G):
#计算度中心性,降序
dc = nx.algorithms.centrality.degree_centrality(G)
return sorted(dc.items(), key=lambda x: x[1],reverse = True)
def betweenness(G):
#计算介数中心性,降序
dc = nx.betweenness_centrality(G)
return sorted(dc.items(), key=lambda x: x[1],reverse = True)
def closeness(G):
#计算接近中心性,降序
dc = nx.closeness_centrality(G)
return sorted(dc.items(), key=lambda x: x[1],reverse = True)
def spread(G, beta, initial, func, gamma=0):
colors = {"R": 'b', "I": 'r', "S": 'g'}
y = []
n = len(G.nodes) # 总数
for i in range(n):
G.nodes[i]['state'] = 'S'
edge_color = 'g'
s = n - initial
desc_dc = func(G)
i_nodes = []
# 选择前inttial个度中心性最高的节点设为感染源
for i in range(initial):
G.nodes[desc_dc[i][0]]['state'] = 'I'
i_nodes.append(desc_dc[i][0])
y.append(((s, (len(i_nodes)), 0)))
# 开始传播,直到所有人被传染
r_nodes = nx.Graph()
while len(i_nodes) != 0:
# 当前轮被传染的人数
i_temp = []
# 当前恢复人数 gamma 概率
for i in i_nodes:
if random.random() < gamma:
r_nodes.add_node(i)
i_nodes.remove(i)
G.nodes[i]['state'] = 'R'
i_nodes_temp = nx.Graph()
i_nodes_temp.add_nodes_from(i_nodes)
for i in i_nodes_temp.nodes:
# 按beta概率传染I节点的邻居节点
for node in G.neighbors(i):
r = random.random()
if r < beta and G.nodes[node]['state'] == 'S':
G.nodes[node]['state'] = 'I'
i_temp.append(node)
for t in i_temp:
if t not in i_nodes:
i_nodes.append(t)
s = n - len(i_nodes) - len(r_nodes.nodes)
i = len(i_nodes)
r = len(r_nodes.nodes)
y.append((s, i, r))
states = nx.get_node_attributes(G, 'state')
color = [colors[states[i]] for i in range(n)]
nx.draw_networkx_nodes(G,ps,node_color=color,node_size=50)
nx.draw_networkx_edges(G,ps,width=1,arrows=True,arrowstyle='->')
plt.show()
return np.array(y)
# 选择度中心性最高的5个点作为感染源
result = spread(G,0.3,5,centrality,0.1)
print(result)
plt.plot(result[:,0], 'g', label='Susceptibles')
plt.plot(result[:,1], 'r', label='Infectious')
plt.plot(result[:,2], 'b', label='Recovereds')
plt.legend(loc='right')
plt.xlabel('time')
plt.ylabel('number of people')
plt.show()
注意,在处理大型真实社交网络时,可能需要使用分布式计算框架,在集群上进行计算,避免计算时间过长导致的长时间等待。
如果我的回答解决了您的问题,请采纳!
[1] https://zhuanlan.zhihu.com/p/38330654
[2] https://www.cnblogs.com/thousfeet/p/10647102.html
[3] https://blog.csdn.net/bryant_meng/article/details/78570164
导入真实社交网络需要先获取数据集,可以从一些公开的数据集库中下载,如SNAP(Stanford Network Analysis Project)和KONECT(The Koblenz Network Collection)。下载后,可以将数据集保存为CSV文件或其他格式,然后在Pycharm中使用pandas库进行导入和处理。
以下是一个示例代码,假设我们已经下载了一个名为"facebook_combined.txt"的数据集,它包含了Facebook上的社交网络数据:
import pandas as pd
# 读取数据集
df = pd.read_csv('facebook_combined.txt', sep=' ', header=None, names=['source', 'target'])
# 查看数据集信息
print(df.info())
# 查看前5行数据
print(df.head())
在这个示例中,我们使用pandas的read_csv函数读取了数据集,并指定了分隔符为空格,列名为"source"和"target"。然后使用info()函数查看数据集的信息,包括行数、列数、数据类型等。最后使用head()函数查看前5行数据。
需要注意的是,导入真实社交网络数据集可能会遇到一些问题,如数据集过大导致内存不足、数据格式不规范等。在处理这些问题时,可以使用一些技巧和工具,如分块读取、数据清洗等。
首先,要导入一个真实的社交网络,需要先找到该社交网络的数据集或者API。常见的社交网络数据集有Facebook、Twitter等。可以在网上搜索相关数据集并下载或者使用API获取数据。下载下来的数据集需要进行数据清洗和处理,然后将其转换为网络结构,即节点和边的关系。可以使用Python的pandas和networkx库进行数据处理和转换。
例如,如果要导入Twitter的社交网络,可以使用Twitter的API获取用户的关注者和好友信息,然后将其转换为节点和边的关系。具体实现可以参考以下示例代码:
import tweepy
import networkx as nx
# Twitter API 参数
consumer_key = 'YOUR_CONSUMER_KEY'
consumer_secret = 'YOUR_CONSUMER_SECRET'
access_token = 'YOUR_ACCESS_TOKEN'
access_token_secret = 'YOUR_ACCESS_TOKEN_SECRET'
# 授权 Twitter API
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
# 获取用户的关注者和好友信息
api = tweepy.API(auth)
followers = api.followers_ids(screen_name='twitter_handle')
friends = api.friends_ids(screen_name='twitter_handle')
# 创建网络结构
G = nx.DiGraph()
for f in followers:
G.add_edge(f, 'twitter_handle')
for f in friends:
G.add_edge('twitter_handle', f)
# 可以对网络进行可视化
nx.draw(G)
然后,将导入的社交网络应用到sir模型中,可以使用networkx库中的spread函数进行传播模拟。具体实现可以参考以下示例代码:
import networkx as nx
# 创建社交网络
G = nx.read_edgelist('path/to/edgelist')
# 使用spread函数进行传播模拟
result = spread(G, 0.3, 5, centrality, 0.1)
print(result)
其中,spread函数是自定义的传播模拟函数,需要传入四个参数:网络结构G,传播概率beta,初始感染节点数initial,选择节点的函数func,恢复概率gamma。在函数中,会根据传播概率和选择节点的函数进行节点的传播和感染状态的更新,直到所有节点都被传染或者恢复。
需要注意的是,在导入真实社交网络时,数据集可能比较大,需要进行适当的处理和优化,否则会导致程序运行缓慢或者崩溃。同时,需要对网络结构和传播模型进行适当的调整和优化,以适应不同的数据集和应用场景。
引用chatGPT作答,要在 Pycharm 中导入真实社交网络,您需要使用相应的网络库(如 NetworkX),并从真实数据集中读取和构建网络。一种常见的方法是使用 CSV 文件,其中包含每个节点和它们之间的边的信息。
下面是一个简单的示例,演示如何从 CSV 文件中读取数据并创建 NetworkX 图:
import networkx as nx
# 从 CSV 文件中读取节点和边的数据
with open('my_social_network.csv', 'r') as f:
lines = f.readlines()
# 创建一个空图
G = nx.Graph()
# 添加节点
for line in lines:
node1, node2 = line.strip().split(',')
G.add_node(node1)
G.add_node(node2)
G.add_edge(node1, node2)
# 打印图的一些基本信息
print(nx.info(G))
在上面的代码中,my_social_network.csv 是一个包含节点和边信息的 CSV 文件。您需要将其替换为实际的数据集名称和路径。
一旦您成功创建了网络,您可以像之前一样使用 spread() 函数进行传播模拟,并在 NetworkX 中绘制图形以可视化传播过程。