这些问题会在接下来的多个notebook中逐一探索,首先,本notebook将演练使用networkx画社会网络分析图。然后在接下来的notebook中演练对图的化简,分别根据边权重化简和利用MST算法化简。
2使用方法
操作顺序是:
3修改历史
2022-08-18:第一版发布
本notebook是GooSeeker大数据分析团队开发的,所分析的源数据是GooSeeker分词和文本分析软件生成的,本notebook中的代码可自由共享使用,包括转发、复制、修改、用于其他项目中。
5准备运行环境
5.1引入需要用到的库
#-*-coding:utf-8-*-
importos
importnumpyasnp
importpandasaspd
importnetworkxasnx
importmatplotlib.pyplotasplt
importpylab
%xmodeVerbose
importwarnings
#软件包之间配套时可能会使用过时的接口,把这类告警忽略掉可以让输出信息简练一些
warnings.filterwarnings("ignore",category=DeprecationWarning)
#把RuntimeWarning忽略掉,不然画图的时候有太多告警了
warnings.filterwarnings("ignore",category=RuntimeWarning)
5.2设置中文字体
因为含有中文,pyplot画图有可能会显示下面的错误信息:
C:\ProgramData\Anaconda3\lib\site-packages\matplotlib\backends\backend_agg.py:238:RuntimeWarning:Glyph32993missingfromcurrentfont.font.set_text(s,0.0,flags=flags)
#plt.rcParams['font.sans-serif']=['SimHei']
#上面一行在macOS上没有效果,所以,使用下面的字体
plt.rcParams['font.sans-serif']=['ArialUnicodeMS']
plt.rcParams['axes.unicode_minus']=False
5.3常量和配置
在我们发布的一系列JupyterNotebook中,凡是处理GooSeeker分词软件导出的结果文件的,都给各种导出文件起了固定的名字。为了方便大家使用,只要把导出文件放在data/raw文件夹,notebook就会找到导出文件,赋值给对应的文件名变量。下面罗列了可能用到的文件名变量:
pd.set_option('display.width',1000)#设置字符显示宽度
pd.set_option('display.max_rows',None)#设置显示最大
#np.set_printoptions(threshold=np.inf)#threshold指定超过多少使用省略号,np.inf代表无限大
#存原始数据的目录
raw_data_dir=os.path.join(os.getcwd(),'../../data/raw')
#存处理后的数据的目录
processed_data_dir=os.path.join(os.getcwd(),'../../data/processed')
filename_temp=pd.Series(['词频','分词效果','选词矩阵','选词匹配','选词结果','共词矩阵'])
file_all_word=''
file_seg_effect=''
file_word_occurrence_matrix=''
file_word_frequency_matrix=''
file_word_document_match=''
file_chosen_word=''
file_co_word_matrix=''
5.4检测data\raw目录下是否有GooSeeker分词结果表
在本notebook只使用共词矩阵表,下面的代码将检查data/raw中有没有这个表,如果没有会报错,后面的程序就没法执行了。
#0:'词频',1:'分词效果',2:'选词矩阵',3:'选词匹配',4:'选词结果',5:'共词矩阵'
print(raw_data_dir+'\r\n')
foritem_filenameinos.listdir(raw_data_dir):
iffilename_temp[5]initem_filename:
file_co_word_matrix=item_filename
continue
iffile_co_word_matrix:
print("共词矩阵表:","data/raw/",file_co_word_matrix)
else:
print("共词矩阵表:不存在")
输出结果像这样:
C:\Users\work\workspace_219\notebook\发布-二舅\用networkx和python编程可视化分析共词关系图\notebook\eda\../../data/raw
共词矩阵表:data/raw/共词矩阵-知乎-二舅.xlsx
6读取共词矩阵表并存入矩阵
6.1用pandasdataframe读入共词矩阵
df_co_word_matrix=pd.read_excel(os.path.join(raw_data_dir,file_co_word_matrix))
df_co_word_matrix.head(2)
6.2提取字段名
将用于给graph的node命名
coword_names=df_co_word_matrix.columns.values[1:]
print("Thereare",len(coword_names),"words")
coword_names
输出结果:
Thereare133words
array(['世界','二舅','现实','时候','故事','人生','事情','苦难','精神','底层','内耗',
'时代','人民','视频','社会','人们','问题','母亲','普通人','国家','农村','作者',
'年轻人','价值','意义','一生','经历','感觉','方式','大学','房子','年代','条件',
'能量','医生','老师','办法','大众','电影','鸡汤','机会','压力','父母','穷人',
'小镇','角度','悲剧','收入','关系','内容','视角','老人','内心','环境','流量',
'情况','情绪','文案','目的','观点','人类','农民','资本','个体','励志','代表',
'平台','文艺创作','分钟','经济','想法','朋友','心理','群众','人物','日子','资源',
'思想','历史','残疾人','文艺','编剧','木匠','过程','生命','身体','状态','艺术',
'政府','物质','人人','医疗','村子','文学','热度','心态','网友','周劼','机制',
'宁宁','外甥','兴趣','主流','公子','父亲','官方','文艺作品','好人','源泉','公寓',
'彭叔'],dtype=object)
6.3生成矩阵数据结构
#使用astype函数对数据类型进行转换,否则,下面画图的时候可能会报错
array_co_word_matrix=df_co_word_matrix.values[:,1:].astype(float)
array_co_word_matrix
array([[101.,74.,24.,...,1.,1.,1.],
[74.,403.,59.,...,5.,1.,1.],
[24.,59.,76.,...,1.,1.,1.],
...,
[1.,5.,1.,...,7.,0.,0.],
[1.,1.,1.,...,0.,1.,0.],
[1.,1.,1.,...,0.,0.,1.]])
统计一下词语数量看看:
word_num=len(array_co_word_matrix)
word_num
输出结果:133
7生成图并进行探索
7.1从NumPy数组生成networkx图
#graph_co_word_df=nx.from_pandas_adjacency(df_co_word_matrix)
graph_co_word_matrix=nx.from_numpy_array(array_co_word_matrix)
print(nx.info(graph_co_word_matrix))
#graph_co_word_matrix.edges(data=True)
Name:
Type:Graph
Numberofnodes:133
Numberofedges:7843
Averagedegree:117.9398
7.2给node加上label
如果不加label,画出来的图上的每个节点只是一个编号,加上label可以看到节点对应的词。
coword_labels=nx.get_node_attributes(graph_co_word_matrix,'labels')
coword_labels
{}
foridx,nodeinenumerate(graph_co_word_matrix.nodes()):
print("idx=",idx,";node=",node)
coword_labels[node]=coword_names[idx]
graph_co_word_matrix=nx.relabel_nodes(graph_co_word_matrix,coword_labels)
sorted(graph_co_word_matrix)
7.3画图
#方案1:用pylab画图
#pos=nx.shell_layout(graph_co_word_matrix)
#nx.draw(graph_co_word_matrix,pos,with_labels=True,node_color='white',edge_color='grey',node_size=1200,alpha=1)
#pylab.title('co-wordmatrix',fontsize=25)
#pylab.show()
#方案2
#pos=nx.circular_layout(maximum_tree)
pos=nx.spring_layout(graph_co_word_matrix)
plt.figure(1,figsize=(30,30))
nx.draw(graph_co_word_matrix,pos,node_size=10,with_labels=True,font_size=22,font_color="red")
#nx.draw(graph_co_word_matrix,pos,with_labels=True)
#nx.draw_networkx_labels(graph_co_word_matrix,pos,labels)
plt.show()
8点度中心性分析
上面画的图糊成了一片,改进方向可以有这些
8.1定义一个公共画图函数
defdiplay_graph_degree(G):
seq_degree=sorted((dforn,dinG.degree()),reverse=True)
dmax=max(seq_degree)
fig=plt.figure("Degreeofthecountgraph",figsize=(8,8))
#Createagridspecforaddingsubplotsofdifferentsizes
axgrid=fig.add_gridspec(5,4)
ax0=fig.add_subplot(axgrid[0:3,:])
Gcc=G.subgraph(sorted(nx.connected_components(G),key=len,reverse=True)[0])
pos=nx.spring_layout(Gcc,seed=10396953)
nx.draw_networkx_nodes(Gcc,pos,ax=ax0,node_size=20)
nx.draw_networkx_edges(Gcc,pos,ax=ax0,alpha=0.4)
ax0.set_title("ConnectedcomponentsofG")
ax0.set_axis_off()
ax1=fig.add_subplot(axgrid[3:,:2])
ax1.plot(seq_degree,"b-",marker="o")
ax1.set_title("DegreeRankPlot")
ax1.set_ylabel("Degree")
ax1.set_xlabel("Rank")
ax2=fig.add_subplot(axgrid[3:,2:])
ax2.bar(*np.unique(seq_degree,return_counts=True))
ax2.set_title("Degreehistogram")
ax2.set_xlabel("Degree")
ax2.set_ylabel("#ofNodes")
fig.tight_layout()
8.2对点度中心性排序
观察哪些词是中心词。可以看到,由于数据集中的每个文档都比较长,共现的机会很高,所以,点度中心性很近似,前面的这些基本上都是全连接。
sorted(graph_co_word_matrix.degree(),key=lambdax:x[1],reverse=True)
8.3综合展示点度中心性
因为图的密度很高,用这个新定义的画图函数依然显示一片黑,但是还有两个图值得注意,实际上这两个图展示了相同内容,只是展示的角度不同,从这两个图可以看到具有某个点度的节点数量。