astamuse Lab

astamuse Labとは、アスタミューゼのエンジニアとデザイナーのブログです。アスタミューゼの事業・サービスを支えている知識と舞台裏の今を発信しています。

DB3分クッキング Neo4jではじめるグラフデータベース入門

f:id:astamuse:20180123182120j:plain

こんにちは、福田 a.k.a. FDKです。

バルトークのアレグロ・バルバロを聴きながらバルクロードを実行しています。

点と点をこねくり回していると、イノヴェイションが生まれることがあります。

そう、まさに “Connecting the Dots” の瞬間です。

はじめに

グラフは、点と点を線で繋いだ構造で、この世界の至るところに見られます。 点同士を結ぶ線に向きや重みを持たせて関係性を表現することで、様々な探索ができるようになります。

例えば、SNS。人を点、友達関係を線で表し、友達関係の連鎖を辿り新たな関係を知るといったことはイメージしやすいと思います。

ボキャブラリ。わたしたちがものごとを考えるとき、言葉は欠かせません。キーワード同士にも何らかの関係があり、豊かな語彙は文脈とともに思索の飛び石となります。

ここでは、特許文書に現れるキーワードとその近接関係、そしてキーワードが現れる文脈との関係データをグラフ化して探索をしてみます。

Neo4jとは

グラフデータベースは、グラフ構造のデータの格納と検索に特化したデータベースです。商用、オープンソース、様々なプロダクトがあり、広く使われています。

Neo4jは、Neo Technology社により開発されたデータベースで、2010年にバージョン1.0がリリースされました。2018年1月23日時点での最新の安定バージョンは3.3.2です。

特徴として以下があげられます。

  • Cypherと呼ばれる宣言型グラフ向けクエリ言語
  • ACIDトランザクションのサポート
  • プロパティグラフ(点と線それぞれにkey-valueの形式で複数の属性を持たせられる)
  • Javaで実装されている
  • Boltというバイナリプロトコル(3.0以降)
  • 豊富なドライバ(.NET、Java、JavaScript、Python、Ruby、 PHP、R、Go、Erlang、C/C++、Clojure、Perl, Haskellなど)
  • 内部的にLuceneを使用
  • コミュニティ版とエンタープライズ版
  • GPLv3 及び AGPLv3 / 商用

*1

レシピ編

データ

  • キーワードのデータ(4,722,057行)
  • キーワード同士の関連データ(136,802,075行)
  • 課題文脈のデータ(22,444行)
  • キーワードと課題の関連データ(114,832,650行)

手元の実験用テストデータ。日本国内特許公報データをもとに、Hadoop、Word2vecなどを使って生成したデータになります。アスタミューゼにはデータがたくさんあり、データからデータを生成できます。

環境・ミドルウェア

  • GCP n1-highmem-8 preemptible*2 (8 vCPU, 52GB RAM, SSD storage 100 GB)
  • Linux (Ubuntu 16.04.3 LTS)
  • Neo4j 3.4.0 alpha06*3

設計

Neo4jで扱うプロパティグラフの形式に落とし込みます。

まず、キーワードと、課題文脈のデータ*4をNodeに対応させます。

そして、Node同士の関係をRelationshipに対応させます。関係の向きと重み、ラベルを定義します。

角丸の四角がNode(点)、矢印がRelation(線)になります。

f:id:astamuse:20180123193603p:plain

準備編

マニュアル*5を参照しながらセットアップします。

ここではUbuntu 16.04.3 LTSにNeo4j 3.4.0 alpha06をインストールします。

インストール

$ wget -O - https://debian.neo4j.org/neotechnology.gpg.key | sudo apt-key add -
$ echo 'deb http://debian.neo4j.org/repo testing/' | sudo tee -a /etc/apt/sources.list.d/neo4j.list
$ sudo apt-get update
$ sudo apt-get install neo4j=3.4.0.alpha06

*6

設定

