動機
シャーロック・ホームズのまだらの紐をRDFでナレッジグラフにしてSPARQLで犯人を当てようというナレッジグラフ推論チャレンジ なる素敵な企画があるそうで。
word2vecみたいに何でもかんでもベクトルにしてふわっとやるのもいいんだけど、論理構造から推論して答えを導くというアプローチのほうが説明可能性という面でが望みがある気がしている。
いまいち流行っていないのは、word2vec系の技術は導入が簡単でチュートリアルもそれなりにある一方で、ナレッジグラフの類は、なにか検索したいものに対してこれを構築するのが困難だし検索に使うSPARQLも一癖あって、なかなか敷居が高いからだろう。
何はともあれまずは日本語テキストをRDFで構造化したい。誰が何をどうしたという情報を取ろうとするとmecab,cabochaでは足りなくて述語項構造解析という技術がいるのだけど、
COTOHA API の構文解析APIでその結果が得られるのでこれを使うことにする。
ただレスポンスがJSONで直感的に使いづらいので、まずはアクセサを作ることにした。
COTOHA-NLPライブラリ
cotoha-nlp で製造中。簡単に動くところまでできたので一旦こちらで紹介する。
そのうちpypiにも登録したい。
使い方(暫定版)
$ git clone https://github.com/obilixilido/cotoha-nlp
$ cd cotoha-nlp
$ pyenv local 3.6.5
$ pipenv --three
$ PIPENV_SHELL=/bin/bash pipenv shell
$ pip install -e .
$ echo "兄の太郎は図書館に行きました" | python example/example.py --client_id [client_id] --client_secret [client secret] --developer_api_base_url https://api.ce-cotoha.com/api/dev/nlp --access_token_publish_url https://api.ce-cotoha.com/v1/oauth/accesstokens
pyenv,pipenvは導入済みの想定で。
[client_id] と [client secret] はCOTOHA APIのサイトにログインすると確認できる。
サンプルちょっと解説
# パーサを初期化
parser = Parser(client_id, client_secret, developer_api_base_url, access_token_publish_url)
# パース
s = parser.parse(input())
## 使ってみる
# 入力文そのまま
print(s.form)
#-> 兄の太郎は図書館に行きました
# 述語の文節の表記を取得
print(s.get_predicate().form)
#-> 行きました
# 述語の動作主を取得
print(s.get_predicate().get_children(filter=["agent"])[0].get_chunk_head_token().form)
#-> 太郎
# 述語の動作主を形容している語を取得
print(s.get_predicate().get_children(filter=["agent"])[0].get_chunk_head_token().get_children(filter=["nomd"])[0].form)
#-> 兄
なんとなく、親・子の関係が直感的でない気がするけど、可視化してみた結果に従った。
cabocha等の普通の係り受け構造の説明だとはツリーが逆転してる(これとか)けど、ツリー構造として捉えるならこっちのほうが自然だろうと思い。
今後
とりあえず誰が何をどうした情報が取れそうなので、適当なテキスト(青空文庫かwikipediaかな)で情報抽出してRDFにしてRDF DBに入れてみる予定。
以前 Apache Jenaを使ったことがあったけど今はAllegroGraphのほうが良いのかな?
あとcotoha-nlpもテスト等充実しないと...