takanakahiko’s blog

多分三日坊主で辞めます。

PrismDB を支える技術( LOD を理解せずとも使えるプラットフォームを目指して )

プリッカソンというコミュニティで PrismDB というものを作っています。 今回は、PrismDBを作っていく上で技術的に注力している部分を紹介しようと思います。

今回は LOD についてある程度知識のある方向けに書くので、PrismDB自体の紹介は少なめに、技術的なポイントを抑えていこうと思います。

この記事は Linked Open Data Advent Calendar 2020 の2日目の記事です。 書く人がマジで無なので、良ければご参加ください〜。 Linked Open Data 技術に関わるもの (SPARQLとか)であればご自由に参加いただけるのでぜひに〜! マジで1ツイートとかでいいから!頼みますよ!

adventar.org

PrismDB とは

PrismDB とはプリティーシリーズの情報を集約しているプラットフォームです。 ファンメイドなプラットフォームでありであり、公式とは一切の関係が無いという次第です。

という前置きを踏まえ、プリティーシリーズというアニメやゲームを展開している作品群に関する情報を集めた PrismDB というプラットフォームを皆で協力して作っています。

この PrismDB はプリッカソンというハッカソン向けに作成されたのが始まりです。 プリッカソンの参加者が LOD を勉強するところから始めるのは1日という限られた時間を使うにはあまりにも足りません。 そういった意味でも LOD や SPARQL を理解せずに利用できるという要件が必須であるのは明確でした。

それらを実現するために、PrismDBがどのような仕組みを作ったか、それを紹介できればと思います。

csv2rdf

LOD の障壁はなんと言っても、その規格の知名度の低さにあると思います。 LOD、つまりは RDF を取り扱うプロジェクトは初心者の参入障壁がぐっと引き上がってしまいます。 本リポジトリを作ったときに LOD についてある程度の知識を持っていた Contributor は僕と @banjun さんだけでした。 こういったプラットフォームはデータの数がキモですから、当然2人以外の協力も不可欠です。

そこで PrismDB では CSV to RDF を行う仕組み( csv2rdf )を作っています。 データの追加に関して RDF を意識せずに作業を行えるようにしたのです。 この csv2rdf を CI 上で実行することでデータの検証と RDF の生成を自動的に行なっています。

github.com

ではその csv2rdf について詳細を説明していこうと思います。 上記リンクの README と内容は被るのですが、

まず csv2rdf は変換処理の設定が記述された json を読むことになります。

// setting.json
{
    "subjectBaseUrl": "$BASE_URL/rdfs/characters/",
    "PredicateBaseUrl": "$BASE_URL/prism-schema.ttl#",
    "dataCsvPath": "characters.csv",
    "columnsCsvPath": "characters-columns.csv",
    "rdfType": "$BASE_URL/prism-schema.ttl#Character"
}

ここで大切なのは dataCsvPathcolumnsCsvPath です。 上記の設定では「characters.csv の 内容をRDF に変換する。列の情報は characters-columns.csv を参照されたし。」という意味となります。

それぞれの内容は以下のようになります。

// characters.csv
key,名前,かな,声優
manaka_laala,真中 らぁら,まなか らぁら,茜屋日海夏
minami_mirei,南 みれぃ,みなみ みれぃ,芹澤優
hojo_sophie,北条 そふぃ,ほうじょう そふぃ,久保田未夢
// characters-columns.csv
key,predicate
名前,name
かな,name_kana
声優,cv

また、 csv2rdf を用いて変換すると以下のようなRDFファイルが生成されます。

// output.ttl
<https://example.com/rdfs/characters/manaka_laala>
    <https://example.com/preds/name> "真中 らぁら";
    <https://example.com/preds/name_kana> "まなか らぁら";
    <https://example.com/preds/cv> "茜屋日海夏".

<https://example.com/rdfs/characters/minami_mirei>
    <https://example.com/preds/name> "南 みれぃ";
    <https://example.com/preds/name_kana> "みなみ みれぃ";
    <https://example.com/preds/cv> "芹澤優".    

