实验十五:社会科学问题研究的计算实践
1.实验目标及要求
(1)掌握网络视角
(2)掌握社会网络基础内容
(3)掌握友谊悖论
2.实验主要内容
随机生成一次符合社会网络特征的网络,通过计算其中友谊悖论现象出现的占比,考察友谊悖论是否算得上一个规律
3.实验前进行一轮测试,验证代码准确度
以n=10,r=4,p=0.5
为基础测试一轮的数据:
[[0 0 1 0 0 0 1 1 1 1]
[0 0 1 0 0 0 1 0 0 0]
[1 1 0 0 1 1 1 0 0 1]
[0 0 0 0 1 1 0 0 0 1]
[0 0 1 1 0 1 1 0 0 0]
[0 0 1 1 1 0 0 0 0 1]
[1 1 1 0 1 0 0 1 0 0]
[1 0 0 0 0 0 1 0 1 0]
[1 0 0 0 0 0 0 1 0 1]
[1 0 1 1 0 1 0 0 1 0]]
5 4.4
2 5.5
6 4.166666666666667
3 4.333333333333333
4 4.5
4 4.5
5 4.0
3 4.333333333333333
3 4.333333333333333
5 4.2
满足的区间: 0.6
保存到数组的索引值: 6
友谊悖论数组: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
友谊悖论字典: {'[0,0.1)': 0, '[0.1,0.2)': 0, '[0.2,0.3)': 0, '[0.3,0.4)': 0, '[0.4,0.5)': 0, '[0.5,0.6)': 0, '[0.6,0.7)': 1, '[0.7,0.8)': 0, '[0.8,0.9)': 0, '[0.9,1.0]': 0}
4.实验代码及其输出结果
代码部分:
import random
import networkx as nx
import numpy as np
# 统计友谊悖论表
stats_dit={"[0,0.1)":0,"[0.1,0.2)":0,"[0.2,0.3)":0,"[0.3,0.4)":0,"[0.4,0.5)":0,"[0.5,0.6)":0,"[0.6,0.7)":0,"[0.7,0.8)":0,"[0.8,0.9)":0,"[0.9,1.0]":0}
stats_list=[0,0,0,0,0,0,0,0,0,0]
# 进行100次测试
for data in range(100):
# 随机生成[50~1000]个节点,每个节点有[4~10]个邻居,结点边的 随机化重连的概率为(0~1)的图
n=random.randint(50,1000)
if n%2==1:
n+=1
r=random.randint(4,10)
p=random.random()
ws = nx.watts_strogatz_graph(n, r, p)
np.set_printoptions(threshold=np.inf)
# 图转邻接矩阵
a = nx.to_numpy_matrix(ws)
a=np.array(a).astype('int64')
# 按顺序保存当前结点的度
new_deg=[]
for i in range(n):
new_deg.append(a[i].sum())
# 统计符合友谊悖论的结点数
friendship=0
# 找出符合悖论的结点,放到合适的区间中
for i in range(n):
# 保存当前节点所在行的数据
new_row_deg = []
# 保存当前结点的所有相邻节点的度
neigh_deg=[]
for j in range(n):
new_row_deg.append(a[i][j])
# 遍历当前行数据,找到=1的位置,证明是当前结点的相邻节点
for k in range(n):
# 将相邻节点的度保存
if new_row_deg[k]==1:
neigh_deg.append(new_deg[k])
# 计算并保存相邻结点的平均度
neigh_deg_num=np.array(neigh_deg).sum()/len(neigh_deg)
# 当前结点度小于相邻结点平均度则 friendship+1
if new_deg[i]<neigh_deg_num:
friendship+=1
# 确定满足友谊悖论的区间
stats_range=friendship/n
# 计算在数组中对应的位置
stats=int(stats_range*10%10)
stats_list[stats]+=1
# 保存字典的键
stats_dit_keys=[]
for i in stats_dit:
stats_dit_keys.append(i)
# 将数组数据保存到字典中
for i in range(10):
stats_dit[stats_dit_keys[i]]=stats_list[i]
# 输出统计表数据
print("统计表数据:",stats_dit)
输出结果:
统计表数据: {'[0,0.1)': 0, '[0.1,0.2)': 1, '[0.2,0.3)': 1, '[0.3,0.4)': 2, '[0.4,0.5)': 4, '[0.5,0.6)': 71, '[0.6,0.7)': 21, '[0.7,0.8)': 0, '[0.8,0.9)': 0, '[0.9,1.0]': 0}
5.结果验证和心得体会
根据实验结果可知,在100
次友谊悖论结果验证中,友谊悖论现象出现占比在0.5
以上的有92
次,可以得到这个友谊悖论说法算得上是一个规律。经过此次实验,感受到了调用python库的方便之处,直接使用networkx模块
,传入结点数,结点度数,结点边的随机化重连概率直接可以生成一个关系图,再使用networkx模块
的内置函数将关系图转变成邻接矩阵,很是方便快捷。对于求邻接矩阵平均度的问题,我是想先求出每个结点的的度,存在一个列表中。找每一行中等于1的结点就为当前结点的相邻节点,去存结点度的列表中找每个相邻结点对应的度,求和算出平均度数。再将当前结点度和平均度进行比较,如果当前结点度小于相邻节点平均度,则该结点符合友谊悖论,则加1,最后用符合友谊悖论的结点数除以当前关系网的总结点数就为该关系网内结点的友谊悖论的占比。这就是我对于此次实验的思路,不知道是否有错误的地方,代码应该也能进一步优化,后续会找找可以优化的地方。此次实验也让我了解到了关于网络视角的概念,网络就是实体及其实体之间的关系,可以应用到现实生活的很多地方,也了解了友谊悖论理论,看来是一个普遍存在的理论了,但占比大多数也是在该关系网的0.5~0.7
之间。