Pythonで共起ネットワークを作成するでは、PythonライブラリのMatplotlibとNetworkXで夏目漱石の『こころ』のテキストをもとに共起ネットワークを作成した。作成したネットワーク図は画像なので、単純に表示して見るだけなのだが、PythonライブラリのPlotlyを使うとインタラクティブな可視化ができる。
今回は、KH CoderでStack OverflowのDeveloper Surveyを可視化するで利用したStack Overflow Annual Developer Surveyのデータを使って、インタラクティブな共起ネットワークを作成する。
Windows10(1903)のWSL(Ubuntu 18.04)とJupyter Notebookを使用。
Plotlyはpipでインストールできる。
他にNetworkXとGraphvizも使う。インストールはPythonで共起ネットワークを作成するを参照。
使用するデータはStack Overflow Annual Developer Surveyで、2019年のデータ(developer_survey_2019.zip)をダウンロードして解凍し、survey_results_public.csvをJupyter Notebookの作業ディレクトリに置いておく。KH CoderでStack OverflowのDeveloper Surveyを可視化すると同じように、過去に経験のあるプログラミング言語やデータベース、フレームワークなどの開発で使われる技術に関する質問の回答結果を使用する。データクリーニングのためのコードを流用するのでsurvey_loader.pyとして保存しておく。以下は使用する質問項目。
それから、「;」区切りの回答を回答者ごとにリストにして、技術ペアごとのJaccard係数を算出する。方法はPythonで共起ネットワークを作成すると同じ関数を使用するので、Gistの全体コードをcoonetwork_sample.pyとして保存しておく。survey_loader.pyとcoonetwork_sample.pyはJupyter Notebookの作業ディレクトリに置いておく。
回答ペアごとのJaccard係数を算出したら、NetworkXとGraphvizでネットワークのノードとエッジの配置を決め、そのデータを使ってPlotlyで可視化する。NetworkXで決めたノードとエッジの配置をもとにPlotlyで可視化する方法がNetwork Graphs in Pythonにあるので、これを参考にした。コードは以下の通り。
Jupyter Notebookでコードを実行すると以下のような共起ネットワーク図が作成された。
さらに、メニューがあってズームなどができるし、マウスオーバーでテキストなどを表示できる。
今回は、KH CoderでStack OverflowのDeveloper Surveyを可視化するで利用したStack Overflow Annual Developer Surveyのデータを使って、インタラクティブな共起ネットワークを作成する。
環境
Windows10(1903)のWSL(Ubuntu 18.04)とJupyter Notebookを使用。
必要ライブラリなどのインストール
Plotlyはpipでインストールできる。
他にNetworkXとGraphvizも使う。インストールはPythonで共起ネットワークを作成するを参照。
データのクリーニングとJaccard係数の算出
使用するデータはStack Overflow Annual Developer Surveyで、2019年のデータ(developer_survey_2019.zip)をダウンロードして解凍し、survey_results_public.csvをJupyter Notebookの作業ディレクトリに置いておく。KH CoderでStack OverflowのDeveloper Surveyを可視化すると同じように、過去に経験のあるプログラミング言語やデータベース、フレームワークなどの開発で使われる技術に関する質問の回答結果を使用する。データクリーニングのためのコードを流用するのでsurvey_loader.pyとして保存しておく。以下は使用する質問項目。
- LanguageWorkedWith(プログラミング言語、スクリプト、マークアップ言語)
- DatabaseWorkedWith(データベース)
- PlatformWorkedWith(プラットフォーム)
- WebFrameWorkedWith(ウェブフレームワーク)
- MiscTechWorkedWith(その他の技術)
- DevEnviron(開発環境)
それから、「;」区切りの回答を回答者ごとにリストにして、技術ペアごとのJaccard係数を算出する。方法はPythonで共起ネットワークを作成すると同じ関数を使用するので、Gistの全体コードをcoonetwork_sample.pyとして保存しておく。survey_loader.pyとcoonetwork_sample.pyはJupyter Notebookの作業ディレクトリに置いておく。
ネットワーク図の作成
回答ペアごとのJaccard係数を算出したら、NetworkXとGraphvizでネットワークのノードとエッジの配置を決め、そのデータを使ってPlotlyで可視化する。NetworkXで決めたノードとエッジの配置をもとにPlotlyで可視化する方法がNetwork Graphs in Pythonにあるので、これを参考にした。コードは以下の通り。
import os import numpy as np import pandas as pd import networkx as nx from networkx.drawing import nx_agraph from plotly import graph_objs as go # Stack Overflow Annual Developer Surveyのデータをクリーニングする関数をインポート from survey_loader import to_df, clean_df # Jaccard係数を算出する関数をインポート from coonetwork_sample import bform2pair, pair2jaccard def build_interactive_network(G, pos, pr_values): # Plotlyで共起ネットワークを可視化 # nodeの大きさと色をページランクアルゴリズムによる重要度(pr_values)により変える # edgeデータの作成 edge_x = [] edge_y = [] for edge in G.edges(): x0, y0 = pos[edge[0]] x1, y1 = pos[edge[1]] edge_x.append(x0) edge_x.append(x1) edge_x.append(None) edge_y.append(y0) edge_y.append(y1) edge_y.append(None) edge_trace = go.Scatter( x=edge_x, y=edge_y, line=dict(width=0.5, color='#888'), hoverinfo='none', mode='lines') # nodeデータの作成 node_x = [] node_y = [] for node in G.nodes(): x, y = pos[node] node_x.append(x) node_y.append(y) node_trace = go.Scatter( x=node_x, y=node_y, text=list(G.nodes()), textposition='top center', mode='markers+text', hoverinfo='text', marker=dict( showscale=True, # colorscale options #'Greys' | 'YlGnBu' | 'Greens' | 'YlOrRd' | 'Bluered' | 'RdBu' | #'Reds' | 'Blues' | 'Picnic' | 'Rainbow' | 'Portland' | 'Jet' | #'Hot' | 'Blackbody' | 'Earth' | 'Electric' | 'Viridis' | colorscale='Rainbow', reversescale=False, color=[], size=10, colorbar=dict( thickness=15, title='Page Ranking', xanchor='left', titleside='right' ), line_width=2)) # nodeの色、サイズ、マウスオーバーしたときに表示するテキストの設定 node_adjacencies = [] node_text = [] for node, adjacencies in enumerate(G.adjacency()): # nodeに接続するedgeの数 node_adjacencies.append(len(adjacencies[1])) node_text.append('{} connection(s)'.format(len(adjacencies[1]))) node_trace.marker.color = pr_values node_trace.marker.size = [value*1000 for value in pr_values] node_trace.hovertext = node_text # ネットワーク図の可視化 fig = go.Figure(data=[edge_trace, node_trace], layout=go.Layout( showlegend=False, hovermode='closest', margin=dict(b=20,l=5,r=5,t=40), xaxis=dict(showgrid=False, zeroline=False, showticklabels=False), yaxis=dict(showgrid=False, zeroline=False, showticklabels=False)) ) fig.show() def build_network(jaccard_dict): # 回答ペアごとのJaccard係数をもとにnodeとedgeのレイアウトを決めてネットワーク図を可視化 G = nx.Graph() # 接点/単語(node)の追加 # ソートしないとネットワーク図の配置が実行ごとに変わる nodes = sorted(set([j for pair in jaccard_dict.keys() for j in pair])) G.add_nodes_from(nodes) print('Number of nodes=', G.number_of_nodes()) # 線(edge)の追加 for pair, coef in jaccard_dict.items(): G.add_edge(pair[0], pair[1], weight=coef) print('Number of edges=', G.number_of_edges()) # nodeの配置方法の指定 seed = 0 np.random.seed(seed) # k = node間反発係数 #pos = nx.spring_layout(G, k=0.3, seed=seed) # できるだけnodeが重ならないようにする(Graphvizを使う) pos = nx_agraph.graphviz_layout( G, prog='neato', args='-Goverlap="scalexy" -Gsep="+6" -Gnodesep=0.8 -Gsplines="polyline" -GpackMode="graph" -Gstart={}'.format(seed)) # ページランクアルゴリズムによる重要度 pr = nx.pagerank(G) # 共起ネットワークの可視化 build_interactive_network(G, pos, list(pr.values())) def main(): df = to_df() df = clean_df(df) df['tech'] = df[df.columns[1:]].apply(lambda row: ';'.join(row).split(';'), axis=1) print(df['tech'].head()) # Jaccard係数の計算 pair_count = bform2pair(df['tech'].tolist(), min_cnt=20) jaccard_dict = pair2jaccard(pair_count, df['tech'].tolist(), edge_th=0.4) # 共起ネットワーク作成 build_network(jaccard_dict) if __name__ == '__main__': main()
結果
Jupyter Notebookでコードを実行すると以下のような共起ネットワーク図が作成された。
さらに、メニューがあってズームなどができるし、マウスオーバーでテキストなどを表示できる。
0 件のコメント:
コメントを投稿