
RDF・RDFS・OWL・Turtleの違いを整理して、ファイルで理解するオントロジー入門
「オントロジーを勉強し始めたけれど、RDF、RDFS、OWL、Turtleの違いが分からない」
これは、たぶんオントロジー初心者が最初につまずきやすいポイントです。少なくとも、ぼくはこれらが出てきたときに思考が止まりました。。。 なので、これらだけをザックリ解説する記事になっております。
特に混乱しやすいのが、次のような疑問です。
- RDFとOWLは別のファイル形式なのか
.ttlファイルはRDFなのかOWLなのかex:とは何を意味するのか- URIはどのように決めればよいのか
- RDF/XMLでは、なぜURIの書き方が場所によって違うのか
この記事では、社員と会社を表す小さなサンプルを使いながら、これらの関係を順番に整理します。
最初はつらいですが、がんばって途中まで読んでみてください!なんとなく、わかった気になるはずです。
そして意外だったのは、オブジェクト指向プログラミング言語を触ったことがある方々は、理解しやすいかもですので、その観点でも読んでみていただけますと幸いです。
※途中で出てくるオントロジーのファイル(.ttl)を、グラフとして可視化しそのまま編集できる VSCode Extension を公開していますので、こちらも合わせて使っていただくと、よりイメージがわきやすいかもしれませんので、せひ使ってみてください!
全体像を理解する
まず、RDF、RDFS、OWL、Turtleは、すべて同じ種類のものではありません。
一言で整理すると、次のようになります。
RDF :情報をグラフとして表すためのデータモデル
RDFS :クラスや継承関係を定義する基本的なスキーマ
OWL :より高度な意味や論理関係を定義するオントロジー言語
Turtle :RDFグラフをテキストで書くための記法
.ttl :Turtleで書かれたファイルの拡張子
RDFでは、情報を「主語・述語・目的語」の3要素で表します。これをトリプルと呼びます。
たとえば、
山田はABC社に勤務している
という情報は、次のように表せます。
山田 ── worksFor ──> ABC
Turtleでは、次のように書きます。
@prefix ex: <https://example.com/company#> .
ex:yamada ex:worksFor ex:abc .
ex:は省略記号です。
ex:yamada
は、実際には次のIRIを表します。
https://example.com/company#yamada
同様に、ex:worksForも次のIRIに展開されます。
https://example.com/company#worksFor
ここで重要なのは、Turtleはあくまで「書き方」だという点です。
同じRDFグラフを、RDF/XMLで書くこともできます。
<rdf:Description rdf:about="https://example.com/company#yamada">
<ex:worksFor
rdf:resource="https://example.com/company#abc"/>
</rdf:Description>
TurtleとRDF/XMLは見た目が異なりますが、どちらも同じRDFトリプルを表せます。
RDFSを使うと、クラスや継承関係を定義できます。
ex:Employee rdfs:subClassOf ex:Person .
これは、「EmployeeはPersonの一種である」という意味です。
OWLでは、さらに複雑な意味を表現できます。
ex:worksFor owl:inverseOf ex:hasEmployee .
これは、「山田がABCに勤務しているなら、ABCは山田を社員として持つ」という逆方向の関係を定義します。
したがって、全体の関係は次のようになります。
RDF
└─ 情報をトリプルとして表す
RDFS
└─ RDF上でクラスや継承を定義する
OWL
└─ RDF上でさらに高度な論理を定義する
Turtle
└─ それらをテキストファイルに書くための構文
つまり、.ttlファイルの中には、単純なRDFデータも、RDFSスキーマも、OWLオントロジーも書くことができます。
ここまで理解できれば、全体像はほぼつかめています。
ここから詳しく解説
1. RDFとは何か
RDFは、Resource Description Frameworkの略です。
名前だけを見ると難しそうですが、基本的な考え方はシンプルです。
RDFでは、すべての情報を次の3要素で表します。
主語 ── 述語 ──> 目的語
英語では、次のように呼びます。
Subject ── Predicate ──> Object
たとえば、
山田はABC社に勤務している
という情報は、次のトリプルになります。
主語 :山田
述語 :勤務している
目的語 :ABC社
RDF風に名前を付けると、次のようになります。
山田 ── worksFor ──> ABC
さらに、
山田の社員番号はE001である
という情報は、次のトリプルになります。
山田 ── employeeId ──> "E001"
RDFでは、こうしたトリプルをたくさん組み合わせて、情報のネットワークを作ります。
┌── employeeId ──> "E001"
│
山田 ───────────┼── worksFor ────> ABC
│
└── manages ─────> 鈴木
この構造をRDFグラフと呼びます。
2. URIやIRIを使う理由
RDFでは、山田やABC、worksForなどを、単なる文字列ではなくIRIで識別します。
たとえば、次のIRIを使えます。
https://example.com/company#yamada
https://example.com/company#abc
https://example.com/company#worksFor
IRIは、世界中で名前が衝突しないようにするための識別子です。
たとえば、異なる会社がどちらもEmployeeという言葉を使っていたとしても、IRIが異なれば別の概念として区別できます。
https://company-a.example/vocab#Employee
https://company-b.example/vocab#Employee
RDFにおけるIRIは、データベースの主キーやプログラムの完全修飾名に近い役割を持ちます。
3. Turtleとは何か
Turtleは、RDFグラフを人間が比較的読みやすい形で記述するための構文です。
次のTurtleを見てみましょう。
@prefix ex: <https://example.com/company#> .
ex:yamada
ex:worksFor ex:abc ;
ex:employeeId "E001" ;
ex:manages ex:suzuki .
このファイルには、次の3つのトリプルが書かれています。
ex:yamada ex:worksFor ex:abc .
ex:yamada ex:employeeId "E001" .
ex:yamada ex:manages ex:suzuki .
セミコロン;は、同じ主語を繰り返さないための省略記法です。
したがって、
ex:yamada
ex:worksFor ex:abc ;
ex:employeeId "E001" .
は、次と同じ意味です。
ex:yamada ex:worksFor ex:abc .
ex:yamada ex:employeeId "E001" .
4. @prefixとex:の意味
Turtleファイルの先頭には、よく次の記述があります。
@prefix ex: <https://example.com/company#> .
これは、
ex:
を、
https://example.com/company#
の省略形として使う、という宣言です。
そのため、
ex:yamada
は次のIRIに展開されます。
https://example.com/company#yamada
また、
ex:worksFor
は次のIRIに展開されます。
https://example.com/company#worksFor
exという名前自体に特別な意味はありません。
次の3つは、対応する宣言があれば同じIRIを表します。
@prefix ex: <https://example.com/company#> .
@prefix company: <https://example.com/company#> .
@prefix c: <https://example.com/company#> .
ex:Employee
company:Employee
c:Employee
重要なのはexという省略名ではなく、展開先のIRIです。
5. 名前空間IRIはどのように決めるのか
サンプルでは、次のIRIを使用しています。
https://example.com/company#
example.comは、説明資料やサンプルコードで使用するためのドメインです。
本番環境では、原則として自社や自分が管理しているドメインを使用します。
たとえば、自社のドメインがmycompany.co.jpなら、次のような名前空間を考えられます。
@prefix company:
<https://data.mycompany.co.jp/vocab/company#> .
実データ用のIRIは、語彙とは分けると管理しやすくなります。
@prefix company:
<https://data.mycompany.co.jp/vocab/company#> .
@prefix resource:
<https://data.mycompany.co.jp/resource/> .
使用例は次のとおりです。
resource:yamada
a company:Employee ;
company:worksFor resource:abc ;
company:employeeId "E001" .
ここでは、
company:Employee
が「社員という概念」を表し、
resource:yamada
が「具体的な山田という人物」を表します。
名前空間を決めるときは、次の点が重要です。
- 自分たちが管理するドメインを使う
- 長期間変更しなくて済む名前にする
- 語彙と実データを必要に応じて分離する
- 一度公開したIRIを安易に変更しない
- 可能であれば、ブラウザでアクセスした際に説明を返せるようにする
IRIは単なるWebページのURLではなく、概念やリソースの識別子です。
そのため、Webサイトのデザインを変更したからといって、オントロジーのIRIまで変更するべきではありません。
6. #と/はどう使い分けるのか
名前空間には、主にハッシュ形式とスラッシュ形式があります。
ハッシュ形式
@prefix ex: <https://example.com/company#> .
展開結果は次のようになります。
https://example.com/company#Employee
https://example.com/company#worksFor
比較的小規模な語彙を、1つの文書として管理するときに向いています。
スラッシュ形式
@prefix ex: <https://example.com/company/> .
展開結果は次のようになります。
https://example.com/company/Employee
https://example.com/company/worksFor
各用語を個別のURLとして管理したい場合に向いています。
どちらが絶対に正しいというわけではありません。
それよりも、一度決めたIRIを安定して使い続けることのほうが重要です。
7. TurtleはRDFそのものではない
ここは重要なポイントです。
RDF :情報の構造
Turtle :その構造を書く方法
たとえば、次のTurtleがあります。
ex:yamada ex:worksFor ex:abc .
この内容は、RDF/XMLでも表せます。
<rdf:Description
rdf:about="https://example.com/company#yamada">
<ex:worksFor
rdf:resource="https://example.com/company#abc"/>
</rdf:Description>
見た目はまったく違いますが、どちらも次のトリプルを表しています。
主語:
https://example.com/company#yamada
述語:
https://example.com/company#worksFor
目的語:
https://example.com/company#abc
つまり、TurtleとRDF/XMLは、同じRDFグラフを異なる形式で表現しているだけです。
プログラムでたとえるなら、同じデータをJSONとXMLのどちらで表現するか、という違いに近いでしょう。
8. RDF/XMLにおけるex:の意味
RDF/XMLでは、ファイルの先頭に次のような名前空間宣言があります。
<rdf:RDF
xmlns:rdf=
"http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:ex=
"https://example.com/company#">
ここで、
xmlns:ex="https://example.com/company#"
と宣言しています。
そのため、
<ex:worksFor>
は、次のIRIを表します。
https://example.com/company#worksFor
ex:worksForがそのまま文字列として保存されるわけではありません。
XMLの名前空間機能によって、正式なIRIへ展開されます。
9. なぜrdf:resourceには完全なIRIを書くのか
次のRDF/XMLを見てみましょう。
<ex:worksFor
rdf:resource="https://example.com/company#abc"/>
ex:worksForはXML要素名です。
そのため、XML名前空間の仕組みにより、次のIRIへ展開されます。
https://example.com/company#worksFor
一方、
rdf:resource="https://example.com/company#abc"
の引用符の中は、XMLの要素名ではなく、単なる属性値です。
XML名前空間のプレフィックスは、通常、属性値の中までは展開してくれません。
そのため、次のようには書きません。
<ex:worksFor rdf:resource="ex:abc"/>
期待するIRIを確実に指定するため、完全なIRIを書きます。
<ex:worksFor
rdf:resource="https://example.com/company#abc"/>
これはRDFの都合というより、XML名前空間の仕組みに由来する制約です。
Turtleでは、主語・述語・目的語のすべてに同じプレフィックス記法を使えます。
ex:yamada ex:worksFor ex:abc .
そのため、人間が直接読み書きする用途では、Turtleのほうが簡潔です。
10. rdf:resourceがある場合とない場合
次の2つを比較してみましょう。
<ex:worksFor
rdf:resource="https://example.com/company#abc"/>
<ex:employeeId>E001</ex:employeeId>
違いは、目的語がリソースなのか値なのかです。
rdf:resourceがある場合
<ex:worksFor
rdf:resource="https://example.com/company#abc"/>
この目的語は、ABCという別のリソースです。
山田 ── worksFor ──> ABC
Turtleでは次のようになります。
ex:yamada ex:worksFor ex:abc .
要素の中に値がある場合
<ex:employeeId>E001</ex:employeeId>
この目的語は、E001という文字列です。
山田 ── employeeId ──> "E001"
Turtleでは次のようになります。
ex:yamada ex:employeeId "E001" .
RDFでは、目的語にIRIで識別されるリソースを置くことも、文字列や数値などのリテラルを置くこともできます。
11. RDFSとは何か
RDFだけでもデータは表現できます。
しかし、RDFだけでは次のような構造を十分に説明できません。
- EmployeeはPersonの一種である
- ManagerはEmployeeの一種である
- worksForの主語はEmployeeである
- worksForの目的語はOrganizationである
こうした基本的なスキーマを表現するのがRDFSです。
たとえば、次のようにクラスを定義できます。
@prefix ex:
<https://example.com/company#> .
@prefix rdfs:
<http://www.w3.org/2000/01/rdf-schema#> .
ex:Employee
a rdfs:Class ;
rdfs:subClassOf ex:Person .
ex:Manager
a rdfs:Class ;
rdfs:subClassOf ex:Employee .
クラス階層は次のようになります。
Person
└─ Employee
└─ Manager
ManagerがEmployeeのサブクラスで、EmployeeがPersonのサブクラスなら、ManagerはPersonでもあります。
12. rdfs:domainとrdfs:range
RDFSでは、プロパティの主語と目的語の型を表現できます。
ex:worksFor
rdfs:domain ex:Employee ;
rdfs:range ex:Organization .
これは、次の意味です。
worksForの主語はEmployeeである
worksForの目的語はOrganizationである
たとえば、次のデータがあるとします。
ex:yamada ex:worksFor ex:abc .
RDFSの推論を行うと、次の型を導けます。
ex:yamada a ex:Employee .
ex:abc a ex:Organization .
ただし、domainとrangeを入力チェックと考えてはいけません。
たとえば、次のデータがあったとします。
ex:invoice123 ex:worksFor ex:abc .
人間から見ると、「請求書が会社に勤務する」という不自然なデータです。
しかしRDFSは、このデータを単純にエラーにするのではなく、次のように推論します。
ex:invoice123 a ex:Employee .
つまり、RDFSのdomainは、
EmployeeだけがworksForを使用してよい
という入力制約ではなく、
worksForの主語になっているものはEmployeeである
という意味です。
13. OWLとは何か
OWLは、RDFSより高度な意味や論理関係を表現するためのオントロジー言語です。
RDFSで表現できる主な内容は、次のとおりです。
- クラス
- サブクラス
- プロパティ
- サブプロパティ
- domain
- range
OWLでは、さらに次のような内容を表現できます。
- 2つのクラスが同じ意味である
- 2つのクラスが同時には成立しない
- 2つのプロパティが逆関係である
- プロパティが推移的である
- プロパティが対称的である
- 個体同士が同一である
- 特定の条件を満たすものをクラスとして定義する
- キーを定義する
- 値の個数に制約を付ける
14. OWLによる逆プロパティ
次のOWL定義を考えてみます。
ex:worksFor
a owl:ObjectProperty ;
owl:inverseOf ex:hasEmployee .
これは、worksForとhasEmployeeが逆方向の関係であることを表します。
データに次の記述がある場合、
ex:yamada ex:worksFor ex:abc .
OWL Reasonerは、次の情報を推論できます。
ex:abc ex:hasEmployee ex:yamada .
人間が両方向を手動で登録しなくても、片方の情報からもう片方を導けるのです。
15. OWLによるクラスの条件定義
OWLでは、クラスを単に名前で宣言するだけでなく、条件によって定義できます。
たとえば、Managerを次のように定義できます。
Managerとは、
Employeeであり、
少なくとも1人のEmployeeを管理しているもの
OWLでは、次のように記述できます。
ex:Manager
owl:equivalentClass [
a owl:Class ;
owl:intersectionOf (
ex:Employee
[
a owl:Restriction ;
owl:onProperty ex:manages ;
owl:someValuesFrom ex:Employee
]
)
] .
データに次の記述があるとします。
ex:yamada ex:manages ex:suzuki .
山田がEmployeeで、鈴木もEmployeeであることが分かれば、Reasonerは次を推論できます。
ex:yamada a ex:Manager .
つまり、Managerという型を明示的に書かなくても、条件から分類できます。
16. OWLの排他関係と不整合
OWLでは、2つのクラスが同時には成立しないことを表現できます。
ex:Organization
owl:disjointWith ex:Person .
これは、OrganizationとPersonが排他的であることを意味します。
もし、あるリソースに次の両方の型が付いた場合、
ex:abc a ex:Organization .
ex:abc a ex:Person .
オントロジーは論理的に不整合となります。
OWL Reasonerは、単に1行の入力ミスを探すのではありません。
オントロジー全体について、すべての条件を同時に満たせるかどうかを検証します。
17. OWLは入力バリデーションではない
OWLは強力ですが、データベースの入力チェックとは考え方が異なります。
OWLでは、一般にオープンワールド仮定が使われます。
たとえば、鈴木の勤務先がデータに書かれていない場合、OWLは次のようには判断しません。
鈴木には勤務先が存在しない
代わりに、次のように考えます。
鈴木の勤務先は、まだ分かっていない
つまり、情報が書かれていないことと、その情報が存在しないことは別です。
そのため、次のような検証にはOWLだけでは向かない場合があります。
- employeeIdは必須
- employeeIdは必ず1つ
- 年齢は0以上
- メールアドレスは特定の形式
- 必須プロパティが欠けていないか確認する
こうした入力データの検証には、SHACLという技術がよく使われます。
役割を整理すると、次のようになります。
RDFS・OWL
データが何を意味するかを定義する
SHACL
データが期待する形になっているかを検証する
18. RDFパーサーとReasonerの違い
Turtleファイルを読み込んだからといって、自動的にすべての推論が行われるわけではありません。
パーサーとReasonerは別の役割を持ちます。
RDFパーサー
TurtleやRDF/XMLを読み込み、
明示的に書かれたRDFトリプルを取り出す
Reasoner
RDFSやOWLの意味論を使い、
明示されていない情報を推論する
たとえば、次のデータがあるとします。
ex:yamada ex:manages ex:suzuki .
単純なRDFパーサーは、このトリプルを読み込むだけです。
しかし、RDFSやOWLの定義があり、Reasonerを使用すると、次のような型が推論される可能性があります。
ex:yamada a ex:Manager .
ex:yamada a ex:Employee .
ex:yamada a ex:Person .
ex:suzuki a ex:Employee .
ex:suzuki a ex:Person .
使用するReasonerや設定によって、どの範囲まで推論されるかは異なります。
19. .ttl、.rdf、.owlの違い
ファイル拡張子と、内部で使われる意味論は分けて考える必要があります。
.ttl
Turtle構文で書かれたRDFファイルです。
中身は、単純なデータの場合もあれば、RDFSやOWLの定義の場合もあります。
data.ttl
schema.ttl
ontology.ttl
いずれもTurtle形式で記述できます。
.rdf
RDF/XML形式のファイルであることが多い拡張子です。
.owl
OWLオントロジーに使用されることが多い拡張子です。
ただし、.owlという拡張子だけでは、内部構文が必ずRDF/XMLであるとは限りません。
実際のファイル形式は、内容やContent-Type、使用ツールの設定を確認する必要があります。
20. 一つの.ttlファイルにRDF・RDFS・OWLを書ける
次のようなTurtleファイルを考えてみましょう。
@prefix ex:
<https://example.com/company#> .
@prefix rdf:
<http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:
<http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:
<http://www.w3.org/2002/07/owl#> .
ex:Employee
a owl:Class ;
rdfs:subClassOf ex:Person .
ex:worksFor
a owl:ObjectProperty ;
rdfs:domain ex:Employee ;
rdfs:range ex:Organization ;
owl:inverseOf ex:hasEmployee .
ex:yamada
a ex:Employee ;
ex:worksFor ex:abc .
この1つのファイルには、次の内容が混在しています。
RDFデータ
ex:yamada ex:worksFor ex:abc
RDFS
rdfs:subClassOf
rdfs:domain
rdfs:range
OWL
owl:Class
owl:ObjectProperty
owl:inverseOf
Turtle
ファイル全体の記述構文
したがって、
このファイルはRDFなのか、RDFSなのか、OWLなのか
という二者択一で考える必要はありません。
すべてRDFグラフであり、その中でRDFSやOWLの語彙を使用しています。
21. 実務での使い分け
目的ごとに整理すると、次のようになります。
| やりたいこと | 使用する技術 |
|---|---|
| 情報をグラフとして表したい | RDF |
| 人間が読みやすい形式で保存したい | Turtle |
| クラスや継承関係を定義したい | RDFS |
| 同値・排他・逆関係・制約を定義したい | OWL |
| データの必須項目や形式を検証したい | SHACL |
| RDFデータを検索したい | SPARQL |
実務では、次の組み合わせで使うことが多いでしょう。
データモデル RDF
ファイル形式 Turtle
基本スキーマ RDFS
高度な意味論 OWL
データ検証 SHACL
検索 SPARQL
まとめ
最後に、最も重要な関係をもう一度整理します。
RDF
情報を主語・述語・目的語のトリプルとして表す
RDFS
RDF上でクラス、継承、domain、rangeを定義する
OWL
RDF上で、同値、排他、逆関係、制約などを定義する
Turtle
RDFグラフを読みやすいテキストとして書く構文
.ttl
Turtle形式のファイルに使われる拡張子
そのため、次の表現はすべて正しいものです。
RDFデータをTurtleで書く
RDFSスキーマをTurtleで書く
OWLオントロジーをTurtleで書く
また、
@prefix ex: <https://example.com/company#> .
のex:は、IRIを短く書くための省略名です。
ex:yamada
ex:worksFor
ex:abc
は、それぞれ次のIRIに展開されます。
https://example.com/company#yamada
https://example.com/company#worksFor
https://example.com/company#abc
本番環境で名前空間を設計する場合は、自社が管理するドメインを使用し、長期間変更せずに使えるIRIを選ぶことが重要です。
オントロジーを学ぶときは、最初からOWLの複雑な制約をすべて理解しようとする必要はありません。
まずは、次の順番で学ぶと理解しやすくなります。
1. RDFのトリプルを理解する
2. Turtleでトリプルを書いてみる
3. RDFSでクラスと継承を定義する
4. OWLで逆関係や排他関係を試す
5. Reasonerによる推論結果を確認する
6. 必要に応じてSHACLやSPARQLを学ぶ
RDF、RDFS、OWL、Turtleは別々の技術に見えますが、すべては「意味を持ったグラフデータを表現し、共有し、推論する」という一つの目的につながっています。
ここまで読んだ方はすごいです!!!
改めましてですが、上記オントロジーのファイル(.ttl)を、グラフとして可視化しそのまま編集できる VSCode Extension を公開していますので、こちらも合わせて使っていただくと、よりイメージがわきやすいかもしれませんので、せひ使ってみてください!
以上、やがさきからでした。