投稿
今回はテキストマイニングにおける共起ネットワークを表現するためにNetworkXをいじってみます。
やりたいこと
– Word間の結びつきを図示する
– 結びつきの強さをグラフの線の太さで表現する
- 1: NetworkXの情報集め
- 2: ネットワーク図を作ってみる
- 3: 最後に
NetworkXの情報集め
こちらのページが公式のようです。
Latestのdocに載っています。
Tutorialで使い方、Referenceで関数について調べながらやりました。
ネットワーク図を作ってみる
サイトを確認すると以下のような流れのようです。
– 空のグラフを作る
– nodeを足す
– edgeを足す
さっそくトライしてみます。
# networkxをインストール
!pip install networkx
# networkxをimport
import networkx as nx
まずは空のグラフを作成します。
# 空のグラフを作成
G = nx.Graph()
グラフにnode(頂点)を加えます。
networkx.Graph.add_nodeで加えることができるようです。
# nodeに"1"を加える G.add_node(1)
さっそく図示してみます。
Tutrialの「Drawing graphs」を確認するとmatplotlibを使って描けるようです。
drawの引数にグラフを与えれば取り急ぎはOKですね。
# 図示 # matplotをimport import matplotlib.pyplot as plt # 図示する nx.draw(G)
おお、ちゃんとnodeが一つできました。
networkx.Graph.add_nodes_fromだとlist等まとめてできるようです。
# nodeを複数追加する
G.add_nodes_from([2,3])
# 図示する nx.draw(G, with_labels=True)
ちゃんと番号も入ってました。
edgeも全く話一緒のようです。つなぐ組み合わせを入れればOK
# edgeを加える G.add_edges_from([(1,2),(1,3)]) # 図示 nx.draw(G, with_labels=True)
ちゃんと(1,2), (1,3)がつながって(2,3)はつながってないですね。
一度に情報を入れることもできます。
今度は属性情報としてweightも入れてしまいましょう。テキストマイニングで求めたJaccard係数をweightとして線の太さに使えば良さそうです。
グラフに加えるには「networkx.Graph.add_weighted_edges_from」を使います。
# 空のグラフを作成 H = nx.Graph() # weight付でnodeとエッジも入れる H.add_weighted_edges_from([(1,2,1),(2,3,0.8),(3,4,1),(5,6,1),(6,7,1),(2,6,0.5)]) # 図示 nx.draw(H, with_labels=True)
いいですね。weightを線の太さに指定してみます。
drawのパラメーターにwidthを入れればいいですが、エッジによって違うのでListを作ってfor文で入れます。線が細かったので一律10倍しました。
# weightによって線の太さを変える edge_width = [d["weight"] * 10 for (u, v, d) in H.edges(data=True)] # posを定義 pos = nx.spring_layout(H, k=0.3) # k = node間反発係数 # 図示 nx.draw(H,pos, with_labels=True, width=edge_width)
いい感じになりました。ちゃんと線の幅でweightの大きさが表現されています。
posはレイアウトのアルゴリズムの指定です。ちゃんと調べてないですが、いい感じに落ち着かせてくれるspring_layoutにしました。
最後に線が多過ぎて邪魔くさいと感じた時のためにedgeの剪定を考えます。
weightが小さい=細いedgeは線を無くしてしまいたいです。
networkx.Graph.remove_edges_fromでedgeの組を指定すればOKです。
# weight 0.6以下のedgeを消す removeEdges = [] #空のリスト for (u, v, d) in H.edges(data=True): if d["weight"] <= 0.6: removeEdges.append([u,v]) #weightが0.6以下ならremoveEdgesに追加 # グラフから削除 H.remove_edges_from(removeEdges) # 図示 nx.draw(H,pos, with_labels=True, width=edge_width)
できました。ちゃんと指定したweight以下のエッジが消えています。
これでテキストマイニングの共起ネットワークも表現できそうです。
最後に
NetworkXは他にも最短距離を出す等の分析でも使えるようです。
今回は今必要な部分だけやってみました。