RDFでプロパティグラフを表現する方法の最新事情

# はじめに

（この記事は[ナレッジグラフ Advent Calendar 2024](https://adventar.org/calendars/11112)の参加記事です）

一般的に、ナレッジグラフ（知識グラフ）を構築してデータベースに格納する場合、RDFかプロパティグラフ（PG）かを選択することになります。しかし、実際にはRDF-starという仕組みを利用することで、RDFでPG的な表現をすることが可能であり、代表的なRDFデータベースではすでに実装対応済みです[^1]。さらにPG用のクエリ言語openCyperでRDFデータに対するクエリを実行する技術も開発されており[^2]、両者の垣根が無くなりつつあります。

さて、この**RDF-starの草案内容が今年夏ごろに大きく更新されていた**ので、その紹介をしてみます。

### RDFとPGについて

RDFは「主語（ノード）, 述語（エッジ）, 目的語（ノードorリテラル）」の三つ組（トリプル）ですべての関係を表現します。ノードやエッジにウェブ空間における一意な識別子となるURIを利用する点が特徴的です[^3]。これまでに数多くのナレッジグラフが[Linked Open Data (LOD)](https://lod-cloud.net/)としてウェブ上に公開されており、これらはRDFデータです。そのため、LODの再利用、データの公開・共有・標準化、異種データの統合などの目的にRDFおよびRDFデータベース（トリプルストア）は適しています。さらに、オントロジーやルール言語に基づく推論を利用することで新たなトリプルを導出できる点も特徴です。

RDFについては二年前のアドベントカレンダーで書いた記事を見ていただければと思います。

https://qiita.com/s-egami/items/e7f2153015a1f79e4dd6




PGは「主語（ノード）, 述語（エッジ）, 目的語（ノード）」の三つ組（トリプル）に加えて、プロパティと呼ばれるキーバリュー（Key-Value）型の属性情報を持ちます。このプロパティはノードやエッジに付与できるため、例えば「エッジに意味ラベルだけでなく確信度を付与したい」のようなケースで直感的に記述する事ができます。Neo4jなどのグラフデータベース企業を中心としたコミュニティが成熟しているため資料が多く、各社データベース独自の機能が充実しているという特徴があります。

プロパティグラフについてはこちらの書籍がおすすめです。

https://book.mynavi.jp/ec/products/detail/id=144556



# 本題

RDF-star (旧RDF*)はトリプルを一つのリソース（ノード）として扱うことができ、他のトリプルの主語や目的語となることができます。つまり、「トリプルのトリプル」を作成することができ、これにより二項関係を超えた表現が可能です。

2022年にウェブ標準化団体W3CでRDF-starのWorking Groupが設置され[^4]、どうやら[RDF 1.2](https://www.w3.org/TR/rdf12-concepts/)の仕様として組み込まれるようです（現在はRDF 1.1）。

**この記事の本題は、RDF 1.2の現時点（2024年12月時点）でのWorking Draftによると、これまでのRDF-starの仕様からアップデートされており、いくつかの新機能があるということの紹介です。**

なお、以前のRDF-starの説明は@Adacchi3さんの下記記事でも解説されています。

https://qiita.com/Adacchi3/items/52ce93a2fdf6c7293829

---
#### 補足
RDF-starの本格的な説明の前に、RDFのシリアライゼーションフォーマットの一つ、Turtle (Terse RDF Triple Language)の記法だけ簡単に紹介します。

```turtle
PREFIX ex: <http://example.com/ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
ex:alice foaf:knows ex:bob .
<http://example.com/ns#alice> foaf:age 22 .
ex:bob foaf:age 24 ;
    foaf:name "Bob" .
```

- `PREFIX`で始まる行は名前空間とその接頭辞の定義です
- 接頭辞を利用する場合は3行目の`ex:alice`のようにURIを省略表示でき、省略表示しない場合には4行目の`<http://example.com/ns#alice>`のように`< >`で囲みます
- 4行目の`22`や6行目の`"Bob"`のようにリテラル値はURIでありません
- 5,6行目のように同じ主語のトリプルが続く場合は`;`で次のトリプルの主語を省略できます
---

## 標準のRDF構文のみでなんとかする場合

さて、RDFでは全てをトリプルで表現する必要があったため、「エッジに意味ラベルだけでなく確信度を付与したい」のようなケースでは、トリプルを[具体化（Reification）](https://www.w3.org/wiki/RdfReification)する必要がありました。

例）``ex:alice foaf:knows ex:bob``というトリプルの確信度を0.8としたい場合のReificationによる表現

![スクリーンショット 2024-12-28 2.40.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23675/71f3c278-ffda-336e-9e8b-ecdab2640102.png)

Turtle記述
```turtle
PREFIX ex: <http://example.com/ns#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
ex:statement1
    rdf:subject ex:alice ;
    rdf:predicate foaf:knows ;
    rdf:object ex:bob ;
    ex:confidence 0.8 .
```

このようにトリプル（ステートメント）の主語・述語・目的語を具体化することで、個別のトリプルに対する追加情報をいくらでも付与することが可能です。RDFの基本構文からは逸脱していないため、すべてのトリプルストアで利用可能な表現です。

しかしトリプル数が増えてしまい、クエリが若干複雑化するという課題があります。また、元の``ex:alice foaf:knows ex:bob``というトリプルは明示的には記述されていません。

## RDF-star (2024年7月まで)

RDF-starでは次のように表現します。

![スクリーンショット 2024-12-28 2.52.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23675/d4097aba-2d36-639a-910b-74e8dc8f087d.png)


Turtle-star記述
```turtle
PREFIX ex: <http://example.com/ns#>
<< ex:alice foaf:knows ex:bob >> ex:confidence 0.8 .
```

ここで、`<< ex:alice foaf:knows ex:bob >>`はQuoted Tripleと呼びます。
Quoted Tripleはトリプルでありノードでもあるため、他のトリプルの主語や目的語として使うことができます。Quoted Triple同士の関係を記述することもできます。
また、Quoted Triple内の主語や目的語にもQuoted Tripleを利用できるため、ネスト構造を表現することも可能です。
したがって、RDF-starではプロパティグラフと同等以上の表現が可能になります。

### Quoted Tripleの課題

Quoted Tripleは引用符``<< >>``で囲まれた主語、述語、目的語の組み合わせで一意的に定まります。そのため、Quoted Tripleは個別の識別子を持ちません。
しかし、データによっては主語・述語・目的語の同じ組が異なる文脈で複数回出てくることがあります。その場合、それぞれのQuoted Tripleを区別できず混同してしまうという課題があります。


## RDF-star (2024年8月〜)

現時点でのRDF-starではQuoted Tripleという名前は廃止されており、**Triple Term**という名前になったようです。そして、上記の課題を克服するために新たな機能が追加されています。

### Triple Termに識別子を付与したReified Triple

まず、Triple Termの場合は``<<( ttSubject predicate ttObject )>>``のように表現します。
``ttSubject``はTriple Term内の主語を意味します。`<<(` `)>>`で囲むようになったようですね。

さらに、Triple Termに識別子を付与したReified Tripleなるものが新しくできていました。
Reified Tripleの場合は``<< rtSubject predicate rtObject ~ reifier >>``のように表現します。`~`の後が識別子としてのURIノードになります。

![スクリーンショット 2024-12-28 3.42.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23675/da65ff48-20ce-03da-67f0-d0164a4be49e.png)


```turtle
PREFIX ex: <http://example.com/ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
<< ex:alice foaf:knows ex:bob ~ _:rei-1>> ex:confidence 0.8 .
```

なお、`reifier`としてURIが指定されない場合は空白ノード（blank node）が自動的に割り当てられます（`_:`は空白ノードの意味）
つまり、今までのQuoted Tripleの書き方をした場合はReified Tripleと認識され、その識別子は自動的に空白ノードのID（グローバルなURIではなく内部参照のためのID）が割り当てられるようです。


### rdf:reifiesでTriple Termを具体化

Triple Termに識別子を対応付けるもう一つの方法として、rdf:reifies述語を使用して目的語にTriple Termを指定することができます。

```turtle
PREFIX ex: <http://example.com/ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
_:rei-1 rdf:reifies <<( ex:alice foaf:knows ex:bob )>> .
_:rei-1 ex:confidence 0.8 .
```

これにより間接的にTriple Termを参照できるようになります。
一般的にこの構文ではTriple Termは目的語としてのみ使われるように制限されます。

ややこしいことにこの方法をReificationと呼びますが、前述の[Reification](https://www.w3.org/wiki/RdfReification)のことではなく、RDF 1.2ではrdf:reifiesを使用してTriple Termを識別することを指します。

## Annotation Syntax

厳密には2024年7月以前からAnnotation Syntaxはドラフトに組み込まれていましたが、Reified Tripleの導入に伴って少しアップデートされていたため、ここで一緒に紹介します。

Annotation Syntaxはプロパティグラフのユーザにはより理解しやすい記法で、Property Graph mode (PG-mode)とも呼ばれていました。

```turtle
PREFIX ex: <http://example.com/ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
ex:alice foaf:knows ex:bob ~ _:rei-1 {| ex:confidence 0.8 ; ex:statedBy ex:tom |} .
```

識別子付きでトリプルを作成し、アノテーションブロック`{|　|}`でkey-value形式のようなアノテーションを付与することができます。
reifierの指定がない場合は空白ノードのIDが割り当てられ、アノテーションブロックが無い場合はReified Tripleのみが作成されます。

## RDF-star対応トリプルストア

冒頭で触れましたが、既に代表的なトリプルストアでRDF-star, SPARQL-starがサポートされています。

https://w3c.github.io/rdf-star/implementations.html

しかし現時点では2024年7月以前のRDF-starへの対応にとどまっているようで、Reified Tripleなどの最新のドラフトの表現は使えないようです[^5]

上記の対応表でPG modeと記載されているトリプルストアはAnnotation Syntaxに対応しています。また、トリプルストアによっては若干異なる記法を採用している場合があります。例えばStardogでは引用符`<< >>`の構文の他に下記のような独自の構文を採用しています[^6]。

```turtle
PREFIX ex: <http://example.com/ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
ex:alice foaf:knows { ex:confidence 0.8 } ex:bob .
```

### 余談

筆者はネスト構造やQuoted Triple間の関係を含む複雑なRDF-starのデータをデータ変換なしに直接埋め込み（Embedding）できるRDF-star2Vecを昨年末に発表しました。仕様変更前なのでReified TripleではなくQuoted Tripleのときのものですが、幸い最新ドラフトでもこれまでのRDF-starの構文は使えるので、お役御免というわけでもないようです。ソフトウェア、データセットともに論文内のリンクからたどれますので、利用シーンがあればぜひご自由にお使いいただければと思います。

https://doi.org/10.1109/ACCESS.2023.3341029


# おわりに

RDFでプロパティグラフ的なデータを表現する方法としてRDF-starを紹介し、その最新ドラフトについて説明しました。細かい部分は省略してしまったので、詳細は[草案](https://www.w3.org/TR/rdf12-concepts/)を御覧ください。この後大きく仕様が変わることは無いと期待したいですが、引き続き注目していき何か変化があれば追記しようかと思います。



[^1]: RDF-star Implementations, https://w3c.github.io/rdf-star/implementations.html
[^2]: M. Schmidt, et al., openCypher over RDF: Connecting Two Worlds, *Posters, Demos, and Industry Tracks at ISWC 2024*, https://ceur-ws.org/Vol-3828/paper29.pdf
[^3]: データをLODとして公開する場合にはURIはアクセス可能である必要がありますが、そうでなければURI (URL)はアクセス不可能でも問題はなく、自分で作成した架空のURIでもよいです。
[^4]: RDF-star Working Group Charter, https://www.w3.org/2022/08/rdf-star-wg-charter/
[^5]: 全てを調べたわけではないので、もしかしたら既に対応しているのもあるかもしれません。また、この表は少し古いので、現在の状況と異なる可能性があります。
[^6]: RDFとPGのギャップを埋めるためのStardog独自の構文であり、Turtleのように見えますが標準Turtleではありません。https://docs.stardog.com/query-stardog/edge-properties
[^7]: `Graph DB`ではなく`GraphDB`の場合はOntotext社のGraphDBを指します。