LoginSignup
12
6

More than 1 year has passed since last update.

Pythonでしか描けない美しい共起ネットワークを描こう!

Last updated at Posted at 2022-09-09

はじめに

テキストアナリティクス
この書籍に networkxmatplotlib による 静的共起ネットワーク が紹介されています。
以前の記事 の通り、無事に描くことはできたのですが、

  • ネットワークレイアウト(描画アルゴリズム)を選択できるようにしたい
  • ノードを部分ネットワークごとに色分けしたい(※部分ネットワーク=コミュニティ)
  • コミュニティ分割のアルゴリズムを変更できるようにしたい
  • ノードの配置を決めるlayoutのパラメータkを変更できるようにしたい
  • ノードのサイズを変えたい
  • ノードテキスト(表記単語)の表記サイズをノードのサイズに応じ、大きくしたい
  • 単語表記のフォントサイズを変えたい

など、カスタマイズしてみたい! ということでやってみましたという記事です。

なお、以下のサイトが 超参考になりました。

実行したこと

  • Google Colabで実行する
  • データは「再エネ」でtweet検索したをつぶやきを ついすぽ でcsvにエクスポートしたデータ。
  • 共起ネットワーク生成
  • 共起ネットワークの画像(Jpeg)を Plotly で表示(強引!)

共起ネットワーク

以下は、カスタマイズ前の共起ネットワークです。
image.png

以下がカスタマイズ後です。
まずは、レイアウト(描画アルゴリズム)による違いからです。

レイアウト(描画アルゴリズム)変更

springレイアウト
image.png
layoutでspring, fruchterman_reingold を選択した場合のみ、パラメータk の値を変えるとノードの配置を変えることができます。
値を小さくすると コミュニティ毎に分かれてくれ、値を大きくするとコミュニティ同士が重なり合う感じです。パラメータk の設定範囲は0-1です。
以下は、springレイアウトにおいて、kの設定を小さく(0.04)して描画させたものです。
image.png

kamada_kawaiレイアウト
これは、nlplot に近いですね。これではテキストサイズがノードサイズに応じすこしだけ大きくなるように調整しています。(※あとで述べるフォームで比率が変えられるようにしています。)
image.png
circularレイアウト
image.png
spiralレイアウト
image.png
fruchterman_reingoldレイアウト
springレイアウトと近いですね。どうもアルゴリズムは同じようです。
image.png
randomレイアウト
image.png
spectralレイアウト
これは・・・おまけですね。
image.png

コミュニティ検出アルゴリズム変更

networkx は いくつかの コミュニティ検出アルゴリズム が実行できます。
コミュニティ検出アルゴリズムは、さまざまなネットワークで密に接続されたコンポーネントグループを明確にしてくれます。

community_algorithmによる違いは以下の通りです。(※レイアウトはspringレイアウトとしています。)

greedy_modularity
ダウンロード.png
label_propagation
ダウンロード (1).png
connected_components
ダウンロード (2).png


各種調整し、以下に落ち着きました。
ダウンロード.png
上記の描画条件は以下です。
image.png

コードに関する補足

テキストアナリティクス入門 に掲載されているコードからの差分についてのみ、以下に補足します。

まず、共起ネットワークのカスタマイズ変数をGoogle colabのフォーム機能を利用しセット。

共起ネットワーク見た目調整の変数をフォームにセット
#@title 共起ネットワーク表示

#@markdown  **<font color= "Crimson">ガイド</font>:layout** でネットワークレイアウトが選択できます。**community_algorithm** でコミュニティ分割のアルゴリズムが選択できます。(greedy_modularityはモジュラリティ最適化、label_propagationはラベル伝搬、connected_componentsは連結成分)|**weight_cuttoff** で一定の割合に満たない共起を除外(枝切り)できます。|**node_size** で円の大きさ、**text_size** で単語表記サイズが変更でき、**node_fit_rate**でノードサイズに応じたサイズアップレートが指定できます。|**layout_parameter_k** はノード間の反発力の設定です。**k**が大きいほどノードの配置は円形に近くなります。(この設定はspringとfruchtermanレイアウト時のみ有効)

layout = 'kamada_kawai' #@param ['spring','fruchterman_reingold','kamada_kawai','spectral','spiral','circular','random']
community_algorithm = 'greedy_modularity' #@param ['greedy_modularity','label_propagation','connected_components']
weight_cutoff = 0.025 #@param {type:"slider", min:0.01, max:0.05, step:0.005}
node_size_ = 3500 #@param {type:"slider", min:1000, max:6000, step:500}
text_size = 9 #@param {type:"slider", min:5, max:30, step:1}
text_size_node_fit_rate = 0.3 #@param {type:"slider", min:0, max:1, step:0.05}
layout_parameter_k  = 0.07 #@param {type:"slider", min:0.01, max:1, step:0.01}

