Techブログ - MNTSQ, Ltd.

リーガルテック・カンパニー「MNTSQ(モンテスキュー)」のTechブログです。

身近なデータで30時間クッキング:Slackのログを解析してみる編

MNTSQ Tech Blog TOP > 記事一覧 > 身近なデータで30時間クッキング:Slackのログを解析してみる編

f:id:takumi-hirata-mntsq:20210514200157j:plain

入社して3ヶ月が経った。事業戦略・組織文化・プロダクトに対する解像度はだいぶ高まった実感があるが、実はまだメンバー1人1人のことを良く知らない。 そうだ、Slackのログを分析しよう。

当社では多くのコミュニケーションをSlackで行う。また、情報のopennessを重視しており、Slackのpublic channelの割合は高い水準を維持している。 private channelもそれなりにあるが、弊社のprivate channelの多くはメンバーのロールに対応するように作られており、実際にはほとんどのメンバーが参加しているため、opennessは保たれていると言って良い。

f:id:takumi-hirata-mntsq:20210514171529p:plain
Public and private channel

Slackにはアナリティクスダッシュボードがという機能がある。上のグラフはアナリティクスダッシュボードのスクリーンショットだ。簡単な分析ならこれで十分かもしれない。しかし、メンバー1人1人のことを知るにはもう少しパーソナライズされた情報が欲しい。

Slack APIを使ってメッセージを取得する

Slack APIを使えば全メッセージを取得可能だ。使用するAPIと取得するデータは次の通り。

ユーザとchannelは一度に全て取得できるが、メッセージはサイズが大きいので分割して取得する必要がある。conversations.historyとconversations.repliesはTier 3なので毎分50回となるように間隔を空けてAPIを呼び出す。

前処理

正規表現でテキストに含まれるメンション・URL・コードブロックを除去する。 また、事務やテスト用途のchannelはノイズになるので除外する。個別にチャネル名を指定しても良いが、手作業でやるには数が多いので、ここでは異なり語数で閾値を下回るものを除外する。他にもトークン比(Type-Token Ratio)の閾値を使うことも検討したが、トークン比の分母である延べ語数がchannelごとに大きく異なりそのままでは比較できないので見送る。

データの外観

  • 期間: 2020/5/1 - 2021/4/30
  • ユーザ数: 25
  • channel数: 69
  • メッセージ数: 35200
  • リアクション数: 19678

ユーザ数の推移

f:id:takumi-hirata-mntsq:20210514172856p:plain

メッセージの投稿ユーザを月毎にユニークカウントした。この1年で10人増えて25人になったようだ。めでたい。

ユーザごとのメッセージ数

f:id:takumi-hirata-mntsq:20210514174149p:plain

ユーザごとにメッセージ数、上位10件をプロットした。1位はBoard4人を抑えてSEの西村だ。彼はMNTSQのサラダ技術顧問でもある。メンバーは入社時期が異なるので単純な比較はできないが、それでもサラダ技術顧問の圧倒的存在感には恐れ入る。

人気のリアクション

f:id:takumi-hirata-mntsq:20210514180207p:plain

リアクション数、上位10件をプロットした。なんとポジティブなリアクション。メンバー同士の高いリスペクトが伺える。

ユーザごとのリアクション数

f:id:takumi-hirata-mntsq:20210514181156p:plain

ユーザごとのリアクション数、上位10件をプロットした。リアクション最多は4月に入社したばかりであるはずの広報の高井だ。この勢いは凄まじい。社内のあらゆる場面でリアクションし、活性化を促している証拠だろう。

“口癖”を分析する

メンバーごとにTF-IDFの総和を求め、値が高い上位10件を“口癖”とした。トークナイザーにはSentencePieceを使う。SentencePieceのパラメータは次の通り。

spm.SentencePieceTrainer.Train(
    input='./data/texts.txt',
    model_prefix='models/sentencepiece',
    vocab_size=8000,
    character_coverage=0.9995,
)

TF-IDFのパラメータは次の通り。

vectorizer = TfidfVectorizer(
    strip_accents=None,
    token_pattern=r'(?u)\S\S+',
    max_df=0.01,
    max_features=10000
)

SentencePieceで1文字のトークンが大量に作られるが、それらはtoken_pattern=r'(?u)\S\S+'で除外する。また、max_df=0.01で「です」や「から」を除外する。代表してBoard4人の結果を次に示す。 f:id:takumi-hirata-mntsq:20210514181502p:plain

率直に述べると、「わかる」という気持ちになる。板谷の「...!」や生谷の「あー」「はい」はものすごくよく見るし、安野の「done」「あざます」はSlackに限定されずリアルでもよく使われる。堅山は上から下まで全てそれっぽい。他のメンバーに対しても分析してみたが、非常に興味深い結果で、社内でも好評だった。

職種ごとの人気のリアクション

職種をBoard・Engineer・Legal・Sales/CS/PRの4つに分類する。SalesとCSとPRは、あまり詳細にすると人数が少なくなり統計的性質の観察が難しくなるので、便宜上同じカテゴリにした。単純なカウントでは前述した人気のリアクションと被るので、少し工夫をする。職種ごとの特徴を出したいのでTF-IDFで全員がよく使うリアクションが上位に来ないようにする。TF-IDFのパラメータは次の通り。

vectorizer = TfidfVectorizer(
    strip_accents=None,
    token_pattern=r'(?u)\S\S+',
    stop_words=['+1'],
)

職種ごとのTF-IDFの総和を求め、上位5件をプロットしたものが次の図である。 f:id:takumi-hirata-mntsq:20210514184407p:plain

職種ごとに結構好みが分かれているように見える。Boardに女性はいないはずだが、なぜかwoman-gesturing-okが上位にある。Sales/CS/PRは状態管理のためにリアクションを使っているようだ。

“返信”の関係を可視化する

“返信”とはチャンネル内またはスレッド内のあるメッセージと1つ前のメッセージの関係で、チャンネル内では2つのメッセージの時間間隔が1時間以内のものとする。“返信”の数を重みとする隣接行列をPCAで平面に写し、職種ごとに色分けしたものが次の図である。 f:id:takumi-hirata-mntsq:20210514182748p:plain

図を見ると、なかなか綺麗に職種で分かれていることがわかる。

  • (0.05, -0.1)付近の緑は弁護士で、他のLegalとは仕事が異なりSalesチームと活動しているため、Salesの付近にあると考えられる
  • (0.0, -0.05)付近の赤はCSで、顧客コミュニケーションのために他職種のメンバーと頻繁に情報共有しているため、他職種間の中心にあると考えられる
  • (-0,05, 0.05)付近の橙3点はEngineerの中でも機械学習を主に扱うメンバーで、彼ら(私もその1人だが)はアルゴリズム開発のためにLegalと活発に議論しているため、Legalの付近にあると考えられる

実際にはSlack以外でもGitHub Issueやオフラインでの議論も活発に行われており、この図に表れない関係は存在するものの、例えば平面上で距離が遠いLegalとSales/CS/PRのコミュニケーションに改善点はないか?といったフィードバックを得ることができる。