セマンティックウェブとは、情報の視覚的表現よりもコンピュータに対する識別(意味)を扱うことを目的としたプロジェクトです。すでに古い技術だと考える人もいる一方で、機械学習と組合せて使われるようにもなり、再認知されてきている分野です。ここでは、基本的なことを書いていきます。
知識グラフ
知識グラフでは、主語・述語・目的語のトリプルがデータとして保持されます。主語と目的語を述語によってつないでいるので、エンティティとリレーションからなるグラフとして考えることができます。
例えば、「マッキントッチュに関係する人物を知りたい」「A社のCEOを知りたい」などというクエリに対して対処できるクエリ言語を考えることができます。
クエリ言語は、グラフに対して理論上行える操作に依存しますが、グラフ理論の研究は長年続けられているため、様々なクエリを考えることが可能です。グラフ理論における定理やアルゴリズムを、知識グラフ上では使いやすいというメリットがあります。例えば、グラフデータベース上で利用することが考えられます。
実際には、自然言語のクエリをグラフ操作のクエリに変換するようなタスクを考えることができます。その例は、Facebook Graph Searchのようなものがあります。
RDFとは
RDFは、主語・述語・目的語のトリプルをグラフとして扱う標準的なデータモデルです。
以下はRDFの例です。
<http://rdf.freebase.com/ns/g.11vjz1ynm> <http://rdf.freebase.com/ns/measurement_unit.dated_percentage.date> "2001-02"^^<http://www.w3.org/2001/XMLSchema#gYearMonth> . <http://rdf.freebase.com/ns/g.11vjz1ynm> <http://rdf.freebase.com/ns/measurement_unit.dated_percentage.source> <http://rdf.freebase.com/ns/g.11x1gf2m6> . <http://rdf.freebase.com/ns/g.11vjz1ynm> <http://rdf.freebase.com/ns/type.object.type> <http://rdf.freebase.com/ns/measurement_unit.dated_percentage> . <http://rdf.freebase.com/ns/g.11vjz1ynm> <http://rdf.freebase.com/ns/measurement_unit.dated_percentage.rate> 4.5 . <http://rdf.freebase.com/ns/g.11vjz1ynm> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://rdf.freebase.com/ns/measurement_unit.dated_percentage> .
rdflib
rdflibというpythonライブラリを使えば、すぐにrdfを読み込めて、クエリで検索できます。
import rdflib g = rdflib.Graph() g.parse("http://xmlns.com/foaf/spec/index.rdf")
上記のようにfoaf(Friend of a Friend)データを読み込んだら、ワイルドカード検索を実行してみます。
list(g.triples((rdflib.term.URIRef("http://xmlns.com/foaf/0.1/knows"), None, None)))
出力
[(rdflib.term.URIRef('http://xmlns.com/foaf/0.1/knows'), rdflib.term.URIRef('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), rdflib.term.URIRef('http://www.w3.org/1999/02/22-rdf-syntax-ns#Property')), (rdflib.term.URIRef('http://xmlns.com/foaf/0.1/knows'), rdflib.term.URIRef('http://www.w3.org/2000/01/rdf-schema#comment'), rdflib.term.Literal('A person known by this person (indicating some level of reciprocated interaction between the parties).')), (rdflib.term.URIRef('http://xmlns.com/foaf/0.1/knows'), rdflib.term.URIRef('http://www.w3.org/2000/01/rdf-schema#range'), rdflib.term.URIRef('http://xmlns.com/foaf/0.1/Person')), (rdflib.term.URIRef('http://xmlns.com/foaf/0.1/knows'), rdflib.term.URIRef('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), rdflib.term.URIRef('http://www.w3.org/2002/07/owl#ObjectProperty')), (rdflib.term.URIRef('http://xmlns.com/foaf/0.1/knows'), rdflib.term.URIRef('http://www.w3.org/2003/06/sw-vocab-status/ns#term_status'), rdflib.term.Literal('stable')), (rdflib.term.URIRef('http://xmlns.com/foaf/0.1/knows'), rdflib.term.URIRef('http://www.w3.org/2000/01/rdf-schema#isDefinedBy'), rdflib.term.URIRef('http://xmlns.com/foaf/0.1/')), (rdflib.term.URIRef('http://xmlns.com/foaf/0.1/knows'), rdflib.term.URIRef('http://www.w3.org/2000/01/rdf-schema#label'), rdflib.term.Literal('knows')), (rdflib.term.URIRef('http://xmlns.com/foaf/0.1/knows'), rdflib.term.URIRef('http://www.w3.org/2000/01/rdf-schema#domain'), rdflib.term.URIRef('http://xmlns.com/foaf/0.1/Person'))]
(knows, , )というトリプルで検索した結果です。rdflibではその他に様々なことができるので、興味のある方はドキュメントをお読みください。 https://rdflib.readthedocs.io/en/stable/
SPARQL
SPARQLは、RDFグラフに対する標準化されたクエリ言語です。
SPARQLにはSELECT, CONSTRUCT, ASK, DESCRIBEという4種類のクエリがあります。これらは、グラフのパターンを検索するものです。
select
基本的に、WHERE句のトリプルの条件で一致したエンティティを抽出できます。
SELECT ?who ?film WHERE{ ?film fb:film.film.directed_by ?who . ?film fb:film.film.starring ?who . }
construct
検索条件で得たエンティティタプルを使って新しいグラフを構成できます。
CONSTRUCT{ ?who <http://employment.history/was_employed_in> ?year } WHERE{ { ?film fb:film.film.starring ?who . ?film fb:film.film.initial_release_date ?year . } UNION { ?film fb:film.film.directed_by ?who . ?film fb:film.film.initial_release_date ?year . } }
ask
指定したパターンがグラフにあるかどうかを真偽値で返します。
ASK{ ?film fb:film.film.starring fb:en.bob_sagat . ?film fb:film.film.starring fb:en.harrison_ford . }
describe
リソースに対してサービスが持っている有益な情報を返します。
DESCRIBE ?director WHERE { ?film fb:film.film.initial_release_date "2003" . ?film fb:film.film.directed_by ?director }
rdflibでSPARQLを使う
results = g.query(""" SELECT ?film ?year WHERE{ ?film fb:film.film.initial_release_date ?year . } """, initNs={"fb":"http://rdf.freebase.com/ns/"})
オントロジー
オントロジーとは、知識を表現するための正確な語彙を提供するものです。どのエンティティが表現でき、どのようにグループ化され、どんなリレーションでつながるのかを指定できます。
モデル化
エンティティのグループはクラスと言います。(人はPerson,組織はOrganization,等)。一方、属性は独立したエンティティとして表現されます。
John Doe --(birth)--> 19900101
19900101は、John Doeの属性です。birthはそれを結ぶリレーションです。John DoeはPersonというクラスで、19900101はDateというクラスとして定義できます。
当該のドメインのオントロジーを定義することを「モデル化」といいます。
OWL
OWLはクラスと属性を定義するための標準言語で、関係に対する強力な推論を可能にします。
以下は、最低限のOWLです。
owl:Thing
全クラスはThingのサブクラスになります。
owl:Class
RDFのリソースのクラスです。
owl:DatatypeProperty
リテラルを範囲として持つすべての属性のクラスです。
owl:ObjectProperty
owl:Classを範囲として持つすべての属性のクラスです。
rdfs:XMLLiteral
セマンティックウェブの応用例: ナレッジカード
Googleは"ナレッジグラフ"という名前で2012年にセマンティックウェブを広めました。
「エンティティが属性を持ち、他のエンティティと関連を持っている」という事実を利用し、以下のようなナレッジカードを表示することで検索結果の質を向上しました。
これは、GoogleによってFreebaseが買収されたことも関係しているかもしれません。
また、「自然言語の検索クエリを理解し、グラフ内の適切なエンティティを検索する」という問題として考えれば、単なる表示上の問題だけではなく、内部的に検索結果の向上に貢献できる可能性があります。
これが最も有名な応用例の一つだと思います。
さらなる課題: 特定のドメインに特化した知識グラフを自動生成する
OpenIEという手法がありますが、これは非構造データから自動的に「主語・述語・目的語」のトリプルを取得する手法のことです。日本語ではまだまだ研究がありませんが、英語圏ではすでにそれなりの精度が出ている分野です。
OpenIEを使うかどうかに関わらず、「入力したコーパスから自動的に知識グラフを生成する」ようなタスクは、特に情報検索タスクとしては実現したい事柄です。
例えば、求人検索に特化したサービスを構築したいとき、「要求されるスキル」「収入」「業種」「企業」などの関連を調べたいと思うかもしれません。そのような場合に、知識グラフがあれば情報検索に応用できそうな気がします。
すでに、Diffbotのような組織は、Webからデータを自動収集して、それを知識グラフに変換することを行っています。Diffbotはその知識グラフをMicrosoftなどに提供しているようです。
このような応用タスクを解くためには、セマンティックウェブの基本を理解しておくことが役に立ちそうな気がします。
参考
[0] https://googleblog.blogspot.com/2012/05/introducing-knowledge-graph-things-not.html [1] http://shop.oreilly.com/product/9780596153823.do [2] https://rdflib.readthedocs.io/en/stable/ [3] https://venturebeat.com/2018/08/30/diffbot-launches-ai-powered-knowledge-graph-of-1-trillion-people-places-and-things/