知識グラフ入門：辛さでつながる人々

## はじめに :  Neo4jとオントロジーの世界を探る
![napkin-selection (32).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/67f797c2-7f46-efa8-73aa-842f8c3ccff7.png)

こんにちは。この記事では、「辛さでつながる人々」というユニークな視点から、知識グラフ、オントロジー、そしてNeo4jについて探っていきます。カレー好きの方も、データ分析に興味がある方も、一緒に「辛さ」を通じてデータの新しい世界を覗いてみませんか？

## 1. 知識グラフって何だろう？

まずは、知識グラフについて考えてみましょう。私が理解した限りでは、知識グラフは情報をつながりで表現する方法のようです。

例えば、こんな風に考えてみました：

- 田中さんは辛さ耐性5
- バターチキンカレーの辛さは3
- 田中さんはバターチキンカレーが好き

これらの情報を線でつないでみると、何か面白いことが見えてくるかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/1ce7b9cb-fae8-13fc-9b2d-0833c3c8e258.png)

このように、人やモノ、概念をつなげて表現するのが知識グラフの特徴のようです。複雑な関係性も直感的に表現できそうですね。

## 2. オントロジーを考えてみる

次に、オントロジーについて考えてみましょう。正直、最初は難しく感じましたが、「世界の捉え方を整理する」ことだと理解しました。

カレーの世界を例に、オントロジーを考えてみます：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/323a1963-7be9-fd7d-9540-f573215a12cf.png)

- 概念（クラス）：カレー、スパイス、人、辛さレベル
- 関係性：含む、耐性がある、好む
- 属性：カレーの辛さ度、人の辛さ耐性

このように整理すると、カレーと人の関係がより明確になった気がします。でも、これが正解というわけではなく、視点を変えれば別の整理の仕方もありそうです。

# オントロジーの本質：カレーの世界を例に

オントロジーは、特定の領域（ドメイン）における概念と関係性を形式的に表現したものです。カレーの世界を例に、オントロジーの本質的な部分を探ってみましょう。

## 1. 共通理解の基盤

オントロジーは、特定のドメインにおける「共通理解」を形式化します。

**例：** カレーの世界では、以下のような概念と関係性について共通理解を持ちます。
- カレー、スパイス、辛さ、料理人
- カレーはスパイスを含む
- 料理人はカレーを作る

## 2. 知識の明示的表現

暗黙的に理解されていることを、明示的かつ形式的に表現します。

**例：**
- カレーは料理の一種である
- カレーには必ず1つ以上のスパイスが含まれる
- 辛さはレベル1-10で表現される

## 3. 推論の可能性

オントロジーで表現された知識を基に、新たな知識を導き出すことができます。

**例：**
- もし「AさんはBカレーが好き」で「BカレーはCスパイスを使用」なら
- 「AさんはCスパイスの味を好む可能性が高い」と推論できる

## 4. 知識の再利用と共有

一度作成したオントロジーは、他のシステムや用途でも再利用できます。

**カレーのオントロジーの活用例：**
- レシピ推薦システム
- 食文化研究
- スパイス配合の最適化

## 5. 柔軟性と進化

オントロジーは固定的なものではなく、進化させていくことができます。

**進化の例：**
- 新しいカレーの種類の追加
- スパイスの効能に関する新しい知見の統合
- 地域ごとのカレー文化の違いの表現

## オントロジーの意義

オントロジーを使うことで、以下のような利点があります：

1. 複雑な知識を構造化できる
2. 人間とコンピュータの両方が「理解」できる形で表現できる
3. 知識ベースシステムや人工知能の開発に活用できる
4. 異なるシステム間でのデータ統合が容易になる

## 実践のヒント

完璧なオントロジーを一度で作ることは難しいでしょう。以下のアプローチがおすすめです：

- 小規模なオントロジーから始める
- 実際に使用しながら改善していく
- 専門家や利用者からのフィードバックを取り入れる

皆さんも、自分の専門分野や趣味の世界で、オントロジー的な考え方を試してみてはいかがでしょうか。知識の整理や新しい発見につながるかもしれません。

## 3. Neo4jを使ってみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/e4733f37-ebd3-def7-a8fa-f8532403ea80.png)

さて、ここからはNeo4jというデータベースを使って、実際にデータを扱ってみましょう。Neo4jは、先ほどの知識グラフのような構造をそのまま扱えるデータベースだそうです。

まずは、データを入れてみます：

```cypher
CREATE (p:Person {name: '田中', spiceTolerance: 5})
CREATE (c:Curry {name: 'バターチキンカレー', spiciness: 3})
CREATE (p)-[:LIKES]->(c)
```

これで、田中さんとバターチキンカレーの関係が表現できました。

次に、こんなクエリを試してみました：

```cypher
MATCH (p:Person)-[:LIKES]->(c:Curry)
WHERE p.spiceTolerance >= c.spiciness
RETURN p.name, c.name
```

このクエリで、人とカレーの関係性の情報を見つけられそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/dacad0a8-a425-949f-7d50-820d2823ca58.png)


## 4. システム化への挑戦：目的から考える

ここまで来たら、実際にシステムを作ってみたくなりました。「辛さでつながる人々」というアイデアを形にするには、どうすればいいでしょうか。

### 4.1 目的を考える

まずは目的を明確にしてみます：

- カレー好きの人々をつなげたい
- 個人に合ったカレーを推薦したい

