Python で W3C PROV オントロジーを可視化する(Python PROV)

本記事では Python の prov パッケージを利用して、PROV 情報を可視化する方法を見ていきます。

【目次】

[1]はじめに

W3C PROV オントロジーを利用すると、物事の来歴情報を記述することができます。

PROV 仕様は来歴表現に関するデータモデルやシリアライズフォーマットが定義されていますので、機械可読な来歴情報を表現できます。

ただし、一般に、形式的な表現のままでは人間が理解しやすいとは限りません。

これは PROV の仕様が複雑という意味ではなく、人間は、情報量が多くなると全体像を把握しづらくなるということかと思います。

これに対して PROV の表現を可視化(図示)するための推奨事項が公開されています。

このような PROV 情報の可視化を行えば、全体像を把握しやすくなると思います。

前回の記事『Git2PROV を例に W3C PROV オントロジー表現の基本を知る』では、Git のコミット履歴に関する PROV 表現例を図を中心に概観しました。

簡単な来歴の図は手作業で書くこともできますが(前回の記事は手作業で書きました)、データが複雑になると手作業で書くのは無理です。

これは作図作業に時間がかかる、というだけでなく、誤りのもとになります。

そこで本記事では、Python の prov パッケージを利用して、PROV 情報から図を機械的に自動生成する方法を見ていきます。

なお、本記事のコードは Google Colaboratory で動作確認しています。

[2]Prov Python package の利用

可視化の前に、Python の prov パッケージを利用して PROV 情報を扱う方法をざっと見ておきます。

(1)Prov Python package のインストール


インストールは pip コマンドで行えます。
!pip install prov

(2)PROV-N の概要

Prov パッケージの使い方の前に、PROV-N による表現形式を知っておくと後々便利ですので、ここではその概要を述べます。

PROV オントロジーのデータモデルは、PROV-DM として仕様化されています。

このデータモデルの記述に利用されている仕様が PROV-N です。

このように書くと、なんだか難しそう、とか面倒な感じがしますが、そうでもありません。

ここでは PROV-N の詳細な説明は割愛しますが、まずはイメージをつかむために、PROV の図に対応する PROV-N の記述をざっとみていきます。

以下は前の記事で利用した Git のコミット履歴を PROV で表現した図です。

Gitのコミット履歴の PROV グラフ

この図でもわかる通り、PROV 情報はグラフ構造で、ノードとそれをつなぐ矢印で構成されています。

ノードには Entity、Activity、Agent があります。

例えば、図には file という Entity、file_v1 という Entity、 technodaifuku という Agent、commit_1 という Activity などがあり、これらを PROV-N では以下のように書きます。

entity( file )
entity( file_v1 )
agent( technodaifuku )
activity( commit_1 )

一方、矢印は名前と方向を持っています。

例えば、entity( file_v1 ) から entity( file ) の向きに specializationOf という矢印を PROV-N では以下のように書きます。(矢印の起点が最初の要素、矢印の終点が次の要素になっていることに注意してください。)

specializationOf( file_v1, file )

このように、PROV-N は、グラフのノードと矢印を一つ一つ記述するイメージです。

正確には、PROV-N は、述語名と用語の順序付きリストで構成される関数型の構文になっていて、どのような述語名に対してどのような用語の順序付きリストを与えることができるかも定義しています。

上記例はとてもシンプルな例ですが、使うだけなら上記のイメージを基本として、必要に応じて仕様を参照するという感じで使えるのではないかと思います。

(3)Python で PROV 情報を作成する

PROV-N の書き方が分かると、Python Prov パッケージを利用して PROV 情報を記述できます。

以下は Python prov パッケージを利用して、先の図にある Git 履歴の PROV 情報を作るコードです。

データを作るコードは PROV-N の記法に対応していることがわかります。

import prov.model as prov

def create_git2prov_sample_doc():
  doc = prov.ProvDocument()
  doc.set_default_namespace('http://example.org/')

  doc.entity('file')
  doc.agent('technodaifuku')

  # v1
  doc.entity('file_v1')
  doc.activity('commit_1')

  doc.wasGeneratedBy('file_v1', 'commit_1')
  doc.wasAssociatedWith('commit_1', 'technodaifuku')
  doc.wasAttributedTo('file_v1', 'technodaifuku')
  doc.specializationOf('file_v1', 'file')

  # v2
  doc.entity('file_v2')
  doc.activity('commit_2')

  doc.wasGeneratedBy('file_v2', 'commit_2')
  doc.used('commit_2', 'file_v1')
  doc.wasAssociatedWith('commit_2', 'technodaifuku')
  doc.wasAttributedTo('file_v2', 'technodaifuku')
  doc.wasInformedBy('commit_2', 'commit_1')
  doc.wasDerivedFrom('file_v2', 'file_v1')
  doc.specializationOf('file_v2', 'file')

  return doc

