Hatena::Grouplifesciencedb

ゲノム周辺 このページをアンテナに追加 RSSフィード

2009-10-14

第1章 Why Semantics ? と第2章 Expressing Meaning

|  第1章 Why Semantics ? と第2章 Expressing Meaning - ゲノム周辺 を含むブックマーク はてなブックマーク -  第1章 Why Semantics ? と第2章 Expressing Meaning - ゲノム周辺  第1章 Why Semantics ? と第2章 Expressing Meaning - ゲノム周辺 のブックマークコメント

http://lifesciencedb.g.hatena.ne.jp/nakao_mitsuteru/20091013/progsemweb の第一回目の資料です。

東大がお試し期間のようで、Programming the Semantic Web: ProQuest Tech Books から読めるようです。


まえがき

  • WWWがかつて通った、人々が「なぜ?」と問いかけるのをやめて「どうやって?」を問いかけ始めた時期にセマンティックウェブも到達してきた。
  • Just enough RDF で Just enough OWL と言える。

序文


1. Why Semantics ?

  • subject-verb-object 主語-動詞-目的語の三つ組み(トリプル) で知識を表現する。
  • Who likes mushrooms ? という質問に解答できる。
ウェブをまたいだデータ統合
  • WWW以前はプロトコル毎にアプリが必要だった。FINGERやSMTPなど。
  • すべてがウェブになって、いまはウェブブラウザ一つで何でもできる。
  • データにアクセスしやすくなったけど、アプリは目的に特化し、アドホックな技術でデータの統合をしている。
  • データ統合の標準的な方法をこの本で提供する。
従来のデータモデル手法

表形式データ

レストラン住所料理価格開店日
釜竹根津うどん$$月、火、水、木、金
すずき白金とんかつ$$火、水、木、金、土
  • だれでも馴染みのある形式。
  • 簡単にデータを読んだり操作することができる。
  • 行(row)と列(column)にデータの意味がある。
  • 明らかな限界として、ネストしたデータの扱いがある。多値や構造化。ソートなどの計算に活かせない。
レストラン住所料理価格開店日
釜竹根津うどん$$月(11a-4p)、火(11-4)、水(11-4)、木(11-7)、金(11-8)
すずき白金とんかつ$$火(11-7)、水(11-7)、木(11-7)、金(11-7)、土(11-8)

関係データ

  • パワフルで実績がある。
  • レストランデータを複数のテーブルで表現可能。
    • 図1−1スキーマ
      • Cuisine(ID,Name)
      • Restaurant(ID, Name, Address, CuisineID)
      • Hours(RestaurantID, Day, Open, Close)
    • 図1−2データ

レストラン

ID名前住所価格料理ID
1釜竹根津$$1
2すずき白金$$2

料理

ID名前
1うどん
2とんかつ

営業時間

レストランID曜日開店閉店
1114
1114
1114
1117
1118
2117
2117
2117
2117
2118
  • 問い合わせはSQL
  • 関係データベースには値の名前があるだけで「意味」は無い。

スキーマを発展したりリファクタリングする

  • ウェブのデータは速やかに変化していくので、それにあわせてスキーマを変更しつづける必要がある。
  • レストランに加えてバーのデータを扱うことを考える。多くのレストランにはバーが付属していることがある。例がウマくない><
バー住所DJスペシャルドリンク
ロフト新宿Yesビール
  • (1)新しいbarテーブルをレストラントテーブルにjoinテーブルを介して接続する方法。住所情報が重複している。
  • (2)Venueテーブルを新しくつくって、Barテーブルとレストランテーブルをそこに関連づける方法。より正規化したアプローチ。
  • このようにテーブルを追加するときに、データの移行コストが発生する。移行コストはとても重い.(schema migration)
  • object-relation mapping(ORM)はひとつの解答であるが、依然として複雑性は高い。

非常に込み入ったスキーマ

  • データの発展に付随したマイグレーションに起こりうる他の問題:スキーマは多種のデータを扱うと複雑化する。
  • CRMERPではなんとかなっているけど進展の速いbiotechnologyでは疑問視されている。

最初のときにちゃんとする

  • 抽象化して、key/valueスキーマでデータ型が増えても対応できるようにしておくと、データが変更されてもスキーマの変更をしなくてもよくなる。
    • Properties(VenueID, FieldID, Value)
    • Field(ID, Name)
  • メリット:新しいフィールドをくわえたいときにスキーマの変更を伴わない。
  • デメリット:検索に不向きになる。普通やらない。

セマンティック関係
VenueIDFieldValue
1料理うどん
1価格$$
1名前釜竹
1住所根津
  • これまでカラム名(Field)にあった意味的関係がデータのなかに表現されている
メタデータはデータ
  • データ表現についてのデータ → メタデータ
  • テーブル間は外部キーで関係づけられている
  • メタデータ無しにデータが流通しがち → スキーマの解釈が困難
  • パラメータ化データのような自己記述的データで解決できる
不確実性のために作り上げる
  • メタデータ+データを単一表現する
  • 将来のデータ変更に対して備える
「果てしないベータ

2. Expressing Meaning

  • コードをつかってデータをあつかう。
  • "fully parameterized venue" テーブル(表1−4)
  • 三つのカラム → triple
  • 主語はエンティティ
  • 述語はエンティティのプロパティ
  • 目的語は(1)エンティティもしくは(2)リテラル
  • 複数のトリプルが有向グラフを構成する