### 4.2 必要そうな機能を考える

目的を実現するために、こんな機能があれば良さそうです：

1. ユーザーの辛さ耐性を登録する機能
2. カレーの辛さレベルを管理する機能
3. ユーザーの好みのカレーを記録する機能
4. カレーを推薦する機能
5. 似た嗜好のユーザーをマッチングする機能

### 4.3 データの整理を試みる

これらの機能を実現するために、どんなデータが必要か考えてみました：

- ユーザー情報（名前、辛さ耐性レベル）
- カレー情報（名前、辛さレベル、主要スパイス）
- ユーザーとカレーの関係（好み、食べた経験）
- スパイス情報（名前、辛さへの貢献度）

### 4.4 データの関係性を整理する

これらのデータがどう関連しているか、図で表現してみました：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/35572d10-5df3-e882-7790-e0c73ffb58f9.png)


### 4.5 Neo4jでの実装を試みる

これらの関係性をNeo4jで表現してみます：

```cypher
// 人物データの追加
CREATE (p1:Person {name: '田中', spiceTolerance: 7})
CREATE (p2:Person {name: '佐藤', spiceTolerance: 3})
CREATE (p3:Person {name: '鈴木', spiceTolerance: 8})
CREATE (p4:Person {name: '高橋', spiceTolerance: 5})
CREATE (p5:Person {name: '渡辺', spiceTolerance: 6});

// カレーデータの追加
CREATE (c1:Curry {name: 'バターチキンカレー', spiceLevel: 3})
CREATE (c2:Curry {name: 'ビンダルーカレー', spiceLevel: 8})
CREATE (c3:Curry {name: 'グリーンカレー', spiceLevel: 6})
CREATE (c4:Curry {name: 'マッサマンカレー', spiceLevel: 4})
CREATE (c5:Curry {name: 'ティッカマサラ', spiceLevel: 5});

// 関係性の追加
MATCH (p:Person), (c:Curry)
WHERE (p.name = '田中' AND c.name IN ['ビンダルーカレー', 'グリーンカレー']) OR
      (p.name = '佐藤' AND c.name IN ['バターチキンカレー', 'マッサマンカレー']) OR
      (p.name = '鈴木' AND c.name IN ['ビンダルーカレー', 'ティッカマサラ']) OR
      (p.name = '高橋' AND c.name IN ['グリーンカレー', 'マッサマンカレー']) OR
      (p.name = '渡辺' AND c.name IN ['バターチキンカレー', 'ティッカマサラ'])
CREATE (p)-[:LIKES]->(c);
```

### 4.6 クエリを試してみる

Neo4jブラウザを使用している場合、以下のクエリでグラフを可視化できます：

```cypher
MATCH (p:Person)-[r:LIKES]->(c:Curry)
RETURN p, r, c
```

このクエリを実行すると、Neo4jブラウザはグラフ表示モードに切り替わり、ノードと関係性が視覚的に表示されます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/58a45e50-c6ae-b42e-772d-23d98f35f3f5.png)


特定の人物に焦点を当てた可視化も可能です：

```cypher
MATCH (p:Person {name: '田中'})-[r:LIKES]->(c:Curry)
RETURN p, r, c
```

これにより、田中さんとその好みのカレーの関係が視覚化されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/4c489685-4483-52c4-a602-dcdf27d4d87b.png)

```cypher
// ユーザーの辛さ耐性に合うカレーを探す
MATCH (p:Person {name: '田中'}), (c:Curry)
WHERE c.spiceLevel <= p.spiceTolerance
RETURN c.name AS RecommendedCurry, c.spiceLevel
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/f71825cf-5e7d-b0f5-aa22-d380da7c44c0.png)

```cypher
// 似た辛さ耐性を持つユーザーを見つける
MATCH (p1:Person {name: '田中'}), (p2:Person)
WHERE p1 <> p2 AND abs(p1.spiceTolerance - p2.spiceTolerance) <= 1
RETURN p2.name AS SimilarUser, p2.spiceTolerance
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/8e4a4d72-3dfb-c90f-b1f2-0a8d1d3abb17.png)

## まとめ：辛さでつながる知識の世界を作る試み

![napkin-selection (33).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/c639a66a-e1c0-f31d-36d2-ddebe37f233b.png)

「辛さでつながる人々」というアイデアから出発し、目的を定め、必要なデータを整理し、関係性を図示し、そしてデータベースに実装するまでの過程を辿ってみました。

この過程を通じて、個人的に感じたのは、知識グラフの構築には多様なアプローチがありうるということです。目的や状況に応じて柔軟に設計し、試行錯誤しながら改善していくことが重要かもしれません。もちろん、これは私の限られた経験からの気づきに過ぎず、他にも様々な方法や考え方があるかもしれません。

今回の例は、カレーと辛さという特定のテーマに基づいていましたが、この考え方は他の分野にも応用できる可能性があります。例えば：

1. 音楽の好みでつながる人々の知識グラフ
2. 旅行経験に基づいた観光地推薦システム
3. 専門知識や技能のマッチングシステム

皆さんも、興味のある分野で「つながり」を見出し、知識グラフ化を試みてみてはいかがでしょうか。そうすることで、データを見る新しい視点が得られるかもしれません。また、皆さんの経験から、今回とは異なるアプローチや気づきが生まれるかもしれません。