Database for AI - Grakn.aiことはじめ part 3 - ポケモングラフマスター

##はじめに
前回の[Database for AI - Grakn.aiことはじめ part 2 - AzureにGrakn.aiをインストールしてグラフを愛でる](https://qiita.com/ShinHashitani/items/f98de1bec9dd657fc782)でAzureにGraknをインストールした際にポケモンのテストデータを入れてみた。今回はこのテストデータに対してVisualizerをいじって基本操作を説明してみる。
#### 英語が読める方へ
[本家ブログ](https://blog.grakn.ai/an-introduction-to-the-grakn-web-dashboard-e07a935a1b80)とさほど内容は変わらないので、そちらをどうぞ。

#### Virtual Boxを使用する場合
[Database for AI - Grakn.aiことはじめ part 2 .1 - Oracle Virtual Boxで学ぶGrakn Academy](https://qiita.com/ShinHashitani/items/e5e162c5958f819d1a40)で記載したようにOracle Virtual Boxにて試される場合、Grakn Academyにも同じサンプルが用意されているので、VMにログイン後：

```Bash:
grakn/graql console -f grakn/example/pokemon.gql -k pokemon
```

とすれば良。
##キースペースハンドラー
GraknにはKeyspaceというネームスペースの概念があり、作業対象のネームスペースを特定して作業を実施する必要がある。（デフォルトはgrakn）これはクエリの実行だけでなく、データ投入等でも同様。コマンドラインでは`-k pokemon`という形式で指定するが、Visualizerでは
![keyspace_selector.PNG](https://qiita-image-store.s3.amazonaws.com/0/213933/f2f06dab-e1a1-72a5-e36f-00beb2e7f98e.png)
コンソール右上にあるハンドラーで切り替える。
##メニュー
主にGraphとConsoleを切り替えて作業を行うが、いずれにおいてもクエリを実行する事が可能。
####コンソール:
![console.PNG](https://qiita-image-store.s3.amazonaws.com/0/213933/482e4312-50c3-67c6-61a0-cbc8886343b9.png)
####グラフ：
![graph.PNG](https://qiita-image-store.s3.amazonaws.com/0/213933/aaaeefc3-e306-61da-b6d2-5c9aeb376d13.png)
##クエリ
####クエリウィンドウ
クエリウィンドウにクエリを記述してから▶ボタンで実行する。もしくはEnterで実行。クエリウィンドウはマルチラインに対応しているので、Shift+Enterでウィンドウ内での改行を行うことが出来る。コピペで複数行のコマンドをペーストした際には自動的に複数行化される。
![multiline.PNG](https://qiita-image-store.s3.amazonaws.com/0/213933/3aed2d60-29a6-ca62-35c8-fabd434c3798.png)
####キャンセルボタン
お察しの通りXボタンでクエリをクリアする事が出来る。但しクリアされるのはクエリだけであって実行結果はクリアされない。実行結果もクリアしたい場合には**Shiftを押しながらXボタンの押下**が必要。
####クエリオプション
クエリのオプション変更は歯車ボタン：
![option.PNG](https://qiita-image-store.s3.amazonaws.com/0/213933/92643d60-08a3-9dea-ba3c-3a14d1fa4cd9.png)
Activate InferenceはデフォルトOffになっているが、Inference（演繹）、つまり明示的でない関連性をクエリで表現するか否かを切り替える事が出来る。そもそものGraknの用途を考えるとOnにしておいて良い。
####タイプ
エンティティやリレーションを特定し、その全件（もしくはオプションで指定した上限数）を取得するクエリを生成し実行する。
![type.PNG](https://qiita-image-store.s3.amazonaws.com/0/213933/a3c438e3-95c2-1259-45a3-1af154124c65.png)
ここで一番右のAll(Types)を選択すると、オントロジーにおける全エンティティ/リレーションを一気に取得する事が出来る。つまりこれを選択すると**オントロジーを可視化**出来る。ちなみにPokemonオントロジーは以下のようになっている：
![pokemon_ontology.PNG](https://qiita-image-store.s3.amazonaws.com/0/213933/0e90a55c-d735-ae34-df0a-c05e6cf01e25.png)
オブジェクト指向的に見ると、Entity、Relationship、ならびにAttributeは全て*Thing*のサブクラス（?）である事が分かる。ただし、どのEntityがどのattributeを持っているか、どのEntity同士がrelationshipで繋がっているかは見えない。あくまでオントロジーの構成要素のみ。（アグリゲーション/コンポジションを表現するものではない。）
##グラフ
さて、当然コンソールをVisualizerで使うことも出来るが、Visualizerと言われるくらいなのでグラフをいじってナンボ。ここではグラフの基本的な扱い方について説明する。
####クエリの構成要素
まずは水タイプのポケモンを取得してみる：

```bash
match
($x, $y) isa has-type;
$x isa pokemon;
$y isa pokemon-type has name "water";
get;
```

結果はこうなる：
![pokemon_water.PNG](https://qiita-image-store.s3.amazonaws.com/0/213933/7fc78ce3-26fa-33b0-7273-e03df66e6016.png)
上のクエリのmatchが条件文の開始、getの行が実行行となる。その間の3行が条件文にあたるが、これらは順不同である。また、ここで```has name "water"```としている箇所がフィルタリングの条件で、SQLにおけるWHEREとほぼ同意。代わりに```has name $pokemon_name```という風に変数を指定する事も出来、後に続く```get```に指定すればこれのみ抽出する事も可能。

今回の実行結果ではgetするものを指定しなかったので、クエリ結果に該当する全てのThingが抽出されている。よって、Entityではなくクエリ内にrelationship（pokemonとpokemon-type）も含まれているのでこれらを繋ぐ線も表示されているが、例えば上のクエリを

```bash
match
($x, $y) isa has-type;
$x isa pokemon;
$y isa pokemon-type has name "water";
get $x, $y;
```

とするとエンティティだけが抽出される。ある属性（Attribute）に$で変数定義すると、これらを抽出する事も可能。これはEntityもRelationshipもAttributeも全てThingを継承したクラスであり、Thingであればグラフで表現できるからこうなる。
####グラフの表示を変更する
さて、抽出できたがデフォルトの表示ではIDしか表示されずあまり使えない。（真ん中のpokemon-typeは一つだけなので"water"なんだろうと推測は出来るが。）そこで表示をカスタマイズしたいんだが、これは表示されているエレメントをクリックしたまま（1秒くらい）すると出てくる属性をいじれば変更する事ができる：
![pokemon_label.PNG](https://qiita-image-store.s3.amazonaws.com/0/213933/5f2e0aeb-06b2-cfbc-ea72-3ff76d963ad5.png)
まずは表示したいAttributeを選ぶことによってようやくデータ探索として使える程度になる。また色を変えることも可能。表示属性の変更はEntityにもRelationshipにも適用する事が可能で、種類が多いと非常に便利。ちょっといじると：
![pokemon_after_change.PNG](https://qiita-image-store.s3.amazonaws.com/0/213933/ea6f47e3-a450-4e04-0e3d-c269e414b57a.png)
こうなった。これで最低限名前が見れる。
####関連性を拡張する
現在はクエリ結果を表示している状態なので、各ポケモンに対する他の関連性は見えてこない。これは、Entityをダブルクリックする事によって特定ノードのRelationshipを引き出すことが出来る。グラフに表示されているラプラスをダブルクリックしてみると：
![pokemon_lapras.PNG](https://qiita-image-store.s3.amazonaws.com/0/213933/1aefde47-520e-7b52-f3b2-38d2549134f0.png)
今度は```pokemon-type:ice```も抽出された。これはラプラス（読み方あってると良いが）には水属性と氷属性の両方が備わっている事を意味する。（実際に正しいかどうかは知らないが）

ひとつここで注意しておきたいが、今回```pokemon-type:ice```が発見できたが、この作業は実行されたクエリのドメイン内においてのみ抽出される。ラプラスに例えば先祖その他Relationshipが貼られていても、このクエリでは抽出されない。

```bash
match
$x isa pokemon has name "Charmeleon";
$a ($x, $a1) isa has-type;
$c ($c1, $x) isa evolution;
$b ($x, $b1) isa evolution;
get;
```

ポケモンタイプと先祖-子孫のRelationshipを定義することにより、以下のように抽出される。ここでは同じevolutionに対し、先祖側、子孫側の両方にCharmeleonを定義しているのがポイント。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213933/9e0bd7be-5f11-2400-9463-388d387f0ae2.png)
##さいごに
今回をもって、「Grakn.aiことはじめ」は締めくくりたいと思う。

まだまだ色々紹介できていない事は沢山あり、特にGrakn最大の強みであるInference（演繹）については触れていないが、今後個別のトピックとして扱っていこうと思う。