社内に飛び交うフィードバックを NetworkX を使って可視化する
この記事はユアマイスター アドベントカレンダー 2022の 25 日目の記事です。
ユアマイスターで VPoE をしている inase17000 です。2022 年のアドベントカレンダー最終回担当という大役を任されてからプレッシャーで毎日寝ても醒めても記事のことが頭か離れませんでした。年末の風物詩ですね。
今回はユアマイスターならではの文化にも触れながら、ネットワーク分析の基礎を実践してみようと思います。
週報で、仲間を「褒める」文化
ユアマイスターでは全社員が週報を書いています。特別なツールは利用しておらず、Google スプレッドシートの所定の欄に、業務内容・所感などを記載する形式です。
この週報の記入と併せて homehome 欄(読み方:ホメホメ欄。褒め褒めに由来)が存在します。
homehome 欄では、仲間の中から名前を選び、homehome コメントをあわせて記載する形式です。ここでは、「XXXX をしてくれてありがとう」という感謝の言葉や、「XXXX が役に立ちました、ナイス!」など労いの言葉などを気軽にかけることができます。
また、週報と併記する形でそのコメントを見ることができるように、全員に公開されています。直接業務で関わりを持たなくても仲間の様子を知ることができる重要な情報ソースとなります。
ユアマイスターの行動指針の 1 つである「FEEDBACK IS GIFT」を現す行動のひとつとして、一緒に働く仲間へフィードバックを伝えるユアマイスターならではの文化だと言えます。
フィードバックは分散しているか、部署を超えて飛び交っているか
homehome 欄の運用を半年以上続けて多くのデータが溜まってきたところ、さらに活用する方法を検討していると、とある疑問が湧き立ちました。
- フィードバック(homehome)は部署を超えて飛び交っているか?
- フィードバック(homehome)は分散しているか?
つまり、越境の度合いと偏りを確認したいと思いました。
ある職種では、特定かつ少数の人としか関わりを持たないことは考えられます。また逆に、常に部署間を行き来してハブになるような役割をしている方もいるため、フィードバックをもらうきっかけである業務上での接触機会は人によって異なります。
その前提条件を踏まえた上で、社内の人材ネットワークの拡がりとフィードバックの行き来を可視化して、組織開発のための一つの材料にしようと考えました。
実行環境の準備
Google Colaboratory
Google Colaboratory(略称「Colab」)では、ブラウザ上で Python を記述、実行できます。面倒な環境構築が不要で、Colab ノートブックという、コードを記述して実行できるインタラクティブな環境を無料で使うことができるのが特徴です。また、コードだけではなく、リッチテキスト(画像、HTML、LaTeX なども可)を 1 つのドキュメントで記述できるため、そのままプレゼンテンーションも可能です。
これまで何度となく利用してきましたが、データとプレゼンテーションを一緒につくることができるため、試行錯誤のサイクルを短くできました。そして、非エンジニアにデータ分析結果を説明するとき、いちいちスライド資料を作る手間を省いて直接見てもらうことができるので、とてもオススメです。
今回のプログラムと実行結果は、参考までにこちらで公開しています。
NetworkX
今回ネットワーク分析では、Python と NetworkX を使っていきたいと思います。
NetworkX は、ネットワーク構造を作成、操作、研究するための Python ライブラリ(BSD ライセンスによるオープンソース)です。できることの一部を抜粋すると、以下のようなものが挙げられます。
- グラフ、ダイグラフ、マルチグラフのためのデータ構造を取り扱える
- ノードは「何でも」可能(例:テキスト、画像、XML レコード)。
- エッジは任意のデータ(例:重み、時系列)を格納可能
今回ネットワーク分析では、Python と NetworkX を使っていきたいと思います。また、初めての方には、NetworkX Tutorialがおすすめします。
データ収集
2022 年 5 月 〜 2022 年 11 月の期間で、合計 1,117 件のフィードバック(homehome)を対象にします。
homehome 欄では、相手を指名してコメントを記載します。記載を簡便化するため、社員ごとに番号を採番し、誰から誰へのフィードバック(homehome)であるかを一覧表にまとめました。
その後、一覧表を CSV ファイルへ出力し、Colab へアップロードしました。アップロードのためのコードは以下を参照してください。
import pandas as pd
df1 = pd.read_csv('homehome-network-analysis - nodes.csv')
nodes = df1.values.ravel() #ravel() で配列を平坦化
# nodes
# array([75, 46, 73, ... 74, 31, 101])
df2 = pd.read_csv('homehome-network-analysis - edges.csv')
edges = df2.values
# edges
# array([[ 97, 1],
# [ 16, 1],
# [ 20, 1],
# ...,
# [ 29, 133],
# [ 7, 133],
# [ 69, 133]])
いざ、可視化
ネットワーク分析では、頂点のことをノード、辺のことをエッジ、ネットワークのことをグラフと呼びます。
社員をノード、フィードバック(homehome)は有向グラフのエッジとして、ネットワーク構造の可視化を行います。グラフの出力には、maplotlib
ライブラリも利用しました。
import matplotlib.pyplot as plt
import networkx as nx
# 有向グラフの作成
G = nx.DiGraph()
# node追加
G.add_nodes_from(nodes)
# edge追加
G.add_edges_from(edges)
# ネットワークの可視化
nx.draw_kamada_kawai(G, with_labels = True, node_color = "red", edge_color = "gray", node_size = 150, width = 1)
plt.show()
ノードに記載されている数字は社員ごとのランダムな番号です(数字の大きい小さいに意味はありません)。
フィードバックは送る人と送られる人がいますので、図の中では矢印の向きとして表現されています。図の周辺部にいて矢印を受けるだけの社員はフィードバックを受けるだけであり、誰にもフィードバックをしていない、ということを意味します。
一般にノードにリンクしているエッジの数を次数と呼びます。次数を計算し、ネットワーク内のつながりの多さを社員一人一人を現す赤い丸の大きさで表現してみましょう。
# ノードの次数に比例してサイズを計算
DEFAULT_SIZE = 150
sizes = [DEFAULT_SIZE * d2 / (sum(d1 for n, d1 in G.degree()) / G.number_of_nodes()) for n, d2 in G.degree()]
# ネットワークの可視化
nx.draw_kamada_kawai(G, with_labels = True, node_color = "red", edge_color = "gray", node_size = sizes, width = 0.3)
plt.show()
最初のグラフに比べて、社員一人一人を現す赤い丸の大きさにばらつきができました。赤い丸が大きければ大きいほど、次数が大きく、反対に赤い丸が小さければ小さいほど、次数が小さいことを表します。
次数が多い、つまり、フィードバックの行き来が多ければ多いほど、中心部に寄っています。ただし、フィードバックを送ったのか、送られたのかは見分けがつかないことに注意してください。フィードバックをたくさん送る人、たくさん受ける人、送るのも受けるのも両方ある人が混ざっています。
次に、ノードを部署ごとに色分けしてみましょう。
# 部署別にノードの色を指定したCSVに差し替え
df3 = pd.read_csv('homehome-network-analysis - nodes_with_deps.csv')
nodes_with_deps = df3.values
# nodes_with_deps
# array([[75, 'lightblue'],
# [46, 'lightblue'],
# [73, 'green'],
# ...,
# [33, 'green'],
# [30, 'green'],
# [74, 'magenta']], dtype=object)
# ノードの色をセット
node_color = [n[1] for n in nodes_with_deps]
# ネットワークの可視化
nx.draw_kamada_kawai(G, with_labels = True, node_color = node_color, edge_color = "gray", node_size = sizes, width = 0.3)
plt.show()
日頃の業務に関連するフィードバックすることが多いため、同じ色のノードは近くに集まりやすい傾向にあります。
もし部署の中だけでフィードバックが留まっていると、別の色のノード同士はつながりがなくなり、色ごとの孤立したネットワークが複数形成されるはずです。しかし、図を見ると、一つのネットワークにまとまっていることを見ると、部署を超えて飛び交っている様子が示唆されています。
また、よくみると同じ色の集合から飛び出して他の色に囲まれているノードも見受けられます。例えば図の左側にある青色の 18 番のノードや図の中央にある赤色の 17, 123, 69 番のノードは、周囲を別の色のノードの集合に囲まれながら、存在しています。このようなノードは越境し業務を進められている可能性が高い、または、複数の部署のハブになるような役割を担っている可能性が高いと考えられます。
せっかくの有向グラフなので、もう少しだけカスタマイズしてみます。
# フィードバック受ける数に比例してサイズを計算
sizes = [DEFAULT_SIZE * d2 / (sum(d1 for n, d1 in G.in_degree()) / G.number_of_nodes()) for n, d2 in G.in_degree()]
# ネットワークの可視化
nx.draw_kamada_kawai(G, with_labels = True, node_color = node_color, edge_color = "gray", node_size = sizes, width = 0.3)
plt.show()
# フィードバック送る数に比例してサイズを計算
sizes = [DEFAULT_SIZE * d2 / (sum(d1 for n, d1 in G.out_degree()) / G.number_of_nodes()) for n, d2 in G.out_degree()]
# ネットワークの可視化
nx.draw_kamada_kawai(G, with_labels = True, node_color = node_color, edge_color = "gray", node_size = sizes, width = 0.3)
plt.show()
このままでも、上記 2 つの図を見比べることで、社員ごとの振る舞いの違いを知ることができます。しかし、交互に図を見ていると、差分を把握しづらいと感じました。
そこで最後に、フィードバックを送る数と受ける数の比を取り、フィードバックを送る比率が高い社員が誰かわかりやすいように可視化してみましょう。
# { フィードバック送る数 / フィードバック受ける数 } の比を取る
sizes = []
for n in G.nodes:
sizes.append(DEFAULT_SIZE * G.out_degree(n) / G.in_degree(n))
# ネットワークの可視化
nx.draw_kamada_kawai(G, with_labels = True, node_color = node_color, edge_color = "gray", node_size = sizes, width = 0.3)
plt.show()
いくつか具体例をあげて特徴を考えてみます。
例えば、図のやや右にある緑色の 16 番のノードに注目してみましょう。この社員はフィードバックを送る数がおおく、受ける数が少ないことから、積極的に他社へフィードバックを行っていることが予想されます。16 番のノードのフィードバックの内訳を見てみると、同じ緑色の部署の社員へのものが多い状態でした。同じ部署の社員と一緒に働く機会の多いハブのような存在なのかもしれません。
次に、図の中央にある水色の 118 番のノードに注目してみましょう。図の中央にいるにもかかわらず、サイズがとても小さいことを見ると、この社員はまわりからフィードバックを受けることが多いようです。また、周りを複数の色に囲まれているため、フィードバックを複数の部署の社員から受けていることが考えられます。
グラフの中心にいるからといって、フィードバックを送る側とは限らないとうことがわかりました。周りのノードと繋がるためにたまたま中心部にいる場合もあるという気づきが得られました。
まとめ
以上から、冒頭に掲げた、
- フィードバック(homehome)は部署を超えて飛び交っているか?
- フィードバック(homehome)は分散しているか?
という 2 点の問いに対して、色やサイズをパラメータに可視化することによって、部署を超えて飛び交うフィードバックの様子や、社員によってフィードバックを送る側が多かったり、受ける側が多かったりと偏りがあることがわかりました。
残る課題としては、異なる部署間のフィードバックが起こっているかという観点では図から明瞭に読み取ることができていません。別の機会に、エッジに重みづけするなどして、越境度合いを加味した分析を行ってみようと思います。
ユアマイスターではエンジニアを募集しています
最後にちょっと宣伝です。
少しでもユアマイスターに興味が湧きましたら、まずは「ユアマイスターと出会うみなさんへ(面接前のご挨拶) エンジニア編」だけでも目を通してみてください!
また、エンジニアインタビューなども取り揃えてますので、併せてこちらもどうぞ!