少し補足しておきます。
  • PROV 情報のコンテナにあたる ProvDocument オブジェクトを作成します。
    • Bundle という概念もありますが、本記事では扱いません。
  • ProvDocument には PROV-N 記法に対応するメソッドが用意されていますので、このメソッドを利用して来歴情報を作成していきます。
  • これまでの説明では取り上げませんでしたが、PROV は RDF 仕様が元になっていますので、ノードに記載している名前はリソース識別子(IRI)です。
    • 上記コードでは set_default_namespace メソッドでデフォルトのネームスペースを定義しています。

ProvDocument オブジェクトがあると、RDF、XML、JSON 形式への変換ができますが、以下のコードで PROV-N 形式のデータを出力できます。

print( create_git2prov_sample_doc().get_provn() )

これを実行すると以下のように出力されます。

document
  default <http://example.org/>
  
  entity(file)
  agent(technodaifuku)
  entity(file_v1)
  activity(commit_1, -, -)
  wasGeneratedBy(file_v1, commit_1, -)
  wasAssociatedWith(commit_1, technodaifuku, -)
  wasAttributedTo(file_v1, technodaifuku)
  specializationOf(file_v1, file)
  entity(file_v2)
  activity(commit_2, -, -)
  wasGeneratedBy(file_v2, commit_2, -)
  used(commit_2, file_v1, -)
  wasAssociatedWith(commit_2, technodaifuku, -)
  wasAttributedTo(file_v2, technodaifuku)
  wasInformedBy(commit_2, commit_1)
  wasDerivedFrom(file_v2, file_v1, -, -, -)
  specializationOf(file_v2, file)
endDocument

なお、「-」は、用語の順序付きリスト項目の省略にあたるものです。詳細は仕様を参照して下さい。

[3]可視化してみる

Prov パッケージの ProvDocument オブジェクトが用意できたら、Graphviz を利用した可視化(図の作成)が可能です。

(1)Graphviz、pydot のインストール

Graphviz、pydot のインストールについて簡単にメモ書きますが、ネット上に情報が沢山ありますので、参考にしてください。

① Graphviz

Graphviz は、オープンソースのグラフデータ視覚化ツールです。

(参考)
Graphviz は Colaboratory に組み込まれているのでインストールの必要はありませんが、参考までに Ubuntu 環境に Graphviz をインストールする簡単なコマンドをメモしておきます。

sudo apt install -y graphviz

② pydot

pydot は Python から Graphviz を利用するためのライブラリです。

Prov パッケージは pydot を利用していますので、pydot パッケージをインストールする必要があります。

!pip install pydot

(2)図(画像)をPNG ファイルとして出力する

Prov パッケージには、ProvDocument オブジェクトから図を作成して pydot オブジェクトを作成する関数(prov_to_dot)が用意されています。

本記事では pydot の write_png メソッドを利用して作成された図を PNG ファイルに保存します。

from prov.dot import prov_to_dot

dot = prov_to_dot( create_git2prov_sample_doc() )
dot.write_png( "git2prov_sample.png" )

上記コードを実行すると、以下の画像が作成されました。

Python Prov で作成した Git コミット履歴の PROV グラフ

ちなみに、Colaboratory 上で以下のコードを実行すると PNG ファイルの内容が表示されます。

from IPython.display import Image,display_png
display_png( Image("git2prov_sample.png") )

(3)属性の追加と日本語表示

これまでの例はシンプルさを優先して、Entity、Activity、Agent の属性を無視してきました。

このため、図に表示される文字はリソース識別子のみです。

しかし、リソース識別子だけでは分かりにくいなど、その他の属性情報も表示したい場合もあります。

PROV-N では各種リソースに対する属性を指定することが可能です。

以下のコードは「テクノ大福」という日本語表記の名前属性を持つ Agent を作成するだけの ProvDocument の作成例です。

import prov.model as prov