<https://example.com/rdfs/characters/hojo_sophie>
    <https://example.com/preds/name> "北条 そふぃ";
    <https://example.com/preds/name_kana> "ほうじょう そふぃ";
    <https://example.com/preds/cv> "久保田未夢".

ここで大切なのは、データを追加する人は characters.csv のみを編集すれば良いという点にあります。 characters.csv は一般的なCSVデータの形になっていて、そこには LOD 側の都合が存在しません。 つまりは LOD 自体に深い理解がなくてもデータを追加する作業ができるようになりました。

また、もう一つメリットがあります。 データをプログラムから読み書きする場合に CSV の方がパッケージや Web 上のナレッジが充実しているという点です。 例えばデータの整形や他媒体からの変換のようなタスクをプログラムする際に便利ということです。

characters-columns.csv にあたるような カラム定義CSV には他にも dataType 等が指定できます。 例えば、「CSV内の特定のカラムは http://www.w3.org/2001/XMLSchema#integer にしたい」みたいなニーズを満たします。 LOD に関する設定を別の CSV で一括定義することで、入力ミス等によるデータの不整合を防ぐことができます。 これは SHACL 等を導入できていないプロジェクトには非常に有効です。

REST API

データの入力に関しては LOD の知識が不要となるような仕組みを導入していることがわかりましたね。 しかし、そのデータを使うときに実際に LOD の知識が必要になるとそれもあまり意味がなくなってきます。

そこで PrismDB は REST API を提供しています。

github.com

この API を提供するサーバは裏側では SPARQL を叩いていて、それらしい値を返しているに過ぎません。 ここで重要なのは、CSV を見たユーザが REST API のレスポンスをある程度予測できるような形式となっていることです。

先程のデータを例にあげましょう。

// characters.csv
key,名前,かな,声優
manaka_laala,真中 らぁら,まなか らぁら,茜屋日海夏
minami_mirei,南 みれぃ,みなみ みれぃ,芹澤優
hojo_sophie,北条 そふぃ,ほうじょう そふぃ,久保田未夢

これに対して、

/api/characters/ にアクセスすると以下のようなレスポンスを得ることが出来ます。

{ "results": [
    {
      "名前": "真中 らぁら",
      "かな": "まなか らぁら",
      "声優": "茜屋日海夏",
    }, {
      "名前": "南 みれぃ",
      "かな": "みなみ みれぃ",
      "声優": "芹澤優",
    }, {
      "名前": "北条 そふぃ",
      "かな": "ほうじょう そふぃ",
      "声優": "久保田未夢",
    }
] }

このようにすることで、RDF や SPARQL の概念を知ることがなくてもユーザはデータの追加とデータの活用を行うことが出来ます。 もちろん SPARQL エンドポイントは用意されているので、SPARQL を用いた高度なデータ取得も可能です。 選択肢を増やすことで利用者の増加を狙っています。

まとめ

PrismDB では、LOD プラットフォームという根幹を据えた上で、LOD技術を意識せずにデータを取り扱えるような工夫を取り入れているよ、という話でした。

ちなみにデメリットも存在しています。 例えば rdflint のようなツールを使うと rdf 内での行数が指定された上で警告が出るので、それに対応するCSV側のデータを検証する作業に時間を要します。 また、この方法で複雑な RDF を構築することを目指そうとしたり、PrismDB以外でも使えるような汎用的な変換機構を作ろうとすると、csv2rdf が RDF の再実装に近くなってしまい、必要以上に規模が大きくなってしまいます。 まだまだ課題感は感じていて随時アップデートしていきますので、今後とも頑張っていこうと思います。

初期から手伝ってくださっている @banjun さんには頭が上がりません。いつもありがとう。 またデータの追加に積極的な @sergeant118 や、 便利な活用事例を作ってくださっている @sue445 さんにも感謝です。他にも様々な方に支えていただいているのですが、キリがないのでここらへんで。