ChatGPTとPythonで学ぶ NetworkX



おはこんばんちわ。今日も引き続きChatGPT先生をお迎えして、「ChatGPTとPythonで学ぶ NetworkX」というテーマで雑談したいと思います。それではChatGPT先生、よろしくお願いします。

---

### **assistant**:

はじめまして、ChatGPT先生です。よろしくお願いします。
今日はNetworkXについて学んでいきましょう。

NetworkXはPythonでネットワーク分析を行うためのパッケージで、グラフの作成、操作、解析、描画などを行うことができます。また、さまざまなタイプのネットワークやグラフ（無向、有向、多重など）の扱いが可能で、また多くの標準的なグラフ理論関数を提供します。

例えば、フレンドシップネットワーク、遺伝子相互作用ネットワークなどを分析する際に使用させていただくことが多いです。

ネットワーク分析についてもっと詳しい話をご希望であれば、ご用命を。

---

### **user**:

NetworkXで使える練習用データセットはありますか？

---

### **assistant**:

はい、NetworkXにはいくつかの練習用データセットが組み込まれています。これらのデータセットは、一部は実世界のネットワーク（例えば、空港間の飛行経路やインターネットのトポロジーなど）、他の一部は数学的に生成されたネットワーク（例えば、ランダムグラフやスケールフリーグラフなど）を表しています。

以下に一部のデータセットを挙げてみます。

- `karate_club_graph()` : Zacharyの空手クラブネットワーク。一つのクラブに所属する34人のメンバーと、それらのメンバー間の結びつきを表します。

- `erdos_renyi_graph(n, p)` : Erdős-Rényi モデルに基づいて生成されたランダムグラフ。nはノードの数、pはエッジが存在する確率を表します。

- `barabasi_albert_graph(n, m)` : Barabási-Albert モデルに基づいて生成されたスケールフリーグラフ。nはノードの数、mは新しいノードが接続する既存ノードの数を表します。

これらの関数を使って、具体的なネットワーク分析の実践を学ぶことができます。また、自分の研究やプロジェクトのために特定のタイプのネットワークを生成する際にも参考になるでしょう。

---

### **user**:

ありがとうございます。では、NetworkXで使える練習用データセットの中身を列挙するPythonコードを書いてください。

---

### **assistant**:

NetworkXで提供されているデータセットを表示する直接的な方法はありませんが、いくつかのデータセットを使ってNetworkXの操作を見てみましょう。

以下の例は、いくつかのデータセットを生成して、それぞれのネットワークのノード数とエッジ数を印刷するPythonコードです。

```python
import networkx as nx

# Zacharyの空手クラブネットワーク
KCG = nx.karate_club_graph()
print("Karate Club Graph: ", len(KCG.nodes()), "nodes, ", len(KCG.edges()), "edges")

# Erdős-Rényiモデルに基づいたランダムグラフ 
ERG = nx.erdos_renyi_graph(10, 0.3)  # ここでは10ノードと各エッジの存在確率0.3で生成
print("Erdos Renyi Graph: ", len(ERG.nodes()), "nodes, ", len(ERG.edges()), "edges")

# Barabási-Albert モデルに基づいたスケールフリーグラフ
BAG = nx.barabasi_albert_graph(10, 2)  # ここでは10ノードと各新ノードの接続数2で生成
print("Barabasi Albert Graph: ", len(BAG.nodes()), "nodes, ", len(BAG.edges()), "edges")
```

これらのコードは、それぞれの生成関数を使用して具体的なグラフを作り、その後ノードとエッジの数を表示しています。具体的なネットワーク分析を行うには、それぞれのグラフに対するさまざまな操作、ショートカットの検出、クラスタリング係数の計算、ページランクの計算などが可能です。

---

### **user**:

ありがとうございます。次の結果が得られました。

```
Karate Club Graph:  34 nodes,  78 edges
Erdos Renyi Graph:  10 nodes,  14 edges
Barabasi Albert Graph:  10 nodes,  16 edges
```

