YutaKa Notebook | Enjoy Python!

Python の文法やモジュール、Python関連のAPIについて画像・ソースコード付きで徹底解説!

【図解】Python NetworkXの使い方【サンプルコード有】 | ネットワーク分析・可視化

今回はpython強力なネットワーク分析ツールNetworkXを紹介します。

NetworkXを使用すると

  • ネットワーク分析
  • ネットワーク構造の可視化
  • 中心性や連結性などの解析

を行うことができます。

この記事は次のドキュメントや本を参考にしています。

興味が湧いた方はぜひこちらもチェックしてみてください!

 

ネットワーク分析の準備

基本用語の整理

まずは、ネットワーク分析に関する超基本用語を整理していきましょう。

次の4つの用語をおさえれば、簡単な可視化は可能です。

  • ネットワーク=グラフ, Graph
  • 頂点=ノード, node
  • 辺=エッジ, edge
  • 頂点の持つ辺の数=次数, degree

NetworkXのオブジェクトは英語名をもとに命名されているので、英語名を覚えた方が良いです。

環境構築

NetworkXは組み込みライブラリではないので、pipまたはcondaでインストールします。

ターミナルで次のコマンドを打ってインストールします。

pip install network
conda install network

環境構築は飛ばして、とりあえずネットワーク分析を試したい場合は、Google Colaboratoryを使用すれば、初めからインストールされているので設定不要です。

networkxのインポート

NetworkXnxという別名でインポートする慣例があるようです。

import networkx as nx

ネットワーク分析ではグラフの出力をすることもあるので、一緒にmaplotlibもインストールしておくと楽ですね。

%matplotlib inline 
# ↑jupter notebookで使用する場合のマジックコマンド
import matplotlib.pyplot as plt
import networkx as nx

ネットワーク分析・可視化の超基本形

ネットワークの可視化のためには、次の手順を踏みます。

  1. Graphオブジェクトの作成:G = nx.Graph()
  2. nodeの追加:G.add_nodes_from([node1, node2, node3,…])
  3. edgeの追加:G.add_edges_from([(node1, node2), (node2, node3), …])
  4. ネットワークの可視化:nx.draw(G, witlabels = True)

オブジェクト作成から、可視化までの基本形は次のようになります。

# Graphオブジェクトの作成
G = nx.Graph()
 
# nodeデータの追加
G.add_nodes_from(["A", "B", "C", "D", "E", "F"])
 
# edgeデータの追加
G.add_edges_from([("A", "B"), ("B", "C"), ("B", "F"),("C", "D"), ("C", "E"), ("C", "F"), ("B", "F")])
 
# ネットワークの可視化
nx.draw(G, with_labels = True)
plt.show()

これで、次のようなグラフが描けます。

以下では、このネットワークをもとに、

  • ノード、エッジ、次数の出力方法
  • ネットワーク図の装飾方法
  • ネットワークの超簡単な分析例

を紹介していきます。

基本的な特性値の出力

nx.info()関数で、Graphオブジェクトの情報をテキストで出力できます。

print(nx.info(G))
 
# Name: 
# Type: Graph
# Number of nodes: 6
# Number of edges: 6
# Average degree:   2.0000

Graphオブジェクトの情報をさっと確認したい場合には便利です。

細かい情報が欲しい場合には、以下で紹介するようなメソッドを使用します。

ノードの出力

ノードの基本出力メソッド:

  • ノードの総数:G.number_of_nodes()
  • ノードの要素:G.nodes()

出力例を見ていきます。

print("number of nodes:",G.number_of_nodes())
print("nodes:", G.nodes())
 
number of nodes: 6
nodes: ['A', 'B', 'C', 'D', 'E', 'F']

エッジの出力

エッジの基本出力メソッド:

  • エッジの総数:G.number_of_edges()
  • エッジの要素:G.edges()

出力例を見ていきます。

print("number of edges:",G.number_of_edges())
print("edges:", G.edges())
 
number of edges: 6
edges: [('A', 'B'), ('B', 'C'), ('B', 'F'), ('C', 'D'), ('C', 'E'), ('C', 'F')]

次数の出力

次数の基本出力メソッド:

  • 各ノードの次数:G.degrees()

出力例を見ていきます。

print("degrees:", G.degrees())
 
degrees: [('A', 1), ('B', 3), ('C', 4), ('D', 1), ('E', 1), ('F', 2)]

各ノードの次数が自動集計・出力されます。

ネットワーク図の見た目変更

nx.draw()メソッドにキーワード引数を設定することで、ネットワーク図の見た目を変更することができます。

