グラフデータベースを使って株式ポートフォリオを可視化したお話(後編: DB操作から)
前回の記事ではグラフデータベースとは何か、グラフデータベースを使えるDBaaSであるNeo4jワークスペースを開くまでを書きました。
後編では開いたNeo4jワークスペースを操作して、グラフを作ってみます。
この記事を書くために触って、作ってみたデータはこんな感じ。
こんな感じの銘柄、業種、それと銘柄取得する主目的の繋がりを可視化できるグラフを書いていきます。そんな記事。
Graph DBを操作する
Graph DBを操作する言語には複数あるらしいですが、Neo4jではOpenCypherと呼ばれる言語を使います。(Graph DBを操作するための言語はプロパティグラフクエリ言語というらしい)
画面上部でQueryタブに切り替えて、操作するためのクエリを入力。ctrl
+Enter
で実行していきます。
入力するクエリについて、この章では以下のように進めていきます。
- ノードを作成してみる
- ノードを検索してみる
- リレーションを作成してみる
- リレーションを検索してみる
- 間違えて作成したものを削除する
- グラフの画像を保存してみる
1. ノードを作成してみる
OpenCypherでノードを作成するときは以下のようなクエリを発行します。
CREATE (:Brand{name: "MHD"})
クエリの内容はこんな感じ。
CREATE (:<ノードのカテゴリ>{name: "ノード名"})
カテゴリとノード名を指定してCREATE
するだけの簡単な構文。
"Mホールディングス"という名前で、カテゴリが銘柄(Brand
)として作成します。
(冒頭の画像でいうオレンジのノードたちがBrand
に属します)
他にも、業種カテゴリを作るためにIndustryCode
や、主目的カテゴリのためにPurpose
を作っていきます。
CREATE(:IndustryCode{name: "食べ物"})
CREATE(:Purpose{name: "お菓子"})
これらのCreate文を全銘柄、全業種、全目的で実行していこう。全部作ってからまとめて実行していきました。
2. ノードを検索してみる
さて、CREATE
で作成できたものを作成できているのか確認してみよう。
検索するにはMATCH
を使います。
クエリの例を挙げるとこんな感じ。
MATCH(nodes:Brand{name:"MHD"})
RETURN nodes
構文としてはこんな感じ。
MATCH(<変数名>:<カテゴリ名>{name:"<名前>"})
return <変数名>
ここでは、1行目でのMATCH
にて、
カテゴリがBrand
、名前がMHD
のものを検索して、変数nodes
に代入します。
そして2行目のRETURN
にて、nodes
を出力すると、検索結果が表示されるというわけです。
複数検索をしたいときは、項目を空欄にしておくとワイルドカードのように検索できます。
カテゴリだけ指定したいときはこう。
MATCH(nodes:Brand)
RETURN nodes
ブランドカテゴリのノードが全て表示された。
ノード名だけ指定したいはこう。
MATCH(nodes{name: "食品"})
RETURN nodes
カテゴリ関係なく、"目的"、"業種"の両方から"食品"という名前のノードを検索している。
全検索するときはこんな感じ
MATCH(nodes)
RETURN nodes
作ったノード全部が出力されます。
表示をTableに切り替えると一覧で見れます。チェックするにはちょっと楽。
3. リレーションを作成してみる
リレーションの作成方法はこんな感じです
MATCH(MHD:Brand{name: 'MHD'})
MATCH(purpose:Purpose{name: 'お菓子'})
CREATE (MHD)-[:目的]->(purpose)
1行目にて、変数MHD
に紐付ける銘柄を代入。
2行目にて、変数purpose
に紐づける目的を代入。
3行目のCREATE
で、MHD
から見ると、purpose
は目的
というリレーションを作成します。
そして>
を使った矢印の方向で、リレーションの向きを表現しているわけです。
CREATE (<接続元>)-[:<関係>]->(<接続先>)
これを各リレーションの数だけ、24回実行していこう。
(わたしは面倒なので各リレーションをNumbersで一覧表にして、Numbers上でクエリを全部生成させました)
4. リレーションを検索してみる
さて、実際にリレーションが作成できているのか、確認しよう。
リレーションでも、検索にはMATCH
を用いて、作成の時と同じように矢印を用いて表現します。
ここで、矢印の>
を消してあげると、方向に関係なく検索できます。方向に関しても、指定しないことがワイルドカードになるということです。
MATCH(MHD:Brand{name: 'MHD'})
MATCH(purpose:Purpose{name: 'お菓子'})
MATCH (MHD)-[relation]->(purpose)
return relation
なんとなく、真ん中に代入するための変数が来るのに違和感を覚える。
MATCH (<接続元>)-[<変数名>]->(<接続先>)
return <変数名>
ここでも、空白にするとワイルドカードのようになるので、
全検索するときはこんな感じ。
MATCH ()-[relation]->()
return relation
リレーションだけ見ても何が何だかわからないので、接続元/先もそれぞれ変数r1
、r2
に入れて表示してしまおう。
MATCH (r1)-[relation]->(r2)
return r1,relation, r2
各銘柄から、目的および業種のリレーションを伸ばしていることがわかる。
関係を全部出力する都合、多くなってしまうね。
5. 間違えて作成したものを削除する
ところで、間違えて生成したものは、検索したのちにDELETE
つかうことで削除できます。
例えば、"施設利用"を間違えて"移設利用"と作ってしまった時の削除はこんな感じ。
MATCH (wrong: Purpose {name: "移設利用"})
DELETE wrong
RETURN
で出力する代わりにDELETE
で削除するわけです。
ここで削除対象が何かしらとリレーション張っている場合は削除できません。エラー吐かれます。
"移設利用"ノードに関する任意の繋がりを検索してみると、こんな感じ。
"移設利用"ノードを削除するにはこの接続を先に削除しておく必要があるわけです。
間違いノードwrong
とワイルドカード(無記入)の繋がりrelation
を検索して、DELETE
で削除。
MATCH (wrong{name: "移設利用"})
MATCH ()-[relation]-(wrong)
DELETE relation
その後、間違いノード削除すると綺麗にすることができます。
MATCH (wrong{name: "移設利用"})
DELETE wrong
繋がりという要素が増えたぶん大変だ。
6. グラフの画像を保存してみる
さぁ、各種ノードとそれらのリレーション、そして間違いの修正まで済んだのでグラフを表示してみよう。
ワークスペース上部にあるExplore
タブに切り替えて、検索ボックスから全てのリレーションを検索します。
(any)-<Any>-(Any)
と入力して、検索ボックス内右端の検索実行ボタン(再生マークのようなボタン)を押すと、検索されたグラフが出てきます。
ある業種だけに絞りたかったら、"ある業種コードと繋がっている銘柄を買う目的"まで絞り込んであげるといいわけです。(検索結果をハイライトする設定は右上の歯車マークからできる)
(IndustryCode name(equal):食品)-<any>-(Brand)-<any>-(Prupose)
ここまで表示できたら、右上ダウンロードするマークを押してExport screenshot
から画像を保存します。
保存したものがこんな感じ。
あとは可視化したグラフから、目的の中でも矢印多い食品を重視しているんだなとか、業種コードごとのばらつきが激しいなとかを観察、分析していこう。
表示までしました。それをどう見て、どういう戦略を立てるのかはまた別のお話なので、この記事はここでおしまい。
Discussion