これらのネットワークを可視化することはできますか？

---

### **assistant**:

はい、NetworkXのグラフはmatplotlibを用いて簡単に可視化することができます。以下に具体的なコードを示します。

```python
import matplotlib.pyplot as plt

# Zacharyの空手クラブネットワーク
plt.figure(figsize=(6,6))
plt.title("Karate Club Graph")
nx.draw(KCG, with_labels=True)
plt.show()
```

![output_1_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/c9ac5973-fd0b-165c-4e9f-91f1c5404134.png)


```python
# Erdős-Rényiモデルに基づいたランダムグラフ
plt.figure(figsize=(6,6))
plt.title("Erdos Renyi Graph")
nx.draw(ERG, with_labels=True)
plt.show()
```

![output_1_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/d976a752-0db7-08ca-c7bf-84a472a727fe.png)


```python
# Barabási-Albert モデルに基づいたスケールフリーグラフ
plt.figure(figsize=(6,6))
plt.title("Barabasi Albert Graph")
nx.draw(BAG, with_labels=True)
plt.show()
```

![output_1_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/9bb78861-9aed-1ef2-a20f-00d27917dbda.png)


このコードはmatplotlibを使って3つのグラフをそれぞれ可視化します。それぞれのグラフは円形のレイアウトにするため、`nx.draw()`関数に各グラフを渡します。また、with_labels=Trueでノードにラベルを表示します。

このコードの結果として、グラフ構造とそれぞれのノードのつながりが視覚的に確認できます。ただし、これらのレイアウトやデザインは初期値であり、さまざまなパラメータを調整してカスタマイズすることも可能です。

---

### **user**:

NetworkXの練習用データセットとして、Karate Club Graph、Erdos Renyi Graph、Barabasi Albert Graph 以外の実世界ネットワークについてできるだけ多く列挙してください。

---

### **assistant**:

NetworkXライブラリにはいくつかの標準的な実世界データセットが組み込まれており、分析や実験のために使用することができます。

一部の有名なデータセットを以下に列挙します: 

1. `florentine_families_graph()`: フィレンツェの家族間の婚姻関係を表現したネットワーク。

2. `davis_southern_women_graph()`: Davisの南部女性クラブネットワーク。20人の女性と14の社交イベントからなるネットワークです。

3. `les_miserables_graph()`: ノードが「レ・ミゼラブル」の登場人物、エッジが共に登場する回数に基づいています。

4. `petersen_graph()`: ピーターセングラフとは、10の頂点、15の辺、それぞれの頂点の次数が3である小さな無向グラフです。グラフ理論においてよく使用されます。

5. `internet_as_graph()`: ASレベルのインターネットのトポロジを表現したネットワーク。
   
