Microsoft Azure & Neo4j でストレングスファインダーをグラフ化

GYAOのtsです。
我々のチームは、オールパブリッククラウドで、[Microservice Architecture](http://microservices.io/patterns/microservices.html)を採用した次期バックエンドを設計中です。

# 経緯

[前回](http://qiita.com/tstakano-yj/items/9b23a457313030a38bff)までで大枠のデザインも決まり、細かい技術に関してもある程度見通しが立ってきたので、今回は少し脱線。
脱線と言ってもそこまで脱線しないが、
team内に「今後必要になるであろう、METAデータ同士のつながりをどう表現していくのがきれいだろう」という課題感があり、試しにグラフDBを検証してみたというお話。
ちょうど周りで[StrengthsFinder](http://sf1.strengthsfinder.com/ja-jp/homepage.aspx)のデータをDBに格納して、色々分析したいみたいな話もあったので、グラフDBに突っ込んで使い勝手を検証してみた。

# 概要

## 目指すところ

* 今回はNeo4jとBlobStorageを使ってCSVデータを可視化する。
* Neo4jのGUIでCypherコマンドを打って結果を確認する。

## ノード構成
下記のような構成でノード、エッジを作成する。
![export (1).png](https://qiita-image-store.s3.amazonaws.com/0/114329/37c5a44a-ceb5-8280-b302-be3a4efb5c78.png)


# 環境整備
## Neo4jの立ち上げ
なにはなくともまずはNeo4jを立ち上げる。
ローカルでもなんでもいいのだが、今回はクラウドでの検証も目的なので、Aure上に立ち上げる。
AzurePortalの新規作成から「Hardened Neo4j on Ubuntu 14.04 LTS」
を選択。
<img width="467" alt="スクリーンショット 2017-02-21 12.18.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/114329/a34dd8ce-5a52-f622-8377-bdcd4d3cd01b.png">
普通に必要事項を記入していくが、
構成は「おすすめ」の構成が試すにはお高いので、最安の構成でBuyする。
<img width="258" alt="スクリーンショット 2017-02-21 12.20.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/114329/0b297272-9598-a11f-6959-7269f6fe6dd7.png">

http://[ip or DNS]/neo4j

でアクセス可能。Basic認証がかかっているが、

ID:neo4j
PASS:Azureの「Hardened Neo4j on Ubuntu 14.04 LTS」の概要に書いてあるパスワード

でログインできる。

# データ投入
## Masterデータ
```strengths-master.csv
"Category","Qualification"
"実行力","アレンジ"
"実行力","回復志向"
"実行力","規律性"
"実行力","公平性"
"実行力","慎重さ"
"実行力","信念"
"実行力","責任感"
"実行力","達成欲"
"実行力","目標志向"
"影響力","活発生"
"影響力","競争性"
"影響力","コミュニケーション"
"影響力","最上志向"
"影響力","自我"
"影響力","自己確信"
"影響力","社交性"
"影響力","指令性"
"人間関係構築力","運命思考"
"人間関係構築力","共感性"
"人間関係構築力","個別化"
"人間関係構築力","親密性"
"人間関係構築力","成長促進"
"人間関係構築力","調和性"
"人間関係構築力","適応性"
"人間関係構築力","包含"
"人間関係構築力","ポジティブ"
"戦略的思考力","学習欲"
"戦略的思考力","原点思考"
"戦略的思考力","収集"
"戦略的思考力","戦略性"
"戦略的思考力","着想"
"戦略的思考力","内省"
"戦略的思考力","分析思考"
"戦略的思考力","未来志向"
```
## personデータ
```strengths.csv
"Org","Name","Qualification1","Qualification2","Qualification3","Qualification4","Qualification5"
"開発本部","いまさん","戦略性","最上志向","競争性","個別化","達成欲"
"TD部開発1","まいまい","着想","自我","戦略性","分析思考","収集心"
"TD部開発1","たかか","着想","慎重さ","未来志向","個別化","収集心"
"TD部開発1","おやさん","原点思考","最上志向","アレンジ","個別化","調和性"
"TD部開発1","んごごご","個別化","戦略性","着想","原点思考","学習欲"
"TD部開発1","のもう","慎重さ","達成欲","学習欲","最上志向","目標志向"
"TD部開発1","けんちゃん","慎重さ","責任感","最上志向","調和性","信念"
"TD部開発2","たんたん","回復志向","公平性","調和性","適応性","成長促進"
"TD部開発2","にじるひと","戦略性","着想","最上志向","目標志向","未来志向"
"TD部開発2","ふじじ","学習欲","個別化","最上志向","ポジティブ","適応性"
"TD部開発3","まるさん","最上志向","成長促進","共感性","調和性","社交性"
```
上記をBlobストレージに上げておく。あとは下記のCypherコマンドでデータをインポートする。

```　CypherCommand.
//部署index作成
CREATE INDEX ON :Org(name);
//人物index作成
CREATE INDEX ON :Person(name);
//資質index作成
CREATE INDEX ON :Qualification(name);
//資質カテゴリindex作成
CREATE INDEX ON :Category(name);

//Masterデータの登録
LOAD CSV WITH HEADERS FROM 'https://*****.blob.core.windows.net/****/strengths-master.csv'AS csvLine
MERGE (category:Category { name: csvLine.Category })
MERGE (qualification:Qualification { name: csvLine.Qualification })
CREATE (qualification)-[:BLONGS_TO]->(category)
 
//Personデータの登録
LOAD CSV WITH HEADERS FROM 'https://****.blob.core.windows.net/****/strengths.csv' AS csvLine
MERGE (person:Person { name: csvLine.Name })
MERGE (org:Org { name: csvLine.Org })
MERGE (qualification1:Qualification { name: csvLine.Qualification1 })
MERGE (qualification2:Qualification { name: csvLine.Qualification2 })
MERGE (qualification3:Qualification { name: csvLine.Qualification3 })
MERGE (qualification4:Qualification { name: csvLine.Qualification4 })
MERGE (qualification5:Qualification { name: csvLine.Qualification5 })
CREATE (person)-[:BLONGS_TO]->(org)
CREATE (person)-[:HAS { order: 1 }]->(qualification1)
CREATE (person)-[:HAS { order: 2 }]->(qualification2)
CREATE (person)-[:HAS { order: 3 }]->(qualification3)
CREATE (person)-[:HAS { order: 4 }]->(qualification4)
CREATE (person)-[:HAS { order: 5 }]->(qualification5)

//やり直すときは　all delete
MATCH (n)
DETACH DELETE n
```

# ユースケース
## case1: チームの傾向性をみてみる
開発1〜3が登録されているので、下記のクエリで、チームがどの資質カテゴリに特化しているかみてみる。

```　CypherCommand.
MATCH p =(org { name: 'TD部開発1' })<--()-->()-->()
RETURN p
```
<img width="1153" alt="スクリーンショット 2017-02-21 11.33.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/114329/a1b1ae7d-793b-6e43-f7a5-ece9b81bf23d.png">
開発1は戦略と実行に特化したチームの模様。人間関係や影響力は逆に傾向として弱い。
各々が独立して考えて成果を出すみたいな感じかな・・・。そういえばそうかも。

開発2もみてみる。

```　CypherCommand.
MATCH p =(org { name: 'TD部開発2' })<--()-->()-->()
RETURN p
```

<img width="839" alt="スクリーンショット 2017-02-21 11.35.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/114329/ca0349f5-d2c2-f429-0f43-d87e7c89e3ba.png">

お、このチームは影響力、実行力が傾向として弱いかもですね。
そこで、実行力の資質を多く持ったメンバーをアサインします。

```strengths.csv
"TD部開発2","マックス","達成欲","調和性","信念","責任感","活発性"
```
<img width="952" alt="スクリーンショット 2017-02-21 11.42.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/114329/ce7d61da-f0b1-e1ac-edb0-c9809c1cecbb.png">
更に第一資質で、最も強い傾向を測定してみます。

```　CypherCommand.
MATCH p =(org { name: 'TD部開発2' })<--()-[r]->()-->()
WHERE r.order=1
RETURN p
```

<img width="761" alt="スクリーンショット 2017-02-21 15.02.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/114329/b7def441-5ce6-cf0f-6caf-db39654ddbbe.png">

アサインによりストレングス・ファインダー上は実行力の傾向もあるチームとなりました。

## case2: 資質からアサインするチームを決める
今回は新規案件で要件もまだ決まっていないから、着想を豊富に持ったチームに任せたい。
みたいなケースの場合。

```　CypherCommand.
MATCH p =(qualification { name: '着想' })<--()-->()<--()
RETURN p
```
<img width="1108" alt="スクリーンショット 2017-02-21 12.34.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/114329/c6ef6d47-c6f7-fe9d-e2ef-a10df1a6ef58.png">
開発1がいいかもですね。みたいな結果。

# 所感

当然、人と仕事の問題なので、こんな杓子定規には行かないかと思いますが、チームのアレンジをする時に風評や上司の心象で決まるよりかは客観的な論拠がある分、いいかと思います。MLや[LogicApp](http://qiita.com/tstakano-yj/items/967edafec3a2be83e67f)と連携することで、組織アレンジツールを作れそうです。
人事部門や人材育成部門も導入してもらうと参考になると思います。うちの人事はみてくれてるかな。。。