x--トリプル表現でvenueデータと隣接関係データを単一のスキーマであつかえる(表2−1、表2−2)

例:映画データ
  • トリプル:
  • blade_runner name "Blade Runner"
    • subject: blade_runner
    • predicate: name
    • object: "Blade Runner"
  • blade_runner release_date "June 25, 1982"
    • subject: blade_runner
    • predicate: release_date
    • object: "June 25, 1982"
  • blade_runner はエンティティ ID
  • blade_runner directed_by redley_scott
  • redley_scott name "Ridley Scott"
  • redley_scott はエンティティ ID
  • 図2−4
簡単なトリプルストアを作成する
  • 相互参照トリプルストア
  • 実装して理解を深めるのが目的
  • デザイン:主語、述語、目的語を相互参照し、異なる組み合わせの問い合わせが可能に
  • no title
  • コードの実行は、chapter2 ディレクトリpython
  • Pythonは読みやすい

インデクス

  • subject (s), predicate (p), object (o)
    • spo, pos, osp のすべてインデクス化
    • posインデクスの作成:self._pos = {predicate:{object:set([subject])}}
  • インデクスはセットのディクショナリーのディクショナリー
    • predicate -> object -> [subject]
    • predicate, object, subject は変数なので、値でなくて変数自体でインデクスを構成している
  • subjectのセットへのアクセス:self._pos[predicate][object]
  • predicateのセットへのアクセス:self._osp[object][subject]
  • objectのセットへのアクセス:self._spo[subject][predicate]

追加と削除メソッド

  • 追加 def add(self, (sub, pred, obj)):
  • 削除 def remove(self, (sub, pred, obj)):
  • ファイルからデータをロードする def load(self. filename):
  • ファイルにデータをセーブする def save(self, filename):

問い合わせメソッド

  • マッチするトリプルを取り出す def triples(self, (sub, pred, obj)):
  • マッチする値を取り出す def value(sefl, sub=None, pred=None, obj=None):
from simplegraph import SimpleGraph
movie_graph = SimpleGraph()
movie_graph.add(('blade_runner', 'name', 'Blade Runner'))
movie_graph.add(('blade_runner', 'directed_by', 'ridley_scott'))
movie_graph.add(('ridley_scott', 'name', 'Ridley Scott'))
list(movie_graph.triples(('blade_runner', 'directed_by', None)))
list(movie_graph.triples((None, 'name', None)))
movie_graph.value('blade_runner', 'directed_by', None)
list(movie_graph.triples((None, None, None))) # 全件表示
グラフをマージする
  • グラフモデルでは、二つのグラフをそのまま結合することができる。
  • 個別のグラフを統一的に扱う事ができる。(統合化)
graph1 = SimpleGraph()
graph2 = SimpleGraph()
# データをロードしておく

mergegraph = SimpleGraph()
for sub, pred, obj in graph1.triples((None, None, None)):
    mergegraph.add((sub, pred, obj))
for sub, pred, obj in graph2.triples((None, None, None)):
    mergegraph.add((sub, pred, obj))
映画データの追加と問い合わせ
import simplegraph
graph = simplegraph.SimpleGraph()
graph.load("movies.csv")

Blade RunnerのID

bladerunnerId = graph.value(None, "name", "Blade Runner")
print bladerunnerId

Blade Runnerの出演者のID

bladerunnerActorIds = [actorId for _, _, actorId in graph.triples((bladerunnerId, "starring", None))]
print bladerunnerActorIds

Blade Runnerの出演者の名前

[graph.value(actorId, "name", None) for actorId in bladerunnerActorIds]

ハリソンフォードの出演映画の名前(←name←映画ID←starring←俳優ID←name←俳優名)

harrisonfordId = graph.value(None, "name", "Harrison Ford")
[graph.value(movieId, "name", None) for movieId, _, _ in graph.triples((None, "starring", harrisonfordId))]

ハリソンフォードの出演したシピルバーグ監督映画を問い合わせる。

# スピルバーグの監督した映画ID
spielbergId = graph.value(None, "name", "Steven Spielberg")
spielbergMovieIds = set([movieId for movieId, _, _ in graph.triples((None, "directed_by", spielbergId))])

# ハリソンフォードの出演映画ID
harrisonfordId = graph.value(None, "name", "Harrison Ford")
harrisonfordMovieIds = set([movieId for movieId, _, _ in graph.triples((None, "starring", harrisonfordId))])

# それらの積集合となる映画の名前
[graph.value(movieId, "name", None) for movieId in spielbergMovieIds.intersection(harrisonfordMovieIds)]
他の例

場所

セレブ

ビジネス


まとめ

  • ウェブにデータがある
  • 自己記述性データでデータとスキーマの依存性を減らす
  • トリプルで表現できる
  • トリプルストアの実装例と簡単な問い合わせ例をみた
    • 簡単なデータと簡単な問い合わせだけど、データをグラフで統一的に扱う可能性を感じた
  • グラフにすると、データのマージや柔軟な問い合わせが可能
    • どのような問い合わせについても一定の複雑度のようにみえる
    • 一方、SQLの場合はテーブル構造に依存して簡単なクエリと複雑なクエリが混在している
  • Data Dumps  |  Freebase API (Deprecated)  |  Google Developersはすごい。すべてのデータがCC-BY
トラックバック - http://lifesciencedb.g.hatena.ne.jp/nakao_mitsuteru/20091014