NetworkXによるネットワークの作成と可視化

# 動画解説
この記事の内容は[私のチャンネル](https://www.youtube.com/channel/UC0UnEjW_QUMHqjvQXYJ3WhQ)の以下の動画で解説していますので，よろしければ併せてご覧ください．もし今後とも役に立ちそうであればチャンネル登録もよろしくお願いします．

<iframe width="560" height="315" src="https://www.youtube.com/embed/AC4u1PYlveU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# 世の中いろいろネットワーク
人間関係（リアルなつながり，バーチャルなつながりのどちらも），コンピュータネットワーク，インターネットなど世の中にある様々なものは**ネットワーク**で表現できます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663791/626579e9-15d6-a03c-13c8-0aa5d669a3ae.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663791/1bb06aa5-96da-80a2-57e5-503ec165f146.png)

**ネットワーク**（**グラフ**とも呼ばれます）は**頂点（ノード）**が**辺（エッジ，リンク）**で結ばれたものです．
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663791/d9312840-ad35-d476-11dd-cdef08ebea66.png)

# NetworkXでネットワーク分析
[NetworkX](https://networkx.org/)でネットワークを分析します．NetworkXはPythonベースのネットワークの分析のツールです．ネットワークでつながりを抽象化して表現することで科学的な分析が可能となります．友人関係のネットワークを分析することで，多くの人とつながっている人物を特定することが感染症の制御につながるかもしれません．NetworkXを使ったプログラムを作ることで，このようなネットワークの分析を行ってみましょう！

# ネットワークの作成と可視化
今回は手始めにネットワークの作成と可視化を行っていきましょう．以降でプログラムを順に書いていきますが，プログラム全体を書いたJupyterのファイルは[ここ](https://ux.getuploader.com/kenkyuprogram/download/8)からダウンロードできるようにしています．

## ネットワーク（グラフ）の生成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663791/2f765bf4-6ad5-3a43-3e61-dad5ee446d6b.png)

まずはこのような，ノードが3つ，リンクが3本のネットワークを作成して可視化します．これを作るには以下のように書きます．1行目の`%matplotlib inline`はJupyter上で画像を表示するためのものです（最近は書かなくても表示してくれるようになりました）．`import networkx as nx`はNetworkXをインポートしてnxという名前で使えるようにしています．次がネットワーク（グラフ）を生成している部分です．`G = nx.Graph()`と書くと空のネットワークを生成してくれますが，ここでは`G = nx.Graph([(1, 2), (2, 3), (3, 1)])`と書いてノード1と2，ノード2と3，ノード3と1をリンクでつなげたネットワークを生成します．`nx.draw()`関数にネットワークのオブジェクト`G`を渡すとネットワークを可視化してくれます．オプションで`with_labels=True`をつけてノード上に番号が表示されるようにします．

```python
%matplotlib inline
import networkx as nx # NetworkXをインポート

# ネットワーク生成
G = nx.Graph([(1, 2), (2, 3), (3, 1)])
# G = nx.Graph() # 空のグラフを作成する場合
nx.draw(G, with_labels=True) # ラベルをTrueにして番号の可視化
```

## ノードの追加
次にこのネットワークにノードを追加するには以下のように書きます．

```python
G.add_node(4)
nx.draw(G, with_labels=True)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663791/e3b853a3-9f8b-6d0a-e75e-3e3275ec4c66.png)

これでノード4が追加されましたが，まだどことも繋げていないので，孤立ノードとなっています．

## リンクの追加
このノード4をノード1と繋げるには以下のように書きます．

```python
# リンクの追加
G.add_edge(1,4)
nx.draw(G, with_labels=True)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663791/894d29ba-8c39-4ad7-8d90-cef3c00b240b.png)

## 複数のノードとリンクの追加
次に複数のノードやリンクを一気に追加してみましょう．以下のように書きます．

```python
# 複数ノードの追加
n = [5, 6, 7]
G.add_nodes_from(n)

# 複数リンクの追加
e = [(5,6), (3,7), (4,6)]
G.add_edges_from(e)

nx.draw(G, with_labels=True)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663791/0424fb45-5585-2193-b905-a72023025e57.png)


`G.add_nodes_from()`関数にリスト`[5, 6, 7]`を渡すことでノード5, 6, 7の3つが追加されました．次に複数リンクを追加するにはどのノードとどのノードを繋げるかということをタプル（例：(5, 6)）で書き，タプルのリストを`G.add_edges_from()`関数に渡すことで複数のリンクが追加されます．この例ではノード5と6，ノード3と7，ノード4と6の間にそれぞれリンクが追加されます．

## ノードとリンクの削除
最後に，ノードとリンクの削除を行います．以下のコードを実行するとノード4が削除されます．ノード4はノード1とノード6を橋渡ししているノードだったので，これが削除されることによって，ネットワークが2つの部分ネットワークに分断しました．

```python
# ノードの削除
G.remove_node(4)
nx.draw(G, with_labels=True)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663791/b557bfec-0b13-68e4-6a24-e65594ddbeb8.png)

次に以下のコードを実行することでノード1と2，ノード2と3を繋げていたリンクがそれぞれ削除されます．

```python
# 複数リンクの削除
G.remove_edges_from([(1,2), (2,3)])
nx.draw(G, with_labels=True)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663791/395a6502-49d5-7b1f-bb59-a2f84e942b27.png)

# まとめ
ネットワーク分析ができるPythonパッケージのNetworkXを用いて，今回は，ネットワークの生成と可視化を行ってみました．[次の記事](https://qiita.com/igenki/items/9309d2fee5e0ff7d529e)では，モデルからネットワークを生成する方法を解説しています．

[私のYouTubeチャンネル](https://www.youtube.com/channel/UC0UnEjW_QUMHqjvQXYJ3WhQ)では**研究で使うPython**シリーズを公開していますので，そちらも是非ご確認ください．