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 件のコメント:
コメントを投稿