GitHubのNetworkXリポジトリにある[NetworkXのファイル](https://github.com/networkx/networkx/tree/main/networkx/generators)には様々なジェネレータが配置されています。これらは実世界のデータセットだけでなく、特定の性質を持った合成グラフの生成にも使用することができます。

ただし、これらの一部の関数はネットワークの特定のインスタンスを生成し、他の一部の関数はネットワークの特定のクラスを生成します。したがって、それらに適切なパラメータを付けて呼び出す必要があります。

なお、NetworkXはエッジリスト、隣接リスト、GEXF (Graph Exchange XML Format)、GraphML、Pickle、 LEDA等多くのフォーマットに対応していますので、それぞれのフォーマットで記述された多くの実世界ネットワークデータも簡単に取り扱い可能です。

---

### **user**:

これらのネットワークを可視化することはできますか？

---

### **assistant**:

はい、もちろんです。NetworkXで読み込んだ任意のネットワークデータは、matplotlibを用いて可視化することができます。以下にいくつかのネットワークの例を挙げます。ただしこのコードはインターネット接続が必要で、かつ時間がかかる可能性があります。

```python
import matplotlib.pyplot as plt
import networkx as nx

# Florentine Families Graph
FFG = nx.florentine_families_graph()
plt.figure(figsize=(6,6))
plt.title("Florentine Families Graph")
nx.draw(FFG, with_labels=True)
plt.show()
```

![output_2_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/e67d3ee4-30eb-7e4b-bcb2-b04d7dbf6bbd.png)


```python
# Davis Southern Women Graph
DSWG = nx.davis_southern_women_graph()
plt.figure(figsize=(6,6))
plt.title("Davis Southern Women Graph")
nx.draw(DSWG, with_labels=True)
plt.show()
```

![output_2_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/1d6a4e2b-bfff-c8a2-4e06-8b7fae78033d.png)


```python
# Les Miserables Graph
LMG = nx.les_miserables_graph()
plt.figure(figsize=(6,6))
plt.title("Les Miserables Graph")
nx.draw(LMG, with_labels=True)
plt.show()
```

![output_2_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/23b595a2-1238-302e-ee2d-787fa22e2cdb.png)


```python
# Petersen Graph
PG = nx.petersen_graph()
plt.figure(figsize=(6,6))
plt.title("Petersen Graph")
nx.draw(PG, with_labels=True)
plt.show()
```

![output_2_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/b348ad83-31d9-0d88-16d3-a8391e816ef2.png)


それぞれのネットワークをそれぞれの描画に関連付けて、それらを表示します。各ネットワークは円形のレイアウトで表示され、各ノードはそのラベルと共に表示されます。

また、有効なInternet接続があれば、`internet_as_graph()`を使ってインターネットのASレベルトポロジを表示することも可能です。ただし、このネットワークは非常に大きい（何千ものノードとエッジがあります）ので、完全な描画は時間がかかるかもしれませんし、非常に密度が高いグラフが生成される可能性があります。

これらの例は基本的な描画機能のみを示していますが、`nx.draw()`関数では各ノードの形状、色、サイズ、エッジの幅や色、フォントのプロパティなど、グラフ描画の詳細な調整が可能です。これらを調整することで、より詳細かつ視覚的に豊かなネットワーク可視化を作成することができます。

---

### **user**:

ありがとうございます。NetworkXの練習用データセットとして、Karate Club Graph、Erdos Renyi Graph、Barabasi Albert Graph、Florentine Families Graph、Davis Southern Women Graph、Les Miserables Graph、Petersen Graph 以外の実世界ネットワークについてできるだけ多く列挙してください。

---

### **assistant**:

NetworkXには、上述のもの以外にも多くの実世界のネットワークと合成ネットワークのデータが含まれています。その一部を以下に列挙します：

1. `dolphins_graph()` : ニュージーランドのドルフィン集団の社会ネットワーク。

2. `house_graph()` : 無向グラフで、隣接するノードがフツウの家（一辺が床、他の四辺が壁、一辺が屋根）を構成します。

3. `jazz_graph()` : Jazzミュージシャンのコラボレーションネットワーク。

4. `navigable_small_world_graph()` : ナビゲータブルな小世界モデルに基づくネットワーク。

5. `tutte_graph()` : Tutteグラフ。ハミルトン閉路を持つ3連結平面的な立方グラフになります。

6. `powerlaw_cluster_graph()` : ノード数、新ノードあたりのエッジ数、新しいエッジを追加する際にクラスタリングを優先する確率をパラメータとする、モデルに基づいて生成されるスケールフリーネットワークです。

これらは標準的なデータセットや生成器ですが、NetworkXはエッジリストや隣接リスト、GEXF (Graph Exchange XML Format)、GraphML、Pickle、 LEDAといった一般的なデータ形式からグラフを読み込むことができます。それらを利用すれば、他にも多くの実世界のネットワークデータを読み込んで分析することが可能です。

---

### **user**:

ありがとうございます。これらのネットワークを可視化することはできますか？

---

### **assistant**:

はい、もちろんです。それぞれのデータに対応するコードを以下に示します。

まずは必要なパッケージをインポートします。
```python
import matplotlib.pyplot as plt
import networkx as nx
```

1. Dolphins Graph
```python
plt.figure(figsize=(6,6))
DG = nx.dolphins_graph()
nx.draw(DG, with_labels=True)
plt.title("Dolphins Graph")
plt.show()
```

2. House Graph
```python
plt.figure(figsize=(6,6))
HG = nx.house_graph()
nx.draw(HG, with_labels=True)
plt.title("House Graph")
plt.show()
```

![output_4_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/d237420f-6e28-62ef-e5bd-293135c4532d.png)


3. Jazz Graph
```python
plt.figure(figsize=(6,6))
JG = nx.jazz_graph()
nx.draw(JG, with_labels=True)
plt.title("Jazz Graph")
plt.show()
```

なお、これらの画像はデフォルトの画像です。ノードの色や形、エッジの色や太さなどの属性は変更することが可能です。また、次元削減のアルゴリズムを用いてネットワークの見た目を調整することも可能です。

また、`nx.draw()`関数には様々な描画オプションがあり、ノードの大きさ、色、透明度、エッジの太さ、色、透明度などを調整することができます。それによりさらに豊かなネットワークの可視化が可能になります。

---

### **user**:

次のエラーが得らーれました。

```
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[4], line 2
      1 plt.figure(figsize=(6,6))
----> 2 DG = nx.dolphins_graph()
      3 nx.draw(DG, with_labels=True)
      4 plt.title("Dolphins Graph")

AttributeError: module 'networkx' has no attribute 'dolphins_graph'
```

```
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[6], line 2
      1 plt.figure(figsize=(6,6))
----> 2 JG = nx.jazz_graph()
      3 nx.draw(JG, with_labels=True)
      4 plt.title("Jazz Graph")

AttributeError: module 'networkx' has no attribute 'jazz_graph'
```
---

### **assistant**:

申し訳ありません、やっと問題を理解しました。私の説明が間違っていました。NetworkXには 'jazz_graph' や 'dolphins_graph' という関数は存在しません。私としても混乱を招いてしまう誤情報を提供しました。

NetworkXに直接組み込まれているデータセットは限られていますが、その一方でNetworkXは様々なデータ形式からグラフデータを導入する機能を持っています。つまり、他の多くのデータセットからグラフを作成することが可能です。そのデータセットはGML、GraphML、Pajek、UCINet、LEDAなど様々な形式をサポートしています。

'jazz_graph'や'dolphins_graph'などのデータセットは、一部のリポジトリやデータベースで公開されています。それらをダウンロードし、適切な形式でNetworkXにロードすることでグラフとして扱うことができます。ただし、これらのデータセットは個別にダウンロードし、ロードする処理を行う必要があります。

---

### **user**:

NetworkXに組み込まれていないデータセットで、フリーで使えるデータセットをご存知だったりしますか？

---

### **assistant**:

はい、以下にいくつかのグラフ形式のデータセットを提供しているウェブサイトを列挙します。

1. [Stanford Large Network Dataset Collection](http://snap.stanford.edu/data/): ソーシャルネットワーク、引用ネットワーク、ウェブグラフ、オンラインコミュニティなど幅広いネットワークデータを提供しています。

2. [UC Irvine Network Data Repository](http://networkdata.ics.uci.edu/): 異なる領域のネットワークデータを提供しています。

3. [Konect (the Koblenz Network Collection)](http://konect.uni-koblenz.de/): さまざまな種類のネットワークデータを提供しています。

4. [Gephi Datasets](https://github.com/gephi/gephi/wiki/Datasets) : Gephiはグラフ分析・可視化ソフトウェアであり、そのウェブサイトで多くのデータセットが提供されています。

これらのウェブサイトからデータセットをダウンロードし、NetworkXで適切な形式で読み込むことで、ネットワーク分析を行うことができます。
ただし、データのライセンスや使用規約は各サイトにより異なるので、利用する前に確認してください。

---

### **user**:

ありがとうございます。３つめのKonect (the Koblenz Network Collection)だけはリンクが切れているようです。

---

### **assistant**:

大変申し訳ありません。Konectは現在[Open Academic Graphs](https://oag.moe/)として提供されています。 同じように次のサイトもご参考になるかと思います:

1. [The Colorado Index of Complex Networks (ICON)](https://icon.colorado.edu/): さまざまなネットワークデータがまとめられています。

2. [GitHub上のnetzschleuder](https://github.com/netzschleuder/netzschleuder): 多くのグラフとネットワークデータセットへのリンクが記載されています。

3. [Network Repository](http://networkrepository.com/): Network Repositoryは、グラフとネットワークの研究のためのインタラクティブな科学的データリポジトリです。

ご指摘ありがとうございますし、これらのリソースがあなたの研究を支えるのに役立つことを願っています。データの利用規約やライセンスについては各ウェブサイトでご確認ください。

---

### **user**:

ありがとうございます。遺伝子相互作用ネットワークで、フリーに利用可能なものはありますか？

---

### **assistant**:

いくつかの遺伝子相互作用ネットワークのデータセットが公開されています。以下にその一部を列挙しますが、利用条件やライセンスについては各サイトでご確認ください。

1. [STRING](https://string-db.org/): 細菌、古細菌、バクテリオファージ、ユーグレナ植物、菌類、動物、ウイルスの中から2151以上の種で550,000を超えるプロテインをカバーしており、その相互作用を提供します。

2. [BioGRID](https://thebiogrid.org/): 約70種の生物種の中で、生物学的なデータとプロテインおよび遺伝子相互作用の情報を提供します。

3. [KEGG](https://www.kegg.jp/): 疾患、薬、環境情報資源のような遺伝子やプロテインのネットワーク情報を提供します。

4. [IntAct](https://www.ebi.ac.uk/intact/): プロテインの相互作用を文献から抽出したデータベース。

これらのデータベースから得られるデータを使って、NetworkXで遺伝子やプロテインのネットワーク分析を行うことが可能です。

---

### **user**:

ありがとうございます。地理データをネットワークにしたもので、フリーで利用可能なものはありますか？

---

### **assistant**:

はい、地理データを利用してネットワーク分析を行うためのデータセットもいくつか存在します。以下にその一部を列挙しますが、利用条件やライセンスについては各ウェブサイトでご確認ください。

1. [OpenStreetMap](https://www.openstreetmap.org/): OpenStreetMapは世界中の地理情報を供給しており、道路や水道などの地理的ネットワークを構築するのに使用可能です。特に、[OSMnx](https://osmnx.readthedocs.io/en/stable/)というPythonパッケージを利用すると、直接NetworkXのグラフとして地理的ネットワークを取得することができます。

2. [Natural Earth](https://www.naturalearthdata.com/): Natural Earthは世界の地図データをフリーで提供しています。政治的な境界線や河川、都市などの地理情報が含まれています。

3. [US Geological Survey](https://www.usgs.gov/): アメリカ地質調査所(USGS)は米国の地理、地質学的なデータを提供しています。また、水文学的なデータなども供給しており、これらを使って水文ネットワークの分析などが可能です。

4. [Global Roads Open Access Data Set, Version 1 (gROADS)](https://sedac.ciesin.columbia.edu/data/set/groads-global-roads-open-access-v1): 世界中の道路ネットワークのデータセットを提供しています。

地理的ネットワーク分析では、通常は空間的な情報を含むノードの特徴量やエッジの重み（例えば距離や旅行時間など）を考慮します。NetworkXの機能をフルに活用するため、これらの地理的な情報を適切にエンコードすることが重要です。

---

### **user**:

ありがとうございました！また折を見て使ってみたいと思います！

---

### **assistant**:

どういたしまして！ぜひ色々なデータセットを試して、NetworkXの機能を存分に使ってみてください。もし何か質問や困ったことがあれば、いつでもお尋ねください。ネットワーク分析の成功をお祈りしています！

---