上記コードにより、Google Colabのセルに以下のフォームが表示されます。
image.png

コミュニティライブラリをインポート

コミュニティ検出のライブラリ
from networkx.algorithms.community import greedy_modularity_communities
from networkx.algorithms.community import label_propagation_communities
レイアウトとコミュニティアルゴリズムの選択と実行
def pyplot_network (G):
    plt.figure(figsize=(20, 11), dpi=300)

    if layout == 'spring':
      pos = nx.spring_layout(G, k=layout_parameter_k,iterations=50, threshold=0.0001, weight='weight', scale=1, center=None, dim=2, seed=123)

    elif layout == 'fruchterman_reingold':
      pos = nx.fruchterman_reingold_layout(G, dim=2, k=layout_parameter_k, pos=None, fixed=None, iterations=50, weight='weight', scale=1.0, center=None)

    elif layout == 'spectral':
      pos = nx.spectral_layout(G, weight='weight', scale=1, center=None, dim=2)

    elif layout == 'spiral':
      pos = nx.spiral_layout(G, scale=1, center=None, dim=2, resolution=0.35, equidistant=False)

    elif layout == 'kamada_kawai':
      pos = nx.kamada_kawai_layout(G, dist=None, pos=None, weight=1, scale=1, center=None, dim=2)

    elif layout == 'circular':
      pos = nx.circular_layout(G, scale=1, center=None, dim=2)

    else:
      pos = nx.random_layout(G, center=None, dim=2, seed=None)

    connecteds = []
    colors = []

    if community_algorithm == 'greedy_modularity':
      for i, c in enumerate(greedy_modularity_communities(G)):
        connecteds.append(c)
        colors.append(1/20 * i)

    if community_algorithm == 'label_propagation':
      for i, c in enumerate(label_propagation_communities(G)):
        connecteds.append(c)
        colors.append(1/20 * i)

    else:
      for i, c in enumerate(nx.connected_components(G)):
        connecteds.append(c)
        colors.append(1/20 * i)

    node_colors = []
    for node in G.nodes():
      for i, c in enumerate(connecteds):
        if node in c:
          node_colors.append(colors[i])
          break

テキスト表示は、nx.draw_networkx_labels() ではなく、ノードサイズに応じたテキストサイズにするため、以下のコードとしています。
text_sizeでテキスト表示の最小フォントサイズを指定し、text_size_node_fit_rate でノードサイズに応じてフォントを大きくして表示させるというものです。

テキストをノードサイズに応じて大きく表示
    from matplotlib.pyplot import figure, text
    d = dict(G.degree)
    for node, (x, y) in pos.items():
      text(x, y, node, fontsize=text_size+d[node]*text_size_node_fit_rate, ha='center', va='center')

    plt.axis ("off")
    plt.savefig("networkx.jpeg")
    plt.show()

また、以下の引数を追加しています。

  • nx.draw_networkx_nodes()の引数に node_color=node_colors, alpha=0.3 を追加
  • nx.draw_networkx_edges()の引数に alpha=0.4, edge_color="darkgrey" を追加

※alphaは、透明度です。

ムリヤリPlotly表示

Jpeg保存した共起ネットワーク(ファイル名「networkx.jpeg」)をムリヤリ Plotly で表示させました。
解像度をある程度確保しないときびしいので、dpi=300 としました。

あとはムリヤリ描くだけ・・・

共起ネットワーク画像をPlotly表示
#@title 共起ネットワーク表示(Plotly)
import plotly.express as px
from skimage import io
img = io.imread('networkx.jpeg')

fig = px.imshow(img)
fig.update_layout(width=1500, height=1000, margin=dict(l=10, r=10, b=10, t=10))
fig.update_xaxes(showticklabels=False).update_yaxes(showticklabels=False)
fig.show()

こんな風に拡大できる・・・ただそれだけ。
image.png

最後に

nlplot には敵わないですが、自分好みに見た目をカスタマイズしたいな・・・というときはよいとおもいます。
肝心なのはテキストを分析することなので、美しく描いてモチベをあげることと、共有しやすくすることを通して、よりよき前進を図りたいというところです。

それにしても
networkx はすごいです。いろんなことができすぎ。。。ですね。


networkx で共起ネットワークを描きたい!という方は、ぜひ「テキストアナリティクス入門」を手にされることをおすすめします。(私は回し者ではありません)

GoogleColabで実行するために必要なことについては、以下で触れています。

参考

12
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
6