ここでは、次の基本的なキーワード引数を紹介します。

  • ノード関連:
    • 色:node_color(デフォルト:'C0' 薄い青)
    • サイズ:node_size(デフォルト:300

 

  • エッジ関連:
    • 色:edge_color(デフォルト:'black' 黒)
    • 太さ:width(デフォルト:1

一括で設定(色、ノードサイズ、エッジの太さ)

キーワード引数としてシリアル値(リストでなく1つの値)を与えると、グラフ全体に適用されます。

ノードの色を"red"、エッジの色を"gray"、太さを500にしてみましょう。

nx.draw(G, with_labels=True, node_color = "red", edge_color = "gray", node_size = 500, width = 5)
plt.show()

ネットワーク図の見た目が一括で変更されていますね。

各要素で異なる設定を適用

リストで設定値を渡すことで、各ノード、エッジに異なる設定を適用できます。

各要素の順番に対応するように設定値を渡します。

次の例ではノードの各要素の色をcolorsというリストで渡しています。

colors = ["lightblue", "green", "red", "cyan", "magenta", "yellow"]
nx.draw(G, with_labels=True, node_color = colors)

同様に、node_sizeedge_colorwidthなどもリストで設定することが可能です。

ネットワークの特徴に合わせて見た目を設定すると見やすい図を作成できます

このようなネットワークの可視化については、次の本で詳しく解説されています。

この本や公式ドキュメントで、基本的な分析、可視化方法を学んでいくのがおススメです!

ネットワーク可視化例|次数に応じた配色・サイズ変更

最後に、各ノードの次数に応じて配色・サイズ変更する例を紹介します。

これまで、紹介してきた特性値の出力方法、ネットワーク図の見た目変更を組み合わせていきます。

次の図のように、

  • 各ノードの次数順の棒グラフ
  • 次数に応じたネットワーク図

を作成してみましょう。

このグラフは

  • 棒グラフとネットワークで各ノードの色が対応
  • ネットワーク図のノードのサイズが次数の数に比例

するように作成しています。

デフォルトのネットワーク図よりも視認性がだいぶ上がっています

きっと人に見せるときも、魅力的な図になりましたね!

次数に応じたネットワーク図の例

まずは、ノードの色付け、次数に応じたサイズ調整を行いましょう。

# ネットワーク全体の次数の平均値を計算
average_deg = sum(d for n, d in G.degree()) / G.number_of_nodes()
# ノードの次数に比例するようにサイズを設定
sizes = [300*deg/average_deg for node, deg in G.degree()]
print(sizes)
# [150.0, 450.0, 600.0, 150.0, 150.0, 300.0]
 
# グラフの出力
plt.figure(figsize = (10,5))
plt.subplot(121)
nx.draw(G, with_labels=True, node_color = colors, node_size = sizes, edge_color = "black")
plt.show() # ←棒グラフと並べて表示する場合は消します。

次数順の棒グラフの作成

次に各ノードの次数順の棒グラフを作成します。

# 次数の多い順番でnodeを並び替える
nodes_sorted_by_degree = sorted(G.degree(), key=lambda x: x[1], reverse=True)
print(nodes_sorted_by_degree)
# [('C', 4), ('B', 3), ('F', 2), ('A', 1), ('D', 1), ('E', 1)]
 
# 色のリストを次数順に並び替える
colors_dict = dict(zip(G.nodes(), colors))
colors_sorted = [colors_dict[node] for node, _ in nodes_sorted_by_degree]
print(colors_sorted)
# ['red', 'green', 'yellow', 'lightblue', 'cyan', 'magenta']
 
# グラフの出力
x, height = list(zip(*nodes_sorted_by_degree))
plt.subplot(122)
plt.xlabel("Number of degrees")
plt.ylabel("Name of node")
plt.barh(x, height, color = colors_sorted)
plt.show()

ネットワーク分析おススメの1冊!

pythonでネットワーク分析をしたい方には、こちらの本がおススメです。

実は私はネットワーク分析の基本どころか、NetworkXの存在すらしらなかったのですが…。

この本では

  • ネットワーク分析の流れや用語説明
  • NetworkXをサンプルコード付きで解説

されています。

私のような初学者でもすぐに簡単なネットワーク分析をできるようになりました

今回の記事では紹介しませんでしたが、本の中では

  • ネットワークの中心性を解析する方法
  • グループの分割・抽出方法

などに関しても解説されています。

ネットワーク分析の勉強にオススメな1冊でした!

おわりに

今回はネットワーク分析、NetworkXに関して紹介しました。

ネットワークを可視化すると、一気にデータが意味を持ちだすような印象を持ちます。

pythonの可視化にはmatplotlibを使用することが多いです。

今回も自然な流れでsubplotを使用していました。

matplotlibの簡単な使い方については、こちらの記事もご覧ください!

Twitter@YutaKaでは、ほぼ毎日pythonに関する情報を発信しています。

気楽にツイートしているので、気軽にフォローしてください!