設定ファイル/etc/neo4j/neo4j.confの編集

35,36c35,36
< #dbms.memory.heap.initial_size=512m
< #dbms.memory.heap.max_size=512m
---
> dbms.memory.heap.initial_size=16G
> dbms.memory.heap.max_size=16G
46c46
< #dbms.memory.pagecache.size=10g
---
> dbms.memory.pagecache.size=32g
54c54
< #dbms.connectors.default_listen_address=0.0.0.0
---
> dbms.connectors.default_listen_address=0.0.0.0
< #dbms.threads.worker_count=
---
> dbms.threads.worker_count=8

調理編

CSVの作成

Neo4jには大量のデータをCSVから効率良くロードするためのneo4j-admin importコマンド*7があります。このコマンドはデータの初期ロード専用で、データベースディレクトリが空でないと実行できませんが、高速にデータをロードできます。既存のデータベースへのデータのバルクロードには別途LOAD CSVコマンド*8を使用します。

Node、RelationshipのCSVファイルを複数用意し、一括でロードします。それぞれのCSVファイルのヘッダに、ロード先のスキーマを表現します。詳しくはマニュアル*9にあります。

ここでは、前述の設計に従って、CSVファイルを用意します。

keyword.csv:KeywordのNodeデータ

id:ID(Keyword-ID),name:string,:LABEL
12852111,プリプリ感,Keyword
115168,プリプレグ,Keyword
10515289,プリプレグFRPシート,Keyword
10515208,プリプレグアセンブリ,Keyword
12852112,プリプレグカセット,Keyword
10515209,プリプレグクロス,Keyword
10515210,プリプレグシート,Keyword

issue_fterm_context.csv:FTermのNodeデータ

id:ID(FTerm-ID),code,context,:LABEL
1,2B022EA00,植物の栽培/化学物質の処理目的,FTerm
2,2B022EA01,植物の栽培/化学物質の処理目的/生長調節,FTerm
3,2B022EA02,植物の栽培/化学物質の処理目的/生長調節/種なし果実の作成,FTerm
4,2B022EA03,植物の栽培/化学物質の処理目的/果実、野菜の食味、色付きの向上,FTerm
5,2B022EA10,植物の栽培/化学物質の処理目的/その他,FTerm
6,2B026BB00,海藻の栽培/支柱の目的、機能,FTerm
7,2B026BB01,海藻の栽培/支柱の目的、機能/強度を増す,FTerm
8,2B026BB02,海藻の栽培/支柱の目的、機能/打ち込み引きぬき,FTerm
9,2B026BB03,海藻の栽培/支柱の目的、機能/倒伏防止,FTerm

Nodeデータのフォーマットは、(属性[:型],)+:LABELのような形になります。:IDは識別子であることを表し、Node毎に必ず指定します。:IDの後ろの(Keyword-ID)は、IDの名前空間を指定しています。デフォルトではNodeの名前空間は一つになります。リレーショナル・データベースでよくみられるように数値型のIDを持つエンティティが複数ある場合には、それぞれのIDの名前空間を分ける必要があります。

similarity.csv:SIMILAR_TOのRelationsipデータ

:START_ID(Keyword-ID),score:double,:END_ID(Keyword-ID),:TYPE
14384010,0.846703052521,14251003,SIMILAR_TO
14164776,0.840930700302,14251003,SIMILAR_TO
11690273,0.817037463188,14251003,SIMILAR_TO
10211878,0.808667063713,14251003,SIMILAR_TO
10446057,0.798547029495,14251003,SIMILAR_TO
13343895,0.795734345913,14251003,SIMILAR_TO
14335569,0.789334237576,14251003,SIMILAR_TO
12207055,0.788067042828,14251003,SIMILAR_TO
12698152,0.784716844559,14251003,SIMILAR_TO

keyword_issue.csv:RESOLVEのRelationshipデータ