def create_jpattr_sample_doc():
  doc = prov.ProvDocument()
  doc.set_default_namespace('http://example.org/')
  doc.add_namespace("foaf", "http://xmlns.com/foaf/0.1/")

  doc.agent('technodaifuku', {"foaf:name":"テクノ大福"})

  return doc

少し補足します。
  • 名前属性の語彙には FOAF を利用しています。
  • 属性は、Prov ライブラリでは dictionary の形式で指定することができます。

参考までに、この PROV-N 表記は以下のコードで確認できます。

print( create_jpattr_sample_doc().get_provn() )

PROV-N による属性表現
document
  default <http://example.org/>
  prefix foaf <http://xmlns.com/foaf/0.1/>
  
  agent(technodaifuku, [foaf:name="テクノ大福"])
endDocument

さて、追加された属性がどのように表示されるか確認してみます。

以下のコードで PNG ファイルに出力してみます。

prov_to_dot(create_jpattr_sample_doc()).write_png("jpattr_sample.png")

これにより以下の画像が作成されます。

日本語フォント設定が無い場合に文字化けする例

Agent の図形に加えて、注釈として foaf:name が追加されました。

しかし、デフォルトでは日本語フォントが利用されませんので、名前が文字化けしています。

日本語を表示するためには、以下の二つの作業が必要です。
  • (インストールされていなければ)日本語フォントをインストール
  • pydoc で日本語フォントを指定する

① IPA フォントのインストール

本記事では日本語フォントとして IPA フォントを利用します。

Colaboratory 環境だと以下のコマンドで簡単に IPA ゴシックフォントをインストールすることができます。

!apt-get -y install fonts-ipafont-gothic

IPA フォントの詳細や、各種環境へのインストールについては上記サイトを参照して下さい。

②pydoc で日本語フォントを指定する

prov_to_dot 関数の戻り値である pydot オブジェクトに対して日本語に対応しているフォント名を指定します。(この例では、IPAGothic です。)

dot = prov_to_dot( create_jpattr_sample_doc() )
dot.set_fontname( 'IPAPGothic' )
dot.write_png("jpattr_sample_ipa.png")

これにより正しく日本語が表示されました。

日本語フォント設定を行うと正しく表示される例


[4]RDFファイルを読み込んで可視化する

さて、ここまでは Python Prov パッケージを用いて新規に PROV 情報を作成しました。

しかし、PROV 仕様にそったシリアライズ形式のデータがあれば、それを利用して可視化することもできます。

例えば、前の記事で紹介した Git2PROV ツールが出力する RDF ファイルなどを読み込んで利用することもできます。

ただ、私は適当なデータを持ち合わせておりません。

そこで以下では、先に作成した Git のコミット履歴の ProvDocument を RDF ファイルとして保存し、その RDF ファイルを読み込んで、可視化できることを確認します。

(1)PROV 情報を RDF ファイルとして保存する

RDF 形式に変換するには、ProvDocument の serialize メソッドの format 引数に「rdf」を指定します。

出力内容は以下のコードで確認できます。(このコードは前に作成した Git コミット履歴のドキュメントを利用しています。)

print( create_git2prov_sample_doc().serialize(format="rdf") )

これを実行すると Turtle フォーマットで出力されることが分かります。

このままファイルに保存しても良いのですが、ここでは、以下のように名前空間のプリフィクスとして ex をつけてファイルに保存することにします。

doc = create_git2prov_sample_doc()
doc.add_namespace( "ex", 'http://example.org/' )
doc.serialize( "sample.ttl", format="rdf")

これで「sample.ttl」というRDFファイルが用意できました。

(2)RDFファイルから読み込んで可視化する

RDF ファイルが用意できたら、これを読み込んだ ProvDocument オブジェクトを作成します。

以下のコードのように、ProvDocument の deserialize メソッドの引数に format=”rdf” を指定して読み込みます。(先に作成した「sample.ttl」を読み込んでいます)

from prov.model import ProvDocument

pdoc = ProvDocument.deserialize("sample.ttl",format="rdf")

これで ProvDocument が生成できましたので、以下のコードで可視化してみます。

dot = prov_to_dot(pdoc)
dot.write_png("git2prov_sample_rdf.png")

これにより以下の画像が作成されました。

RDFファイルを Python Prov で読み込んで作図した例


コメント

このブログの人気の投稿

Google Document AIで画像から表形式データを抽出する(Vision API OCRとの違い)

VirtualBoxのスナップショット機能

オントロジーエディタ Protégé を使ってみる