:START_ID(Keyword-ID),n:int,:END_ID(FTerm-ID),:TYPE
12338970,1,2,RESOLVE
42045,1,2,RESOLVE
10181692,1,2,RESOLVE
12637528,1,2,RESOLVE
12676513,1,2,RESOLVE
109171,1,2,RESOLVE
10799840,1,2,RESOLVE
13335687,1,2,RESOLVE
11029079,8,2,RESOLVE

データロード

そして、以下のような簡易ロードスクリプトを用意しました。

#!/bin/bash

systemctl stop neo4j

rm -rf /var/lib/neo4j/data/databases/graph.db/*

NEO4J_DEBUG=true HEAP_SIZE=16g neo4j-admin import --nodes issue_fterm_context.csv --nodes keyword.csv --relation
ships similarity.csv --relationships keyword_issue.csv --ignore-missing-nodes=true --ignore-duplicate-nodes=true
-id-type=INTEGER

chown -R neo4j:neo4j /var/lib/neo4j/data/databases/graph.db/

systemctl start neo4j

実行すると、進捗とサマリーが表示されます。

Neo4j version: 3.4.0-alpha06
Importing the contents of these files into /var/lib/neo4j/data/databases/graph.db:
Nodes:
 /var/tmp/blog/issue_fterm_context.csv

 /var/tmp/blog/keyword.csv
Relationships:
 /var/tmp/blog/similarity.csv

 /var/tmp/blog/keyword_issue.csv

Available resources:
 Total machine memory: 51.10 GB
 Free machine memory: 49.98 GB
 Max heap memory : 15.33 GB
 Processors: 8
 Configured max memory: 31.18 GB

Import starting 2018-01-23 04:05:24.396+0000
 Estimated number of nodes: 7.29 M
 Estimated number of node properties: 14.63 M
 Estimated number of relationships: 145.48 M
 Estimated number of relationship properties: 145.48 M
 Estimated disk space usage: 10.86 GB
 Estimated required memory usage: 569.89 MB

Interactive command list (end with ENTER):
 c: Print more detailed information about current stage
 i: Print more detailed information

(1/4) Node import 2018-01-23 04:05:24.418+0000
 Estimated number of nodes: 7.29 M
 Estimated disk space usage: 710.50 MB
 Estimated required memory usage: 569.89 MB
.......... .......... .......... .......... .......... 5%
.......... .......... .......... .......... .......... 10%
.......... .......... .......... .......... .......... 15%
.......... .......... .......... .......... .......... 20%
.......... .......... .......... .......... .......... 25%
.......... .......... .......... .......... .......... 30%
.......... .......... .......... .......... .......... 35%
.......... .......... .......... .......... .......... 40%
.......... .......... .......... .......... .......... 45%
.......... .......... .......... .......... .......... 50%
.......... .......... .......... .......... .......... 55%
.......... .......... .......... .......... .......... 60%
.......... .......... .......... .......... .......... 65%
.......... .......... .......... .......... .......... 70%
.......... .......... .......... .......... .......... 75%
.......... .......... .......... .......... .......... 80%
.......... .......... .......... .......... .......... 85%
.......... .......... .......... .......... .......... 90%
.......... .......... .......... .......... .......... 95%
.......... .......... .......... .......... .......... 100%

(2/4) Relationship import 2018-01-23 04:05:29.298+0000
 Estimated number of relationships: 145.48 M
 Estimated disk space usage: 10.16 GB
 Estimated required memory usage: 534.38 MB
.......... .......... .......... .......... .......... 5%
.......... .......... .......... .......... .......... 10%
.......... .......... .......... .......... .......... 15%
.......... .......... .......... .......... .......... 20%
.......... .......... .......... .......... .......... 25%
.......... .......... .......... .......... .......... 30%
.......... .......... .......... .......... .......... 35%
.......... .......... .......... .......... .......... 40%
.......... .......... .......... .......... .......... 45%
.......... .......... .......... .......... .......... 50%
.......... .......... .......... .......... .......... 55%
.......... .......... .......... .......... .......... 60%
.......... .......... .......... .......... .......... 65%
.......... .......... .......... .......... .......... 70%
.......... .......... .......... .......... .......... 75%
.......... .......... .......... .......... .......... 80%
.......... .......... .......... .......... .......... 85%
.......... .......... .......... .......... .......... 90%
.......... .......... .......... .......... .......... 95%
.......... .......... .......... .......... .........(3/4) Relationship linking 2018-01-23 04:08:40.284+0000
 Estimated required memory usage: 527.90 MB
.......... .......... .......... .......... .......... 5%
.......... .......... .......... .......... .......... 10%
.......... .......... .......... .......... .......... 15%
.......... .......... .......... .......... .......... 20%
.......... .......... .......... .......... .......... 25%
.......... .......... .......... .......... .......... 30%
.......... .......... .......... .......... .......... 35%
.......... .......... .......... .......... .......... 40%
.......... .......... .......... .......... .......... 45%
.......... .......... .......... .......... .......... 50%
.......... .......... .......... .......... .......... 55%
.......... .......... .......... .......... .......... 60%
.......... .......... .......... .......... .......... 65%
.......... .......... .......... .......... .......... 70%
.......... .......... .......... .......... .......... 75%
.......... .......... .......... .......... .......... 80%
.......... .......... .......... .......... .......... 85%
.......... .......... .......... .......... .......... 90%
.......... .......... .......... .......... .......... 95%
.......... .......... .......... .......... .......... 100%

(4/4) Post processing 2018-01-23 04:09:46.174+0000
 Estimated required memory usage: 478.13 MB
.......... .......... .......... .......... .......... 5%
.......... .......... .......... .......... .......... 10%
.......... .......... .......... .......... .......... 15%
.......... .......... .......... .......... .......... 20%
.......... .......... .......... .......... .......... 25%
.......... .......... .......... .......... .......... 30%
.......... .......... .......... .......... .......... 35%
.......... .......... .......... .......... .......... 40%
.......... .......... .......... .......... .......... 45%
.......... .......... .......... .......... .......... 50%
.......... .......... .......... .......... .......... 55%
.......... .......... .......... .......... .......... 60%
.......... .......... .......... .......... .......... 65%
.......... .......... .......... .......... .......... 70%
.......... .......... .......... .......... .......... 75%
.......... .......... .......... .......... .......... 80%
.......... .......... .......... .......... .......... 85%
.......... .......... .......... .......... .......... 90%
.......... .......... .......... .......... .......... 95%
.......... .......... .......... .......... .......... 100%


IMPORT DONE in 4m 35s 487ms.  
Imported:
 4744499 nodes
 145399772 relationships
 154911213 properties
Peak memory usage: 632.11 MB

4分半程でロードが完了しました。単純計算で約93万行/秒のスループットです。

また、以前のバージョンよりも表示がわかりやすく、進捗の視認性がよくなっています。

インデックスの作成

neo4j-admin importで初期ロードしたデータには、インデックスは作成されていないため、個別に作成します。

cypher-shellというインタラクティブなシェルを使います。*10

$ cypher-shell  
username: neo4j
password: ********
Connected to Neo4j 3.4.0-alpha06 at bolt://localhost:7687 as user neo4j.
Type :help for a list of available commands or :exit to exit the shell.
Note that Cypher queries must end with a semicolon.
neo4j> MATCH (k: Keyword {name: "プリプレグ"}) RETURN k;
+----------------------------------------+
| k                                      |
+----------------------------------------+
| (:Keyword {name: "プリプレグ", id: 115168}) |
+----------------------------------------+

1 row available after 113 ms, consumed after another 4509 ms
neo4j> MATCH (k: Keyword {name: "プリプレグ"}) RETURN k;
+----------------------------------------+
| k                                      |
+----------------------------------------+
| (:Keyword {name: "プリプレグ", id: 115168}) |
+----------------------------------------+

1 row available after 5 ms, consumed after another 3888 ms
neo4j> CREATE INDEX ON :Keyword(name);
0 rows available after 54 ms, consumed after another 0 ms
Added 1 indexes

CREATE INDEXを実行すると、インデックスは非同期で作成されます。

ステータスはログに出力されます。

2018-01-23 04:13:24.092+0000 INFO [o.n.k.i.a.i.IndexPopulationJob] Index population started: [:Keyword(name) [pr
ovider: {key=lucene+native, version=1.0}]]
2018-01-23 04:13:40.480+0000 INFO [o.n.k.i.a.i.IndexPopulationJob] Completed node store scan. Flushing all pendi
ng updates.
BatchingMultipleIndexPopulator{activeTasks=5, executor=java.util.concurrent.ThreadPoolExecutor@2b76dd88[Running,
pool size = 7, active threads = 5, queued tasks = 0, completed tasks = 468], batchedUpdates = [0 updates], queu
edUpdates = 0}
2018-01-23 04:13:40.481+0000 INFO [o.n.k.i.a.i.IndexPopulationJob] Shutting down executor.
BatchingMultipleIndexPopulator{activeTasks=5, executor=java.util.concurrent.ThreadPoolExecutor@2b76dd88[Running,
pool size = 7, active threads = 5, queued tasks = 0, completed tasks = 469], batchedUpdates = [0 updates], queu
edUpdates = 0}
2018-01-23 04:13:46.163+0000 INFO [o.n.k.i.a.i.IndexPopulationJob] Index population completed. Index is now onli
ne: [:Keyword(name) [provider: {key=lucene+native, version=1.0}]]

インデックスの作成が完了したところで、再度検索してみます。

neo4j> MATCH (k: Keyword {name: "プリプレグ"}) RETURN k;
+----------------------------------------+
| k                                      |
+----------------------------------------+
| (:Keyword {name: "プリプレグ", id: 115168}) |
+----------------------------------------+

1 row available after 62 ms, consumed after another 1 ms
neo4j> MATCH (k: Keyword {name: "プリプレグ"}) RETURN k;
+----------------------------------------+
| k                                      |
+----------------------------------------+
| (:Keyword {name: "プリプレグ", id: 115168}) |
+----------------------------------------+

1 row available after 2 ms, consumed after another 1 ms
neo4j>

試食編

プリプレグ

ところで、「プリプレグ」とは何でしょう。食べ物ではなさそうです。あまり耳馴染みがない方も多いかもしれません。私もその一人です。

初めて聞くキーワードを、周辺のキーワードと、キーワードが寄与している文脈から、おおよその見当をつけられるかもしれません。

早速、WebUI*11にアクセスし、クエリを実行してみます。

MATCH (k:Keyword {name: "プリプレグ"})-[s:SIMILAR_TO *1..3]-(l) RETURN DISTINCT s,l,k LIMIT 10

f:id:astamuse:20180123191853p:plain

朧げながら、プリプレグの人となりが見えてきます。わりと硬派な印象です。

今度は、周辺のキーワードに手を伸ばしつつ、関連する課題を探索してみます。

MATCH (k:Keyword {name: "プリプレグ"})-[s:SIMILAR_TO]-(l:Keyword)
WITH k, s, l ORDER BY s.score DESC LIMIT 100
MATCH (k)-[s]-(l)-[r:RESOLVE]->(f:FTerm)
WITH DISTINCT k, s, l, r, f ORDER BY r.n DESC LIMIT 20
RETURN k, s, l, r, f

グラフ表示

f:id:astamuse:20180123183837p:plain

テキスト表示

╒════════════════════════════╤════════════════════════╤═══════════════════════════════╤════════╤══════════════════════════════════════════════════════════════════════╕
│"k"                         │"s"                     │"l"                            │"r"     │"f"                                                                   │
╞════════════════════════════╪════════════════════════╪═══════════════════════════════╪════════╪══════════════════════════════════════════════════════════════════════╡
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":50}│{"context":"接着剤、接着方法/物理(化学)的性質又は目的、効果/機械的特性","code":"4J040LA06","id":1│
│                            │                        │                               │        │4260}                                                                 │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":45}│{"context":"接着剤、接着方法/物理(化学)的性質又は目的、効果/電気磁気特性","code":"4J040LA09","id":│
│                            │                        │                               │        │14263}                                                                │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":45}│{"context":"接着剤、接着方法/物理(化学)的性質又は目的、効果/温度特性又は熱特性","code":"4J040LA08","i│
│                            │                        │                               │        │d":14262}                                                             │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":43}│{"context":"多層プリント配線板の製造/目的課題効果/機械的特性に関するもの","code":"5E346HH11","id":1│
│                            │                        │                               │        │7583}                                                                 │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":30}│{"context":"接着剤、接着方法/物理(化学)的性質又は目的、効果/分子量又はその関連特性","code":"4J040LA01",│
│                            │                        │                               │        │"id":14255}                                                           │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":29}│{"context":"電場又は磁場に対する装置又は部品の遮蔽/目的/電(磁)波シールド電磁シールド","code":"5E321GG05"│
│                            │                        │                               │        │,"id":17466}                                                          │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":29}│{"context":"印刷回路の非金属質の保護被覆/目的効果/その他","code":"5E314GG26","id":17427}   │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.584715306759}│{"name":"ワニス","id":145746}     │{"n":29}│{"context":"電動機、発電機の製造/目的/製造,組立","code":"5H615AA01","id":20027}       │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":28}│{"context":"印刷回路に対する電気部品等の電気的接続/目的効果/はんだ付け性の改良","code":"5E319GG03","id│
│                            │                        │                               │        │":17455}                                                              │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":27}│{"context":"多層プリント配線板の製造/目的課題効果/製造生産に関するもの/歩留生産性の向上","code":"5E346HH33│
│                            │                        │                               │        │","id":17596}                                                         │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":26}│{"context":"接着剤、接着方法/物理(化学)的性質又は目的、効果/結晶関連特性","code":"4J040LA02","id":│
│                            │                        │                               │        │14256}                                                                │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.791278362274}│{"name":"積層板","id":348376}     │{"n":25}│{"context":"プリント基板への印刷部品(厚膜薄膜部品)/目的,効果/その他","code":"4E351GG20","id":13│
│                            │                        │                               │        │245}                                                                  │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":25}│{"context":"電動機、発電機の製造/目的/製造,組立","code":"5H615AA01","id":20027}       │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.791278362274}│{"name":"積層板","id":348376}     │{"n":23}│{"context":"プリント配線の製造(2)/目的効果/密着性の改良/導体とプリント板の基板","code":"5E343GG02","│
│                            │                        │                               │        │id":17545}                                                            │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":23}│{"context":"多層プリント配線板の製造/目的課題効果/電気的特性に関するもの/電気的接続性","code":"5E346HH07"│
│                            │                        │                               │        │,"id":17581}                                                          │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":20}│{"context":"繊維製品への有機化合物の付着処理/目的,効果/接着","code":"4L033AC11","id":14648} │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":19}│{"context":"多層プリント配線板の製造/目的課題効果/その他","code":"5E346HH40","id":17597}   │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.791278362274}│{"name":"積層板","id":348376}     │{"n":17}│{"context":"多層プリント配線板の製造/目的課題効果/機械的特性に関するもの","code":"5E346HH11","id":1│
│                            │                        │                               │        │7583}                                                                 │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":17}│{"context":"印刷回路の非金属質の保護被覆/目的効果/生産性向上","code":"5E314GG24","id":17426} │
├────────────────────────────┼────────────────────────┼───────────────────────────────┼────────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"プリプレグ","id":115168}│{"score":0.641988456249}│{"name":"熱硬化性樹脂","id":13947024}│{"n":15}│{"context":"半導体又は固体装置の封緘,被覆構造と材料/用途又は特殊目的/光半導体用","code":"4M109GA01","i│
│                            │                        │                               │        │d":14812}                                                             │
└────────────────────────────┴────────────────────────┴───────────────────────────────┴────────┴──────────────────────────────────────────────────────────────────────┘

クエリの結果を解釈して評価するためには、別途何らかの判断基準が必要そうです。

門外漢の私には少々荷が重いので、いささか心得のある、ラーメンというキーワードに換えてクエリを実行してみることにします。

ラーメン

MATCH (k:Keyword {name: "ラーメン"})-[s:SIMILAR_TO]-(l:Keyword)
WITH k, s, l ORDER BY s.score DESC LIMIT 100
MATCH (k)-[s]-(l)-[r:RESOLVE]->(f:FTerm)
WITH DISTINCT k, s, l, r, f ORDER BY r.n DESC LIMIT 20
RETURN k, s, l, r, f

グラフ表示 f:id:astamuse:20180123183933p:plain

テキスト表示

╒═══════════════════════════╤════════════════════════╤═══════════════════════════════════╤═══════╤══════════════════════════════════════════════════════════════════════╕
│"k"                        │"s"                     │"l"                                │"r"    │"f"                                                                   │
╞═══════════════════════════╪════════════════════════╪═══════════════════════════════════╪═══════╪══════════════════════════════════════════════════════════════════════╡
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":3}│{"context":"包装体/目的,機能(1)特定の環境の維持/その他/包装体/その他/包装体/その他/包装体/その他","code":"│
│                           │                        │                                   │       │3E067GD10","id":5974}                                                 │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.336226522923}│{"name":"喫食用容器入り冷凍麺","id":13427756}│{"n":3}│{"context":"穀類誘導製品3(麺類)/目的/即席化","code":"4B046LC11","id":12085}        │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":2}│{"context":"食品の保存(凍結・冷却・乾燥を除く)/使用目的/抗微生物","code":"4B021MC01","id":1180│
│                           │                        │                                   │       │3}                                                                    │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.492829829454}│{"name":"ゲル状調味料","id":10169798}    │{"n":2}│{"context":"ゼリ−、ジャム、シロップ/目的/テクスチャーの改善","code":"4B041LC03","id":12012} │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.492829829454}│{"name":"ゲル状調味料","id":10169798}    │{"n":2}│{"context":"種実、スープ、その他の食品/目的/味,香りの改善","code":"4B036LC01","id":11983}  │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":2}│{"context":"袋/目的機能/内容物の保存性向上","code":"3E064EA18","id":5883}           │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":1}│{"context":"肉類、卵、魚製品/目的/呈味の改善","code":"4B042AC03","id":12021}         │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":1}│{"context":"高周波加熱[構造]/目的/電磁波の漏洩防止","code":"3K090LA04","id":10994}     │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":1}│{"context":"肉類、卵、魚製品/目的/保存性の改善","code":"4B042AC06","id":12024}        │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":1}│{"context":"基本的包装技術VII(真空包装)/目的/その他","code":"3E053JA10","id":5838}    │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":1}│{"context":"高周波加熱[構造]/目的/加熱効率向上又は省電力","code":"3K090AA02","id":10977}  │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":1}│{"context":"基本的包装技術VII(真空包装)/目的/高速化","code":"3E053JA01","id":5829}    │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":1}│{"context":"袋/目的機能/その他","code":"3E064EA30","id":5888}                 │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":1}│{"context":"基本的包装技術VII(真空包装)/目的/ガス置換率の向上","code":"3E053JA03","id":5831│
│                           │                        │                                   │       │}                                                                     │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":1}│{"context":"袋/目的機能/排出容易性","code":"3E064EA12","id":5877}               │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":1}│{"context":"袋/目的機能/経済性","code":"3E064EA01","id":5867}                 │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":1}│{"context":"加熱調理器/目的、効果/衛生性、外観","code":"4B055BA51","id":12144}        │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":1}│{"context":"誘導加熱調理器/目的、効果〔回路装置〕/回路素子/インバータ/表示,監視装置/誘導加熱調理器/非物理量※/基準値/構│
│                           │                        │                                   │       │造対象の処理態様※/使い勝手,判り易さ","code":"3K051AD39","id":10504}                   │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":1}│{"context":"包装体/目的,機能(1)特定の環境の維持/その他/包装体/その他/包装体/その他/包装体/風味,香気保持","cod│
│                           │                        │                                   │       │e":"3E067GD02","id":5966}                                             │
├───────────────────────────┼────────────────────────┼───────────────────────────────────┼───────┼──────────────────────────────────────────────────────────────────────┤
│{"name":"ラーメン","id":137294}│{"score":0.617753505707}│{"name":"包装食品","id":10958102}      │{"n":1}│{"context":"食品の調整及び処理一般/目的/その他","code":"4B035LC16","id":11981}        │
└───────────────────────────┴────────────────────────┴───────────────────────────────────┴───────┴──────────────────────────────────────────────────────────────────────┘

インスタントラーメンの製造に関する課題であることがわかります。

以上、簡単ですが、グラフ構造に対してクエリを投げ、周辺の語彙と文脈を照らすことができました。

まとめ

最新のNeo4jをセットアップし、インポートツールを使用してデータの初期ロードを行いました。

特許文書から抽出したキーワード同士の関連と、キーワードが現れる文脈としての分類データのグラフを、あるキーワードを起点として探索しました。

グラフ構造は複雑で、データの量が多くなると全てを把握し見通すことは困難となり、合理的なコストで探索できることがなにより重要になってきます。その点でNeo4jは扱いやすく、一定の規模のデータに対して探索的なクエリ実行ができるので、強力な武器になりそうです。

スマートスピーカー向けに、ブレインストーミングの相手をしてくれるようなアプリケーションを開発してみても面白いかもしれません。

*1:https://neo4j.com

Neo4jをより詳しく知りたい方向けの参考書籍

グラフ型データベース入門 - Neo4jを使う Neo4jユーザーグループ

グラフデータベース ―Neo4jによるグラフデータモデルとグラフデータベース入門 Ian Robinson

O’Reilly’s Graph Databases(無料ダウンロード・英語)

*2:プリエンプティブ仮想マシンを指定することで少し余裕のあるインスタンスをリーズナブルなコストで使用できます

*3:Neo4jの2018年1月23日時点で最新のα版。安定版の最新は3.3.2です

*4:国内の特許公報文書には、案件毎に複数の分類体系のコードが付与され、特許の先行技術調査を行う際に利用されます。Fタームという分類体系もその一つです。

*5:https://neo4j.com/docs/operations-manual/current/installation/linux/

*6:安定版をインストールする場合はリポジトリのtestingをstableにします。

*7:https://neo4j.com/docs/operations-manual/current/tools/import/

*8:http://neo4j.com/docs/developer-manual/current/cypher/clauses/load-csv/

*9:https://neo4j.com/docs/operations-manual/current/tools/import/file-header-format/

*10:以前のバージョンではneo4j-shellというコマンドでした。こちらはまだ存在はしますが、cypher-shellが後継となります

*11:Web UI(デフォルトで7474ポート)にアクセスしてクエリを実行すると、ビジュアライゼーションされたグラフがきれいに表示されます。結果はテーブル形式、テキスト形式、JSONコード形式に切替えられます。また、グラフ表示でノードをダブルクリックすると周辺のノードが展開されます。クエリを投げながら探索の方向性を探るといった使い方ができます。

Copyright © astamuse company, ltd. all rights reserved.