Hatena::Grouplifesciencedb

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

2009-11-18

第8章 Overview of Toolkits の写経

|  第8章 Overview of Toolkits の写経 - ゲノム周辺 を含むブックマーク はてなブックマーク -  第8章 Overview of Toolkits の写経 - ゲノム周辺  第8章 Overview of Toolkits の写経 - ゲノム周辺 のブックマークコメント

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

紹介しているツール類


Sesame

http://lifesciencedb.g.hatena.ne.jp/nakao_mitsuteru/20091024/sesame のように簡単に導入できる。

Sesame Java API をつかう
Semame で RDFS 推論する
Sesame ウェブアプリケーションインスタンスする
ワークベンチを起動する
データを追加する
SPARQL クエリ
REST API

SIMILE/Exhibit


RDF をレポート化する

検索して、フィルターして、うまくみる

Sesame にリンクする

時系列タイムライン

第8章のまとめ


第10章 Tying It All Together の写経

|  第10章 Tying It All Together の写経 - ゲノム周辺 を含むブックマーク はてなブックマーク -  第10章 Tying It All Together の写経 - ゲノム周辺  第10章 Tying It All Together の写経 - ゲノム周辺 のブックマークコメント

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

アプリケーションを構築するステップ:

  1. Sesame に初期データをロードする
  2. ウェブアプリケーションサーバを設定する
  3. オブジェクトを表示するためのHTMLテンプレートを作成する
  4. 公共データからデータセットを拡張する
  5. ほかのセマンティックアプリケーション向けにデータを再出版する
  6. 多数のデータセットを横断してクエリする
  7. Exhibit をつかって可視化する

本のコードとサンプルコードが大分違うので気をつけたい。

おもむろにSesameをうごかすtomcatを起動しておく。

nakao@ortho:/Library/WebServer/tomcat
$ ./bin/startup.sh
Using CATALINA_BASE:   /Library/WebServer/tomcat
Using CATALINA_HOME:   /Library/WebServer/tomcat
Using CATALINA_TMPDIR: /Library/WebServer/tomcat/temp
Using JRE_HOME:       /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home

仕事リストデータ

http://semprog.com/psw/chapter10/joblist.csv

RDFへ変換する

ジョブスキーマhttp://www.medev.ac.uk/interoperability/rss/1.0/modules/jobs/

http://semprog.com/psw/chapter10/convert_jobs.py

依存パッケージ simplejson をインストールしておく。

sudo easy_install simplejson

変換してみる

$ python convert_jobs.py
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
   xmlns:company="http://purl.org/rss/1.0/modules/company/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:jobboard="http://semprog.com/schemas/jobboard#"
   xmlns:jobs="http://www.medev.ac.uk/interoperability/rss/1.0/modules/jobs/rss1.0jobsmodule#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
>
  <rdf:Description rdf:nodeID="dlFohHIo4">
(後略)

出力をファイルに保存

$ python convert_jobs.py > job_listings.rdf

Sesame にデータをロードする

pysesame.py による Sesame サーバの動作確認

http://localhost:8080/openrdf-workbench/repositories/Movies/export にデータをインポートするテスト。

python pysesame.py

http://localhost:8080/openrdf-workbench/repositories/Movies/export に多数トリプルがあればテスト成功。

変換した RDFSesame に直接インポートするコードがコメントアウトされていたので、環境に合わせてみて、解除してみた。

56: c = pysesame.connection('http://localhost:8080/openrdf-sesame/')
57: c.use_repository('joblistings')
58: print c.postdata(data)
python convert_jobs.py    
(中略)
<addinfourl at 4314047984 whose fp = <socket._fileobject object at 0x101211aa0>>

データがはいっていなかったので、http://localhost:8080/openrdf-workbench/ で joblistings レポジトリを新規追加して再度実行するも、動作せず。

Chapter 8. HTTP communication protocol for Sesame 2.0 をみつつ動く状態を Ruby で確認した。 

server = 'localhost'
port = 8080
path = "/openrdf-sesame/repositories/joblistings/statements"
rdf = File.open("job_listings.rdf").read
require 'net/http'
Net::HTTP.start(server, port) {|http|
  response = http.post(path, rdf, "content-type" => 'application/rdf+xml')
  p response.body
}

動作条件は次の二つ。

これを踏まえて pysesame.py の postdata メソッドを変更。

(略)
from urllib2 import urlopen,Request
(略)
    def postdata(self,data):
        host = self.baseurl+'/repositories/'+self.repository+'/statements'
        req = Request(host, data, {'content-type': 'application/rdf+xml'})
        res = urlopen(req)
        return res
(略)

ウェブサイトサーブする

CherryPy
easy_install charrypy
(中略)
Installed /Library/Python/2.6/site-packages/CherryPy-3.1.2-py2.6.egg
Processing dependencies for cherrypy
Finished processing dependencies for cherrypy
Mako ページテンプレート
easy_install mako

一般的なビューア

ウェブアプリの起動

pytohn job_site.py

ポート番号を変更する。Page not found · GitHub Pages を参照。

cherrypy.config.update({'server.socket_port': 8081}) 
cherrypy.quickstart(Main())

http://localhost:8081/アクセスして確認。

しかし、クリックすると pyton が Bus error で落ちた。

http://img.skitch.com/20091118-kbk74d1p3i3qs5mnm7egxegban.jpg


Sesame からデータを得る

参照サイト

データのとれるリクエスト例

$ curl -H 'Accept:application/sparql-results+json' "http://localhost:8080/openrdf-sesame/repositories/joblistings?query=SELECT+%3Fpred+%3Fobj+where+%7B%3Chttp%3A%2F%2Fsemprog.com%2Fschemas%2Fjobboard%23tumblr%3E+%3Fpred+%3Fobj+.%7D" 
{
	"head": {
		"vars": [ "pred", "obj" ]
	}, 
	"results": {
		"bindings": [
			{
				"pred": { "type": "uri", "value": "http:\/\/www.w3.org\/2000\/01\/rdf-schema#seeAlso" }, 
				"obj": { "type": "literal", "value": "http:\/\/api.crunchbase.com\/v\/1\/company\/tumblr.js" }
			}, 
			{
				"pred": { "type": "uri", "value": "http:\/\/purl.org\/rss\/1.0\/modules\/company\/name" }, 
				"obj": { "type": "literal", "value": "Tumblr" }
			}, 
			{
				"pred": { "type": "uri", "value": "http:\/\/www.w3.org\/1999\/02\/22-rdf-syntax-ns#type" }, 
				"obj": { "type": "uri", "value": "http:\/\/www.medev.ac.uk\/interoperability\/rss\/1.0\/modules\/jobs\/rss1.0jobsmodule#Organization" }
			}
		]
	}
}
  1. json で取り出したい。
  2. Accept が無いとレスポンスが application/x-binary-rdf-results-table というバイナリ形式になっている。
  3. リクエストヘッダーに Accept:application/sparql-results+json

これを踏まえて pysesame.py の __getsparql__ メソッドを変更。

(略)
    def __getsparql__(self, method):
        url = self.baseurl+method
        req = Request(url, None, {'accept': 'application/sparql-results+json'})
        data = urlopen(req).read()
(略)

実働コード query_jobs.py

from rdflib import Namespace, BNode, Literal, RDF, URIRef
from pysesame import connection
from urllib import quote_plus

con=connection('http://localhost:8080/openrdf-sesame/')
con.use_repository('joblistings')
print con
DC = Namespace("http://purl.org/dc/elements/1.1/")
JB = Namespace("http://semprog.com/schemas/jobboard#")
COMPANY = Namespace("http://purl.org/rss/1.0/modules/company/")
namefields=set([str(DC['title']),str(COMPANY['name'])])

id = 'http://semprog.com/schemas/jobboard#tumblr'
print id

sa = con.query('select ?pred ?obj where {<%s> ?pred  ?obj .}' % id)
oa = con.query('select ?pred ?sub where {?sub ?pred  <%s> .}' % id)

print sa
print oa

このコードは動くのに、jobs_site.py は落ちる。とりあえずすすむ。


一般的なテンプレート

カンパニーデータを得る

Chunchbase

スタートアップ企業のデータベース

改変して使用した

# Connecion to Sesame
(略)
endpoint='http://localhost:8080/openrdf-sesame/'
con=connection(endpoint)
(略)
c=connection(endpoint)
(略)
Yahoo! Finance

大企業の情報のソース。

Freebase 接続と調和する


特化したビュー

他者へ出版する

RFDa
RDF/XML

データを拡張する

位置
地理、経済、人口

洗練されたクエリ

ジョブデータを可視化する

将来の拡張

第10章のまとめ

  1. 実際にありそうな状況のアプリケーションの開発を実習である。
  2. データを徐々に拡張しつつアプリの開発をすすめている。この開発スタイルがRDFをつかったアプリの特徴かもしれない。
  3. Java プログラミングに慣れていないのでつらい。
トラックバック - http://lifesciencedb.g.hatena.ne.jp/nakao_mitsuteru/20091118

2009-11-16

第6章オントロジーの復習 Using Protege あたり

|  第6章オントロジーの復習 Using Protege あたり - ゲノム周辺 を含むブックマーク はてなブックマーク -  第6章オントロジーの復習 Using Protege あたり - ゲノム周辺  第6章オントロジーの復習 Using Protege あたり - ゲノム周辺 のブックマークコメント

http://lifesciencedb.g.hatena.ne.jp/nakao_mitsuteru/20091013/progsemwebhttp://lifesciencedb.g.hatena.ne.jp/nakao_mitsuteru/20091028/chap5chap6chap7 の Using Protege のあたりを復習する。

巨大な OWL オントロジーの開発を行うためのツール Protege は http://protege.stanford.edu/ から公開されている。


Protege をつかったオントロジー構築の参考サイト

ProgSemWeb はこのあたりの内容は駆け足すぎるので、ほかの参考資料をさがしてみた。


Protege 4.0 の起動

http://img.skitch.com/20091116-dn836bjuhs7mnkk5un3pb2kgrf.jpg

ダブルクリック

http://img.skitch.com/20091116-ppbnmegrs34snxhed6ptw5ea35.jpg

Create new OWL ontology を選んで進む

あたらしいオントロジーを作成する

http://img.skitch.com/20091116-d5cqng42juajyb6dkni34em31y.jpg


オントロジーを編集する

Add + をクリック

http://img.skitch.com/20091116-fnjsuxhkx72furtf8xaa8ubk6r.jpg

オントロジーの説明に「テスト」と追記

http://img.skitch.com/20091116-r15f1jahrnggtui7q66x755wdm.jpg

Type が選択できる。XMLLiteral など選択可。Lang で ja が選択できない。


Entities タブ

Entities パネルではクラスとオブジェクトプロパティが一覧できる。

http://img.skitch.com/20091116-m4emfdxh7q9e2tyu8bt1j37dfq.jpg

http://img.skitch.com/20091116-xx8jbgskt83ab767by4wxb1ggc.jpg


クラスを編集する

クラスは、主語と目的語になるオブジェクトのクラスです。

http://img.skitch.com/20091116-thkjprn14mpyhhn7ueecg3hues.jpg

Description には、つぎのものが設定できる。

  1. Equivalent classes
  2. Superclasses
  3. Inferred anonymouse superclasses
  4. Members
  5. Disjoint classes (共通部分を持たないクラス)

オブジェクトプロパティを編集する

オブジェクトプロパティは、オブジェクトをRangeにする述語になるもの。つぎに、ドメインとレンジを指定する。ドメインは主語になれるオブジェクトのクラス。レンジは目的語になれるオブジェクトのクラス。

http://img.skitch.com/20091116-f13d9ug8w3ad4ar8jutkiijprd.jpg

Charactoristics には、つぎのものが設定できる。

  1. Functional (目的語を一個だけもつ)_1
  2. Inverse functiona (主語を一個だけもつ)1_
  3. Transitive
  4. Symmetric
  5. Asymmetric
  6. Reflexive
  7. Inreflexive

Descriptions は、つぎのものが設定できる。

  1. Domains (主語になりえるオブジェクト
  2. Ranges (目的語になりえるオブジェクト
  3. Equivalent object properties
  4. Super properties
  5. Inverse properties (ステートメントの方向性が逆のプロパティ
  6. Disjoint properties (共通部分を持たないプロパティ
  7. Property chains

データプロパティを編集する

データプロパティは、リテラルをRangeにする述語になるもの。つぎに、ドメインとレンジを指定する。ドメインは主語になれるオブジェクトのクラス。レンジは目的語になれるリテラルのタイプ。

http://img.skitch.com/20091116-k7ekj3pj981pc42y5mkhngmmf6.jpg

Charactoristics は、つぎのものが設定できる。

  1. Functional (目的語を一個だけもつ)

Descriptions は、つぎのものが設定できる。

  1. Domains (主語になりえるオブジェクト
  2. Ranges (目的語になりえるリテラルの型)
  3. Equivalent object properties
  4. Super properties
  5. Disjoint properties (共通部分を持たないプロパティ

インスタンスをつくる

オントロジーだけではなく、そのインスタンスをつくることもできる。インスタンスオントロジーを行ったり来たりして開発プロセスを回すようだ。


オントロジー可視化する

オントロジー可視化GraphViz をつかっている。

http://img.skitch.com/20091116-brc9ge6wgs9enutkpfu7ykxrm9.jpg


まとめ

  • Protege の使い方を眺めてみた。
  • Protege の使いやすさは、OWL オントロジーの理解の具合と表裏一体。慣れたら簡単そうな予感。OWLの勉強し直してきます。
  • 次は既存のオントロジーを活用したあたらしいオントロジーの開発に挑戦したい。

GeorTydayGeorTyday2017/05/09 23:25Generic Viagra Uk Europe Original Cialis Ohne Rezept Need To Order Cialis <a href=http://byuvaigranonile.com>viagra</a> Propecia Vergessen

トラックバック - http://lifesciencedb.g.hatena.ne.jp/nakao_mitsuteru/20091116

2009-10-28

第5章データソース、第6章オントロジー 、第7章公開

|  第5章データソース、第6章オントロジー 、第7章公開 - ゲノム周辺 を含むブックマーク はてなブックマーク -  第5章データソース、第6章オントロジー 、第7章公開 - ゲノム周辺  第5章データソース、第6章オントロジー 、第7章公開 - ゲノム周辺 のブックマークコメント

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

データのリソースオントロジー、データの公開について扱っています。


Part II. 標準とソース 第5章 セマンティックデータのソース

  • セマンティクデータのストア、クエリ、操作についてみてきた
  • 良くある批判は、だれもセマンティックデータを標準をつかって公開してない、であった。
  • ソーシャルネットや映画、音楽の標準語彙を紹介する
  • 大量の強いIDのついたエンティティや数百の語彙をつかっているソーシャルデータベース Freebase をみる
FOAF (Friend of a Friend)
PREFIX foaf:<http://xmlns.com/foaf/0.1/>
PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#>

SELECT ?burl 
WHERE {
  ?a foaf:knows ?b . 
  ?b rdfs:seeAlso ?burl . 
}


ソーシャルネットのグラフ解析

easy_install networkx
import networkx as nx
g = nx.Graph()
g.add_edges_from([('a', 'b'), ('b', 'c'), ('b', 'd'), ('b', 'e'), ('e', 'f'), ('f', 'g')])
g.add_edge('c', 'd')
#
nx.degree(g, with_labels=True)
#
nx.betweenness_centrality(g)
#
nx.find_cliques(g)
#
nx.clustering(g,  with_labels=True)
#
nx.average_clusering(g)
#
  # Build a NetworkX graph of relationships
  nx_graph = nx.Graph()
  for a, b in rdf_graph.qeury('SELECT ?a ?b '+\
              'WHERE { ?a foaf:knows ?b . }',
              initNs={'foaf':FOAF, 'rdfs':RDFS})
    nx_graph.add_edge(str(a), str(b))
      • ノードのcentralityを計算
      • 最も中心的な人物のランキング
      • ノードのクラスター係数を計算
      • cliquishな人々をランキング
  • ルールの連鎖による推論ではなくてグラフ構造からの解析をおこなった

Linked Data

データのクラウド

  • FOAF は人物についてのセマンティックデータソースとして大量に流通している
  • しかし中心的なレポジトリは無い
  • 他のデータの発見性をよくする
  • データ消費者からの視点:
    • ウェブにデータがでたらめにまき散らされている
    • マスターデータキュレイターの不在
    • 網羅的なインデクスの不在
    • 中心的な調整者の不在
  • このデータクラウドから、一貫したデータベースを制作者が紡ぎ出すことが、セマンティックウェブのゴール

Are You Your FOAF file ?


リンクトデータを消費する

  • LInked Data をつかった実習
  • 米国外のアーティストの音楽アルバムを検索し、アーティスト情報やアルバムのレビューをリストするアプリケーション
    • データソース
      • DBpedia
      • Freebase.com
      • BBC
  • BBC
  • MusicBrainz
    • 音楽アーティストのメタデータプロジェクト
    • Linked Data dereferencable URIs を提供していない。
    • Freebase が MusicBrainz ID を dereferencable URIs として扱っている。
  • Freebase
  • DBpedia
  • コード:http://semprog.com/psw/chapter5/lod (このファイルはみつからない)
    • 複数のウェブサービスをつかっているので、それぞれの稼働状況に依存
    • フロー:図5−4
    • 国名を入れると(1)DBpediaにSPARQLクエリでバンドのFreebase IDを取得し(2)Freebase から MusicBrainz ID を取得し(3)MusicBrainsID でBBCからレビューを取得する流れ
      • 三段階でRDFグラフにデータを追加。データは強いIDでリンクしている。
      • 実行部
...
if __name__ == "__main__"
   g = Graph()
   getBands4Location(g)
   getMBZIDs(g)
   getBBCArtistData(g)
   getBBCReviewData(g)
   final_query = """
SELECT ?name ?album ?reviewtext
WHERE {
      ?fbband fb:type.object.name ?name .
      ?fbband owl:sameAs ?bband .
      ?bband foaf:make ?bn0 .
      ?bn0 dc:title ?album .
      ?bn0 rev:hasReveiw ?rev .
      ?rev rev:text ?reviewtext .
      FILTER ( lang(?name) != "en")
}"""

finalresult = g.qeury(final_query, initNs=nsdict)
...


Freebase

screenshot

  • 書き込み可能なセマンティックデータベース
  • 遺伝子からジーンズまで幅広いトピックを扱っている
  • すべてのデータはCC-BYになっている。
  • データの利用に料金はかからない

アイデンティティーデータベース

  • 数百万のエントリ/トピック(ものの単位)の情報があり、コミュニティユーザによってキュレーションされ、それぞれユニークであることが確認されている
  • 強いIDが中心的な役割
  • U2 トピックの Freebase ID
    • /authority/musicbrainz/a3cb23fc-acd3-4ce0-8f36-1e5aa6a18432
      • /authority/musicbrainz (名前空間
      • a3cb23fc-acd3-4ce0-8f36-1e5aa6a18432 (MusicBrainz ID)
    • 外部のdereferencable URIを取り込むのに便利な構造になっている
  • Freebase のエントリは消せない

RDFインターフェイス


Freebase スキーマ

screenshot

wget -q -O - --header="ACCEPT:text/plain" http://rdf.freebase.com/ns/film.actor
  • このようなトリプルがえられ、
<http://rdf.freebase.com/ns/film/actor> <http://rdf.freebase.com/ns/type.type.property> <http://rdf.freebase.com/ns/film.actor.film>
  • /film/actor/film のURIが得られる
wget -q -O - --header="ACCEPT:text/plain" http://rdf.freebase.com/ns/film.actor.film
curl -L -HACCEPT:text/plain http://rdf.freebase.com/rdf/film/actor/film.actor
#
curl -L -HACCEPT:text/plain http://rdf.freebase.com/ns/film.actor.film
#

MQLインターフェイス

  • nickel と発音する。むりやり
  • SPARQLのようなグラフパターンマッチではなく、ツリー状で例示で問い合わせ構造。
  • クエリJSON で表現する
    • ハリソンフォードの誕生日の問い合わせ:
{
  "code": "/api/status/ok",
  "result": {
    "/people/person/date_of_birth": "1942-07-13",
    "id": "/en/harrison_ford"
  },
  "status": "200 OK",
  "transaction_id": "cache;cache04.p01.sjc1:8101;2009-10-26T10:42:34Z;0015"
}
      • SPARQL で表現すると:
PREFIX fb:<http://rdf.freebase.com/ns/>
SELECT ?dob WHERE {  fb:en.harrison_ford fb:people.person.date_of_birth ?dob . }
{
  "id":"/en/harrison_ford",
  "type":"/film/actor",
  "film":[{ "film":[] }]
}  
    • 返り値
{
  "code": "/api/status/ok",
  "result": {
    "film": [
      {
        "film": [
          "Air Force One"
        ]
      },
      {
        "film": [
          "Apocalypse Now"
        ]
      },
      {
        "film": [
          "Blade Runner"
        ]
      },
      {
        "film": [
          "Clear and Present Danger"
        ]
      },
      {
        "film": [
          "Firewall"
        ]
      },
      {
        "film": [
          "Frantic"
        ]
      },
      {
        "film": [
          "Hollywood Homicide"
        ]
      },
      {
        "film": [
          "Indiana Jones and the Kingdom of the Crystal Skull"
        ]
      },
      {
        "film": [
          "Indiana Jones and the Last Crusade"
        ]
      },
      {
        "film": [
          "Indiana Jones and the Temple of Doom"
        ]
      },
      {
        "film": [
          "K-19: The Widowmaker"
        ]
      },
      {
        "film": [
          "Patriot Games"
        ]
      },
      {
        "film": [
          "Presumed Innocent"
        ]
      },
      {
        "film": [
          "Raiders of the Lost Ark"
        ]
      },
      {
        "film": [
          "Random Hearts"
        ]
      },
      {
        "film": [
          "Regarding Henry"
        ]
      },
      {
        "film": [
          "Return of the Ewok"
        ]
      },
      {
        "film": [
          "Star Wars Episode IV: A New Hope"
        ]
      },
      {
        "film": [
          "The Devil's Own"
        ]
      },
      {
        "film": [
          "The Frisco Kid"
        ]
      },
      {
        "film": [
          "The Fugitive"
        ]
      },
      {
        "film": [
          "The Mosquito Coast"
        ]
      },
      {
        "film": [
          "The Star Wars Holiday Special"
        ]
      },
      {
        "film": [
          "What Lies Beneath"
        ]
      },
      {
        "film": [
          "Witness"
        ]
      },
      {
        "film": [
          "Working Girl"
        ]
      },
      {
        "film": [
          "Sabrina"
        ]
      },
      {
        "film": [
          "Star Wars Episode V: The Empire Strikes Back"
        ]
      },
      {
        "film": [
          "American Graffiti"
        ]
      },
      {
        "film": [
          "Star Wars Episode VI: Return of the Jedi"
        ]
      },
      {
        "film": [
          "Six Days Seven Nights"
        ]
      },
      {
        "film": [
          "Hearts of Darkness: A Filmmakers's Apocalypse"
        ]
      },
      {
        "film": [
          "Apocalypse Now Redux"
        ]
      },
      {
        "film": [
          "Hanover Street"
        ]
      },
      {
        "film": [
          "Force 10 from Navarone"
        ]
      },
      {
        "film": [
          "The Conversation"
        ]
      },
      {
        "film": [
          "Zabriskie Point"
        ]
      },
      {
        "film": [
          "Heroes"
        ]
      },
      {
        "film": [
          "Dead Heat on a Merry-Go-Round"
        ]
      },
      {
        "film": [
          "Scary Movie 3"
        ]
      },
      {
        "film": [
          "Getting Straight"
        ]
      },
      {
        "film": [
          "Water To Wine"
        ]
      },
      {
        "film": [
          "Crossing Over"
        ]
      },
      {
        "film": [
          "Morning Glory"
        ]
      }
    ],
    "id": "/en/harrison_ford",
    "type": "/film/actor"
  },
  "status": "200 OK",
  "transaction_id": "cache;cache01.p01.sjc1:8101;2009-10-26T10:44:05Z;0004"
}
{
  "id":"/en/harrison_ford",
  "type":"/film/actor",
  "film":[{ "film":[{"name":null, "directed_by":[] }] }]
}
    • ハリソンフォードの出演映画のうちで女性監督映画の映画名と監督名を問い合わせる
{
  "id":"/en/harrison_ford",
  "type":"/film/actor",
  "film":[{ "film":[{"name":null, 
    "directed_by":[{"name":null, "/people/person/gender":"Female"}] }] }]
}
      • 返り値
{
  "code": "/api/status/ok",
  "result": {
    "film": [
      {
        "film": [
          {
            "directed_by": [
              {
                "/people/person/gender": "Female",
                "name": "Kathryn Bigelow"
              }
            ],
            "name": "K-19: The Widowmaker"
          }
        ]
      }
    ],
    "id": "/en/harrison_ford",
    "type": "/film/actor"
  },
  "status": "200 OK",
  "transaction_id": "cache;cache01.p01.sjc1:8101;2009-10-26T13:26:31Z;0002"
}

metaweb.pyライブラリを使用する

import metaweb
null = None
freebase = metaweb.Session("api.freebase.com") 
q = {"id":"/en/harrison_ford", "type":"/film/actor", "film":[{ "film":null }]}
output = freebase.read(q)
print str(output)
#
for performance in output['film']: print performance['film']
#

人とのインタラクション

  • 曖昧な名前をつかいがち
  • "US" や "The United States of America" という入力に <http://rdf.freebase.com/ns/en.united_states> を割り当てたい
  • 方法1:受付可能な応答を列挙する。強いIDと同様にはたらく
    • ユーザーの入力の表現力を制限してしまう
  • Freebase のアプローチ:自動保管ウイジット

http://img.skitch.com/20091026-8rm1m21h1ey435cij84am4npp1.jpg



コラム:Semantic Search


コラム:Sumushing Identity

  • こべつのデータリソースからのグラフをマージしたとき、理想的には、owl:sameAs で URIRefs 同士が関連ついている。
  • 現実的にはそうではない。
  • FOAF をつかったソーシャルネットワークではアノニマスノードをつかっていても、foaf:mbox がユニークキー的に振る舞う
  • 二つのリソースが同じものか否かは良く知られた課題
    • identity problem
    • reconciliation
    • record matching
    • smushing (RDF的)

コラム:Real-World Data

  • 事例ではエラーや例外処理をほとんどしていないが、Linked Dataのプログラミングでは守りの姿勢が重要
  • RDFa を扱うときに重要なのは、不正な HTML を前処理すること
    • Tidy や Beautiful Soup をつかう
  • RDFテンプレートで生成されることがおおいので、系統エラーがはいりやすい
  • xsd:dateTime 型なのにちがったりすることもしばしば



第6章 オントロジー

  • これまで既存の述語やかんたんなものだけをつかってきた
  • トリプルが広く流通したときには、述語の意味の定義の重要性がましてくる
    • film に TV用につくられた映画はふくまれるのか?など

What Is It Good For ? それは何に良い?
  • 主語、述語、目的語で知識を表現
    • 述語はエンティティ同士の関係、これは哲学の領域 Ontology
  • セマンティックソフトウェアでは世界をモデル化する必要がある
  • システム設計者はオンとロジスト

意味づけのための契約

  • TV向けの映画は film か?
  • オントロジーは正確な語彙を提供する
  • 語彙は、データ生産者とデータ消費者の社会契約書のようなもの
    • 意味付けが十分理解できると、データの利用性や拡張性が増す
  • どのようにして作成したオントロジーが正しいかを確認するか?

モデルはデータ

  • RDFメタモデルならば、オントロジーRDFトリプルを表現できたりデータにそってグラフストアに保存できるのは驚きではない。
  • 第三章では、既存のデータからあたらしいデータを生成し、推論をおこなった。
    • 推論ルールはコードの中にある。
    • 理想的には推論ルールは推論課程にあってほしい
  • オントロジーは推論のための形式ルールを表現できる
    • システムがオントロジーを読み込んだら、手でできる推論はすべて実行できるはずである
  • オブジェクト指向のシステムでは、ルールはオブジェクトが知っている。
  • Semantics Programming

データモデル化の概論
  • movies
    • title
    • release date
    • actors
  • types, properties, clases

クラスとプロパティ

  • class はエンティティのグループ
  • property はエンティティの関係
  • domain は property の主語がどのようなタイプかを定義
  • range は property の述語がどのようなタイプかを定義
ex:hasEyeColor rdf:type rdf:Property .
ex:hasEyeColor rdf:domain ex:Animal .
ex:hasEyeColor rdf:domain ex:Human .
ex:hasEyeColor rdf:range ex:Color .
  • トリプル例
<http://semprog.com/people/jamie> ex:hasEyeColor <http://rdf.freebase.com/ns/en.blue> .
    • jamie は ex:Aminal もしくは ex:Human である
    • /en/blue は ex:Color である
    • セマンティッククラスは Property に対して定義されるので、ex:Animal と ex:Human の関係は定義していない

フィルムをモデル化する

  • 第二章の映画データをモデル化する
    • ブレードランナーはリドリースコット監督作品でハリソンフォードが出演している
    • 図6−2
sp:blade_runner sp:name "Blade Runner"
rdf:type sp:Film
sp:starring sp:harrison_ford
sp:directedBy sp:redley_scott
sp:harrison_fordsp:name "Harrison Ford"
rdf:type sp:Actor
sp:redley_scott sp:name "Ridely Scott"
tdf:type sp:Director
      • RDFとRDFSとOWLの語彙がでてくるけど、説明はのちほど
      • PREFIX sp:<http://semprog.com/film#> という名前空間
      • class sp:Film は property sp:starring と spdirectedBy と sp:name をもっている。
    • 図6−3filmオントロジーのクラス階層
sp:Actor rdfs:subClassOf sp:Person .
sp:Director rdfs:subClassOf sp:Person .
sp:Person rdfs:subClassOf sp:Object .
sp:film rdfs:subClassOf sp:Object .
    • 図6−4propertyの接続先(domainとrange)
sp:namerdf:typeowl:DetatypeProperty
rdfs:domainsp:Object
rdfs:rangexsd:string .
sp:directerByrdf:typeowl:ObjectProperty
rdfs:domainsp:Film
rdfs:rangesp:Director .
sp:starringrdf:type owl:ObjectProperty
rdfs:domainsp:Film
rdfs:rangesp:Actor .
sp:Actor rdf:type owl:Class .
sp:FIlmrdf:type owl:Class .
sp:Director rdf:type owl:Class .
sp:Object rdf:type owl:Class .
xsd:string rdf:type rdf:XMLLiteral .
    • property からそれをつかっている主語(domain側)と目的語(range側)のclassと型がわかる

関係を具体化する

  • データモデル化の一般的な問題は関係についての明言する必要があるときにおこる
  • roleを足す例:ハリソンフォードはブレードランナーでリックデッカードの役(role)をした
    • roleはactor や film のpropertyにはではない
    • role はハリソンフォードの performance の property である。
  • RDFではこのように、主語述語目的語ステートメントをひとつの主語にする処理をreification(具体化)という
    • 図6−5 sp:Performance クラス
sp:blade_rannerrdf:typesp:Film
sp:name"Blade Runner"
sp:starring_:pref1
_:pref1rdf:typesp:Performance
sp:hasActorsp:harrison_ford
sp:hasRolesp:rick_deckard
sp:harrison_fordrdf:typesp:Actor
sp:name"Harrison Ford"
sp:rick_deckardrdf:typesp:Role
sp:name"Rick Deckard"
    • sp:Performance はほかのクラスとことなりものの関係を記述している
      • sp:actorやsp:Filmやsp:Roleとむすびつかないとsp:Performanceは意味が無い
      • RDF では空ノード(_:perf1)
  • セマンティックデータモデル化では、このような具体化は一般的なパターン

実際に十分なOWL
list(graph.subjects(rdfType, owlClass))
      • 述語が rdf:type、目的語が owl:ObjectProperty の主語
list(graph.subjects(rdfType, owlObjectProperty))


プロテジェを利用する

新しいオントロジーを作る


オントロジーを編集する


実際にちょっともっとOWL
  • ものがほかのもとどのように関係するかの曖昧性を取り除く修飾子を加える

Functional and Inverse Functional Properties 機能的と逆機能的プロパティ

  • Functional properties
    • 目的語を一個だけもつプロパティ
    • has_actor と has_role は Functional Properties
    • Performance は single actor と single role
  • Inverse Functional properties
    • 主語語を一個だけもつプロパティ
    • starring は Inverse Functional Properties
  • owl:ObjectProperty のサブクラス
    • owl:FunctionalProperty
    • owl:InverseFunctionalProperty
    • rdf:type をつかって宣言

Inverse Properties 逆プロパティ

  • RDF ステートメントには方向性がある
    • (domain) -> (range)
      • film directedBy director
      • director directed film
    • このような directedBy と directed を関係づける
PREFIX sp:<http://www.semprog.com/film#>
sp:directed owl:inverseOf sp:directedBy .

Disjoint Classes 離れるクラス

  • あるクラスから離すクラスのメンバーは、あるクラスのメンバーでは無い保証される。
  • owl:disjoint
    • 明確に別物にするときにつかう?sameAsの影響をうけない?

現実にとどめる


いくつかの他のオントロジー

FOAFを記述する


ビールオントロジー


これは私の美しい関係スキーマではない!
  • データモデルを構築するとき、最初はに正しくすることはだれにもできない
  • 関係データベーススキーマ設計と異なる点
    • いつでも更新できる。データに影響しない
    • 古いクエリも動作する

よりくわしくは






第7章 セマンティックデータを公開する


Embedding Semantics 意味を埋め込む
  • RDF/XML は複雑すぎる
    • 同じ内容のページを別形式で提供するのは、すでにある資産を活かすことと今後のメンテナンスコストを増やしてしまう
  • すでに多数あるHTMLページに意味を埋め込む方法

Microformats マイクロフォーマット

screenshot

<div class="vcard">
  <div class="fn">Toby Segaran</div>
  <div class="org">The Semantic Programmers</div>
  <dic class="tel">919-555-1234</div>
  <a class="url" href="http://kiwitobes.com/">http://kiwitobes.com/</a>
</div>
  • hCalender event を文字に埋め込む例
<p class="vevent">
 The <span class="summary">English Wikipedia was launched</span> 
 on 15 January 2001 with a party from
 <abbrr class="dtstart" title="2001-01-15T14:00:00+06:00">2</abbr> - 
 <abbrr class="dtstart" title="2001-01-15T16:00:00+06:00">4</abbr> pm at 
 <span class="location">Jimmy Wales' house</span>
 (<a class="url" href="http://en.wikipedia.org/wiki/History_of_Wikipedia">more information</a>)
</p>

ブラウザではこのように表示される:

http://img.skitch.com/20091025-kn2sk9safmqhdxug1iwid3w1xd.jpg

http://img.skitch.com/20091025-mkyyr2jf9ieim427cssmjbnehp.jpg

  • 難点:簡単に導入できるか、複数の microformats を混ぜるのは難しい。

RDFa  

<body xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:foaf="http://xmlns.com/foaf/0.1/">
<h1>Toby's Home Page</h1>
<p>My name is
  <span property="foaf:firstname">Toby</span> and my 
  <span rel="foaf:interest" resource="urn:ISBN:0752820907">favorite book</span>
  is the inspiring 
  <span about="urn:ISBN:0752820907">
    <cite property="dc:title">Weaving the Web</cite> by 
    <span property="dc:creator">Tim Berners-Lee</span>
  </span>
</p>
</body>
  • 次のように表示される:

http://img.skitch.com/20091025-etjumi4sq35kexinbmhihsgnn2.jpg

<div xmlns:beer="http://www.purl.org/net/ontology/beer#">
  <div about="#Guines" typeof="beer:Stout">
    <span property="beer:hasAlocholicContent">7.5</span>% Alcohol
  </div>
</div>

Yahoo! SearchMonkey

screenshot


Google's Rich Snippets


Dealing with Legacy Data 遺産データを扱うこと
  • 一般的な三段階
    1. ソースデータの同定とパース
    2. データにふさわしいスキーマを見つける/作成する
    3. データを名前空間写像し、RDFを作成する
  • 具体的な三つの事例をみる

インターネットビデオアーカイブウェブサービス

from rdflib.Graph import ConjunctiveGraph
from rdflib import Namespace, BNode, Literal, RDF, URIRef
from urllib import urlopen
from xml.dom.minidom import parse

FB = Namespace("http://rdf.freebase.com/ns/")
IVA_MOVIE = Namespace("http://www.videodetective.com/titledetails.aspx?publishedid=")
IVA_PERSON = Namespace("http://www.videodetective.com/actordetails.aspx?performerid=")
RDFS = Namespace("http://www.w3.org/2000/01/rdf-schema#")
def getdata(node, tag):
    datanode = node.getElementByTagName(tag)[0]
    if not datanode.hasChildNodes(): return None
    return datanode.firstChilde.data
    • REST APIXMLを取得し、必要なデータをとりだす
def get_in_theaters():
...
    • 取り出したデータをトリプルにしてRDFグラフに追加
def make_rdf_graph(movies):
...
    • 実行部
if __name__ == '__main__':
   movies = get_in_theatres()
   movie_graph = make_rdf_graph(movies)
   print movie_graph.serialize(format='xml')
  • ソースから獲得したデータを拡張して、明確な意味をつけて再構築した
    • スキーマを公開すると、第三者がデータを利用しやすくなる


テーブルとスプレッドシート(テキストデータ)

...
for title, rating, review in reader(open('MovieReviews.csv', 'U')):
    match = movie.query('SELECT ?movie WHERE {?movie dc:title "%s" .}' % title, initNs={'dc':DC})
    for movie_node, in match:
    	review_node = BNode()
	movie_graph.add((movie_node, REV['hasReview'], review_node))
...
    • 問い合わせ例:評価4以上の映画名とその監督名
PREFIX rev:<http://www.purl.org/stuff/rev#>
PREFIX dc:<http://purl.org/dc/elements/1.1/>
PREFIX fb:<http://www.freebase.com/ns/>

SELECT ?title ?rating, ?dirname
WHERE {
 ?m rev:hasReview ?rev .
 ?m dc:title ?title .
 ?m fb:film.film.directed_by ?d .
 ?d dc:title ?dirname .
 ?rev rev:rating ?rating
 FILTER (?rating > 4)
}
  • さりげなく、REST APIからのデータとcsvからのデータをマージして問い合わせをしている。
    • これは、映画のタイトルがふたつのデータソースで同じ文字列だったから可能。

引き継がれた関係データ(RDB

+----------+
| messages |
+----------+
| id       |               +-------+
| title    |               | users |
| content  |               +-------+
| user_id  | ------------> | id    |
+----------+               | name  |
  ^                        | email |
  |                        +-------+
  |       
+-------------------+
| messages_subjects |      +-------------+
+-------------------+      | subjects    |
| message_id        |      +-------------+
| subject_id        | ---> | id          |
+-------------------+      | description |
                           +-------------+
cur.execute("SELECT id, title, content user FROM messages;")
for id, title, content, user in cur.fetchall():
    mnode = MB['message/%d' % id]
    sg.add((mnode, RDF.type, SIOC['Post']))
    sg.add((mnode, DC['title'], Literal(title)))
    sg.add((mnode, SIOC['content'], Literal(content)))
    sg.add((mnode, SIOC['has_creator'], MB['user/%s' % user]))
    • 各テーブルの行を素直にトリプルに写像している
  • トリプル例:(message:10 has_creator user:1)
    • MB['message/%d' % id] が message:10 になっている。
  • 暗黙のセマンティックをもっているSQLデータベースを明示的なセマンティクスをもつRDFグラフに変換した

RDFLib to Linked Data RDFLibからリンクトデータへ
  • 問い合わせ
wget -q -O - http://127.0.0.1:8000/users/5
  • かんたんに動的にLinked Dataとして公開することができる
  • サイトを拡張したり開発したときは Vapour サイトバリデータを利用するとよい

コラム:Semantic MediaWiki

  • Wiki のコンテンツは構造が乏しいのが課題
  • ページのコンテンツをほかのページのコンテンツと関連づけられる
  • ページの内容の無矛盾性を確保するだけでなく、構造を活かしたクエリが利用できる
  • /wiki/Special:ExportRDF から RDF/XML を生成できる
  • no title
  • no title

コラム:Linked Dataの閲覧

http://dig.csail.mit.edu/2007/tab/:iamge

screenshot

screenshot

screenshot

http://img.skitch.com/20091025-ny2ug1451hgac3uetw8udf1die.jpg

http://img.skitch.com/20091025-fundwrn882cc6xkrqwbeayjy86.jpg

tvfaataxugtvfaataxug2013/07/28 14:48twvzumjgftdjfodfec, <a href="http://www.ajdvbcfhap.com/">gxbnduwehg</a> , [url=http://www.ssixphffnx.com/]kvcnyyrnvv[/url], http://www.qdvteuqazz.com/ gxbnduwehg

djxuwbmlyidjxuwbmlyi2013/11/23 07:45hvfnemjgftdjfodfec, <a href="http://www.zqnujjlihc.com/">cskjewwggd</a> , [url=http://www.ixpakezlrl.com/]hmsrrtgwdo[/url], http://www.ikpdlpiisx.com/ cskjewwggd

トラックバック - http://lifesciencedb.g.hatena.ne.jp/nakao_mitsuteru/20091028

2009-10-24

Sesame を Snow Leopard にインストールした

|  Sesame を Snow Leopard にインストールした - ゲノム周辺 を含むブックマーク はてなブックマーク -  Sesame を Snow Leopard にインストールした - ゲノム周辺  Sesame を Snow Leopard にインストールした - ゲノム周辺 のブックマークコメント

RDF のストアや SPARQL クエリができる Java フレームワーク SesameSnow LeopardMacBook Proインストールした。aduna-software.org - OpenRDF: Coupon Code and Online PromotionにそってインストールSesame HTTP サーバTomcat の上で動かせるので、Tomcat もあわせてインストール

screenshot


Tomcatインストール

Installing Apache Tomcat 6 on Mac OS X 10.5 Leopard or Mac OS X 10.6 Snow Leopardを参考に、http://tomcat.apache.org/download-60.cgi から 6.0.22 をダウンロードして、/Library/WebServer/tomcat に配置。

screenshot

curl -O  http://ftp.riken.jp/net/apache/tomcat/tomcat-6/v6.0.20/bin/apache-tomcat-6.0.20.tar.gz
tar zxvf apache-tomcat-6.0.20.tar.gz
mv apache-tomcat-6.0.20 /Library/WebServer/tomcat

管理ユーザの設定

/Library/WebServer/tomcat/conf/tomcat-users.xml を次のように編集した。

     19 <!--
     20   <role rolename="tomcat"/>
     21   <role rolename="role1"/>
     22   <user username="tomcat" password="tomcat" roles="tomcat"/>
     23   <user username="both" password="tomcat" roles="tomcat,role1"/>
     24   <user username="role1" password="tomcat" roles="role1"/>
     25 -->
     26   <user username="ADMIN" password="PASSWORD" roles="standard,manager,admin"/>
     27 </tomcat-users>

ADMINとPASSWORDは適当に変更されたい。


起動と停止

Tomcat の起動には bin/startup.sh をつかう。

cd /Library/WebServer/tomcat
./bin/startup.sh
Using CATALINA_BASE:   /Library/WebServer/tomcat
Using CATALINA_HOME:   /Library/WebServer/tomcat
Using CATALINA_TMPDIR: /Library/WebServer/tomcat/temp
Using JRE_HOME:       /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home

停止には bin/shutdown.sh をつかう。

./bin/shutdown.sh
Using CATALINA_BASE:   /Library/WebServer/tomcat
Using CATALINA_HOME:   /Library/WebServer/tomcat
Using CATALINA_TMPDIR: /Library/WebServer/tomcat/temp
Using JRE_HOME:       /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home

起動して、ウェブブラウザで確認する。

open http://localhost:8080/

http://img.skitch.com/20091024-fuuwp6iqh6n6ah2wprrdaj2c4h.jpg

このように表示されると起動成功。


この時点でハマったこと。

conf/tomcat-users.xml に、文字をコピペして utf-8 以外の文字が入ってしまい、サーバの起動はするけど、ページの表示がなされないという状態になった。tomcat のログは logs に日付別に出力されているので、それらを tail -f したり、Console.app でモニターしながら解決。


openrdf-sesame-2.3-pr1 のインストール

Sesameは、RDFデータのストレージクエリのためのオープンソースJavaフレームワークフレームワークは、ストレージメカニズムや推論機、RDFファイルフォーマット、クエリ言語の観点において完全に拡張可能であり設定可能。セサミは、JBDCに似たユーザーAPIストリームラインシステムAPIRDFへのSPARQLプロトコルをサポートしたRESTful HTTPインターフェイスをもっている。

General Page for the OpenRDF

OpenRDF Sesame server(openrdf-sesame) と OpenRDF Workbench(openrdf-workbench) の二つがあり、それぞれ、インストールする。

openrdf-sesame-2.3-pr1 のライセンスBSDスタイルのライセンスで、同梱しているものには Apache ライセンスのものもある。

Sesame - Browse /Sesame 2/2.3-pr1 at SourceForge.net から openrdf-sesame-2.3-pr1.tar.gz をダウンロードし,展開し、war ファイルを webapps ディレクトリに配置する。

tar zxvf openrdf-sesame-2.3-pr1.tar.gz
cp openrdf-sesame-2.3-pr1/war/openrdf-sesame.war /Library/WebServer/tomcat/webapps/
cp openrdf-sesame-2.3-pr1/war/openrdf-workbench.war /Library/WebServer/tomcat/webapps/

起動

Tomcat Manager http://localhost:8080/manager/html/list で /openrdf-sesame と /openrdf-workbench を『起動』。

ウェブブラウザで起動を確認。

open http://localhost:8080/openrdf%2Dsesame 

http://img.skitch.com/20091024-gifhi7p9ppj3hm2w12ydmq39hp.jpg

open http://localhost:8080/openrdf%2Dworkbench 

open http://localhost:8080/openrdf%2Dworkbench の表示時にエラーが発生。


エラー、足りないパッケージ(slf4j-1.5.8)を追加

java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder というエラーがあって openrdf-workbench が起動しない。

調べると Page not found - OpenRDF: Coupon Code and Online Promotion の症状だったので、ページあるとおりにSLF4J Binary filesから slf4j-1.5.8 取得し追加.

curl -O http://www.slf4j.org/dist/slf4j-1.5.8.tar.gz
cp slf4j-1.5.8/slf4j-jdk14-1.5.8.jar /Library/WebServer/tomcat/webapps/openrdf-workbench/WEB-INF/lib/ 
cp slf4j-1.5.8/slf4j-api-1.5.8.jar /Library/WebServer/tomcat/webapps/openrdf-workbench/WEB-INF/lib/  

Tomcat Manager で openrdf-workbench を再ロードすると、open http://localhost:8080/openrdf-workbenchアクセスできた。

http://img.skitch.com/20091024-bjcqbf8gtqd3m8uq2mwmxpn7tk.jpg


まとめ

トラックバック - http://lifesciencedb.g.hatena.ne.jp/nakao_mitsuteru/20091024

2009-10-21

第3章、第4章、第5章

|  第3章、第4章、第5章 - ゲノム周辺 を含むブックマーク はてなブックマーク -  第3章、第4章、第5章 - ゲノム周辺  第3章、第4章、第5章 - ゲノム周辺 のブックマークコメント

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

Part I. Chapter 3 セマンティックデータを使用する

簡単な問い合わせ言語
  • トリプルの spo がそれぞれ独立にあつかわれている
    • cities (s), inside (p), California (o)
    • city (s), mayor (p), Someonw (o)
  • それらを関連してあつかう

変数束縛

("San_Francisco_Californai", "inside", "California")
("San_Francisco_Californai", "mayor", "Gavin Newson")
    • 『ID』 はエンティティの『名前』ではない。
  • Chapter 2 でのクエリ形式
(None, "inside", "Carifolnia")
("?city", "inside", "Carifolnia")
    • 返り値:クエリの帰り値は "?city" をキーとしたディクショナリ
[{"?city": "San_Francisco_California"}, {"?city": "San_Jose_Carifornia"}]

("?city", "inside", "California")
("?city", "mayor", "Gavin Newson")
    • 返り値
[{"?city": "San_Jose_California"}]
("?city", "inside", "California")
("?city", "mayor", "?name_of_mayor")
    • 返り値:
[{"?city": "San_Francisco_California", "?name_of_mayor": "Gavin Nwesom"},
 {"?city": "San_Jose_California", "?name_of_mayor": "Norman Mineta"}]
  • これはSPARQLの変数束縛の形式とおなじ。

問い合わせ言語の実装

bg.query([('?company',      "headquarters", "New_York_NY"),
          ('?campany',      "industry",     "Investment Banking"),
          ('?campany',      "contributor",  '?contribution'),
          ('?contribution', "recipient",    "Orrin Hatch"),
          ('?contribution', "amount",       '?dollars')])
  1. campany はニューヨークに本部がある
  2. campany は投資銀行を業務にしている
  3. campany は contribution という名前の出資をしている
  4. contribution の受取人は "Orrin Hatch" である
  5. contribution の総計は dollars である
  • こんな返り値にしたい
[{'campany': 'BSC', 'contribution': u'contrib285', 'dollars': u'30700.0'}]
  • デモ
from simplegraph import SimpleGraph
bg = SimpleGraph()
bg.load('../chapter2/business_triples.csv')
bg.query([('?company',      "headquarters", "New_York_New_York"),
          ('?company',      "industry",     "Investment Banking"),
          ('?contribution',      "contributor",  '?company'),
          ('?contribution', "recipient",    "Orrin Hatch"),
          ('?contribution', "amount",       '?dollars')])
  • 映画のデータでのクエリ例:リドリースコットの監督映画とジュージルーカスの監督映画の両方に出演しているアクターはだれ?
graph.query(['?actor', "starring", ?movie
フィードフォワード推論
  • シンプル、決定論的
    • とある石の質量が1kg、ならば、おなじ石は2.2ポンドであると推論する。
    • (1kg と 2.2ポンドがおなじ質量である)
  • ルールベース
  • 分類
  • 判断
    • 6フィート以上の身長の人ならば、背の高い人と推論する。
    • (背の高い人の定義が外部にある)
  • オンラインサービス
    • レストランのアドレスを知っているならば、地図上の座標をジオコーダーで検索できる。
    • (住所と座標が交換できる)
  • ルールで
  • このセクションではルールベースの推論の例と既存のトリプルから新しいトリプルの推定の例を示す

あたらしいトリプルを推論する

  • 推論の簡単なパターンとして、クエリのマッチをあたらしいトリプルとしてトリプルストアに加える
    • トリプルストアに元のデータとクエリの結果が一体となっている
    • すると、クエリ結果への問い合わせもクエリになる
  • def applyinference(self, rule):
  • class InferenceRule:
    • def getqueries(self):
    • def maketriples(self, binding):
  • class WestCoastRule(InterenceRule):
    • def getqueries(self):
    • def _maketriples(self, campany):
  • 西海岸企業のトリプル(subject, "on_coast", "west_coast")をルール(subject, "headquartered", "San_Francisco_California")から推定し、トリプルストアに追加する
from inferencerule import *
wcr = WestCoastRule()
bg.applyinference(wcr)
list(bg.triples((None, "on_coast", None)))
#


ジオコーディング

from simplegraph import *
from inferencerule import *
geograph = SimpleGraph()
georule = GeocodeRule()
geograph.add(('White House', 'address', '1600 Pennsylvania Ave, Washington, DC'))
list(geograph.triples((None, None, None)))
#
geograph.applyinference(georule)
list(geograph.triples((None, None, None)))
#

ルールの連鎖

  • このような推論があたらしいトリプルをトリプルストアに加えるのはとても便利である
    • すべてのルールを明確に調整することなしにルールの結果にルールを適用できる。
  • 二つの住所の座標から距離を計算し、(1マイル以内の)近くにあるかという推定をするルール
    • ($place, 'close_to', object) トリプルをトリプルストアに加える
    • class CloseToRule(InferenceRule):
      • def __init__(self, place, graph):
      • def getqueries(self):
      • def _maketripels(self, place, lat, long):
    • デモ
from simplegraph import *
from inferencerule import *
pg = SimpleGraph()
pg.load('DC_addresses.csv')
georule = GeocodeRule()
pg.applyinference(georule)
#
whrule = CloseToRule('White House', pg)
pg.applyinference(whrule)
list(pg.triples((None, 'close_to', None)))
#
  • もう一つのルールを連鎖させる
  • 旅行者向けの施設(Turist Attraction)から一マイル以内にある安い(cheap)レストラン(restaurant)を推論するルール
    • class TouristyRule(InferenceRule):
      • def getqueries(self):
      • def _maketriples(self, ta, restaurant):
    • デモ
tr = TouristyRule()
pg.applyinference(tr)
list(pg.triples((None, 'is_a', 'touristy restaurant')))
#
  • これらのルールは一連の依存した関数にみえるのがフツーのデータ処理の考え方
  • 重要なのは、ルールはまったく独立していて、実現できること
  • 図3−2
    • ルールの連鎖ビュー
    • 'address' -> GecodeRule -> (s, 'longitude', o), (s, 'latitude', o)
    • 'longitude', 'latitude' -> CloseToRule -> (s, 'close_to', o)
    • 'close_to', 'is_a', 'cost' -> TuristyRule -> (s, 'is_a', 'turisty restaurant')
    1. 地理的な異常なものは緯度や経度をもつが住所を持たない。それらはトリプルストアに正しく格納でき、GeocodeRuleによって扱われなくてもCloseToRuleによって発見できる
    2. レストランの存在をはじめに知るだろうけどそのコストは知らない場合を考える。GeocodeRule はレストランをgeocodeできるし、CloseToRuleは近いレストランを推定できるけど、TouristyRule はレストランについてなにもできない。しかし、あとでコストがわかったときに、TouristyRule だけを実行すればよい。
  • 図3−3
    • マルチエージェント黒板
    • プログラミングについて効率を犠牲にしているが、分離性、分散の容易さ、誤りへの寛容性、柔軟性について利点がある

人工知能』という言葉

  • このような記号論理の連鎖から知能はでてこない。
  • 昔の人はまちがって、このような記号論理だけから知的な振る舞いを生成しようとしていた。

連結を探索する
  • グラフデータをあつかうときの一般的な質問:二つのエントリが接続しているか?
  • グラフアルゴリズム幅優先探索(breadth-first search)でshortest pathを探索をする

ケビンベーコンの六次

  • 幅優先探索で探索できる
    • Start (actor)
    • First movie step
    • First actor step
    • Second movie step
    • Second actor step
    • ...
共有キーと重複部分のあるグラフ
  • いままでデータ統合についてのセマンティックスの重要性について述べてきたが、グラフの生成と拡張のみを扱ってきた
  • グラフの結合
    • 結合には名前の問題がある。
    • 後の章で詳しくあつかう(多分オントロジーの章)

ビジネスグラフと場所グラフを結合する

  • コード
from simplegraph import SimpleGraph
bg = SimpleGraph()
bg.load("../chapter2/business_triples.csv")
pg = SimpleGraph()
pg.load("../chapter2/place_triples.txt")
#
for t in bg.triples((None, 'headquarters', 'San_Francisco_California')):    print t
#
for t in pg.triples(('San_Francisco_California', None, None)):    print t
#
    • 結合
hq = set([t[2] for t in bg.triples((None, 'headquarters', None))])
len(hq)
#
for pt in pg.triples((None, None, None)):
    if pt[0] in hq: bg.add(pt)
  • スキーマを気にする事無く二つのグラフを結合できた。
    • 確認
for t in bg.triples(('San_Francisco_California', None, None)): print t
for t in bg.triples((None, 'name', None)): print t

結合したグラフに問い合わせる

  • 'Computer software' 産業の会社(company)の所在都市(city)の地域(region)は?
results = bg.query([('?company', 'headquarters', '?city'), ('?city', 'inside', '?region'), ('?company', 'industry', 'Computer software')])
[r['region'] for r in results]
#
  • 'Investment Banking'産業の会社で所在都市の人口が1000000人より多いところは?
results = bg.query([('?company', 'headquarters', '?city'), ('?city', 'population', '?pop'), ('?company', 'industry', 'Investment Banking')])
[r for r in results if int(r['pop']) > 1000000]
#
  • グラフを結合(データ統合)してもこれまでと変わらなくクエリが通用する
基本的なグラフ可視化

Graphviz

graph "test" {
  A -- B;
  A -- C;
  C -- D;
}

トリプルの集合を表示する

  • トリプルストアから直接DOTファイルを保存する
from simplegraph import *
from graphtools import *
cg = SimpleGraph()
cg.load("../chapter2/celeb_triples.csv")
rel_triples = cg.triples((None, 'with', None))
tripletodot(rel_triples, 'dating_triples.dot')
neato -Teps Odating_triples.dot

 

問い合わせ結果を表示する

from simplegraph import *
from graphtools import *
cg = SimpleGraph()
cg.load("../chapter2/celeb_triples.csv")
querytodot(cg, [('?rel', 'with', '?p1'), ('?rel', 'with', '?p2')], 'p1', 'p2', 'relationships.dot')
exit()
neato -Teps -Orelationships relationships.dot

Cyatoscape でやってみる

http://img.skitch.com/20091019-1j2km3kuaysu3y2ywmmma1xjh8.jpg

A	--	B
A	--	C
C	--	D
  • def triplerosif(triples, filename):
def tripletosif(triples, filename):
    out = file(filename, 'w')
    for t in triples:
    	out.write('"%s"\t"%s"\t"%s" \n' % (t[0].encode('utf-8'), t[1].encode('utf-8'), t[2].encode('utf-8')))
  • def querytosif(graph, query, b1, b2, filename):
def querytosif(graph, query, b1, b2, filename):
    out = file(filename, 'w')
    results = graph.query(query)
    donelinks = set()
    for binding in results:
    	if binding[b1] != binding[b2]:
	   n1, n2 = binding[b1].encode('utf-8'), binding[b2].encode('utf-8')
	   if (n1, n2) not in donelinks and (n2, n1) not in donelinks:
	      out.write('"%s"\t--\t"%s"\n' % (n1, n2))
	      donelinks.add((n1, n2))

  • デモ
from simplegraph import *
from graphtools import *
cg = SimpleGraph()
cg.load("../chapter2/celeb_triples.csv")
rel_triples = cg.triples((None, 'with', None))
tripletosif(rel_triples, 'dating_triples.sif')
querytosif(cg, [('?rel', 'with', '?p1'), ('?rel', 'with', '?p2')], 'p1', 'p2', 'relationships.sif')
exit()
  • yFile で organic にするといい感じです。


セマンティックデータは柔軟
  • セマンティックデータは柔軟
  • この章によってできるようになったこと
    • データに何があって、どんな述語がつかわれているか理解するために可視化できる
    • 複数のノードにわたったパターンを検索するクエリを構築できる
    • グラフのアイテム間の結合を調べることができる
    • 場所のジオコードのように、新しい情報を推定するためのルールを構築できる
    • 新しいデータと既存のデータの重複をさがしたり、新しいスキーマ作ること無しにセットをマージできる

Part II. 標準とソース Chapter 4 実際に十分な RDF

  • データフォーマットと標準について
    • どの述語(p)を使うべきかを知るには?
    • データの値は、浮動小数点か数字の文字列表現のどちらに関係するかを知るには?
    • なぜ、"San_Francisco, CA"は San_Francisco_California なのか? 他で無く。
    • コンマ切りトリプルは、格納と共有に最良の方法なのか?
  • これらはデータの保持と共有化の問題
RDF は何?
RDF データモデル
  • RDFは、トリプルで表現された文をつかったデータモデルを表現するための言語。
  • 正確、堅牢、伝達時の曖昧性を排除

URIs は強いキー

リソース

ノード

  • すべてのRDF主語や目的語はリソース、ではない。
  • 匿名ノード、anounymous、blank node
  • 主語もしくは目的語でURIでアドレスできない場合がある
  • 図4−2
  • ノードの ID → _:id
    • id は任意の文字列
    • ローカルなグラフ内でのみのID
    • 強いキーではないのでグラフをまたいで使用できない
    • 関係代名詞のようなもの?
    • Segaran の知っている人の名前はJamie
(_:ax1, "surName", "Segaran")
(_:ax1, "knows", _:zb7)
(_:zb7, "surName", "Jamie")

リテラル

RDFシリアル化形式
  • 各種言語にライブラリがあるので詳しい仕様について熟知していなくても利用できる
  • 4つの形式を紹介する
    • N-triples (シンプルな表記法
    • N3 (N-triplesの圧縮版)
    • RDF/XML (良く利用される形式)
    • RDF in attributes (a.k.a. RDFa) (XHTMLに埋め込む用)
  • くわしくは http://www.w3.org/RDF

友人のグラフ

N-Triples

<http://kiwitobes.com/toby.rdf#ts> <http://xmlns.com/foaf/0.1/homepage> <http://kiwitobes.com/>.
<http://kiwitobes.com/toby.rdf#ts> <http://xmlns.com/foaf/0.1/nick> "kiwitobes".	
<http://kiwitobes.com/toby.rdf#ts> <http://xmlns.com/foaf/0.1/name> "Toby Segaran".
...

N3

  • N-Triples はシンプルで良いが冗長性が、データ量に比例して大きくなる。(URIがとくに冗長)
  • 少しの構造を加えて、N-Triples を圧縮したものが N3
  • URI prefix を定義して、参照したIDを短く表記する
    • 定義文 @prefix semprep: <http://semprog.com/people/>.
    • <http://semprog.com/people/colin> → semprep:colin
  • 同じ主語を省略できる
    • セミコロンで、主語を省略しつつ文結合。ドットが末尾。
    • semprep:colin foaf:knows <http://kiwitobes.com/toby.rdf#ts>; foaf:mbox "colin@semprog.com".
  • 共有した空ノードを名付けずに表記できる
    • [ <http://www.w3.org/2006/vcard/ns#street-adddress> "1005 Gravenstein Hwy North" ; <http://www.w3.org/2006/vcard/ns#locality> "Sebastopol, California" ].
  • a は <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> のショートカット
  • = は <http://www.w3.org/2002/07/owl#sameAs> のショートカット
@prefix foaf: <http://xmlns.com/foaf/0.1/>.
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.

tobes:ts a foaf:Person;
   foaf:homepage <http://kiwitobes.com/>;
   foaf:nick "kiwitobes";
   foaf:name "Toby Segaran".

RDF/XML

  • RDF はデータモデルの一つ、XMLはその表現のひとつ
  • RDF/XMLRDF であると勘違いされがち、読むのが困難と批判されがち
  • タグのパスでグラフを表現
    • ノード(主語)、リンク(述語)、ノード(目的語)
      • 『ストライプ』構造
  • rdf:RDF がトップノード
    • <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" />
  • グラフノードrdf:Description
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
               xmlns:foaf="http://xmlns.com/foaf/0.1/">

  <rdf:Description rdf:about="http://kiwitobes.com/toby.rdf#ts>
    <foaf:knows>
      <rdf:Rescription rdf:about="http://semprog.com/people/colin">
   </foaf:knows>
  <rdf:Description>

</rdf:RDF>
  • リテラルオブジェクトはテキストエレメント、もしくはrdf:Descriptionのアトリビュート
    • <foaf:name>Colin Evans</foaf:name>
    • <rdf:Description foaf:mbox="jamie@semprog.com" />
  • rdf:type 情報のショートカットがある。
    • <rdf:Description rdf:about="http://kiwitobes.com/toby.rdf#ts"><rdf:type><foaf:Person> ...
    • <foaf:Person rdf:about="http://kiwitobes.com/toby.rdf#ts">

RDFa

<span xmlns:foaf="http://xmlns.com/foaf/0.1/"
      about="http://kiwitobes.com/toby.rdf#ts"
      property="foaf:nick"
      countent="kiwitobes" />
  • 例:目的語がURI(about、rel、href)
<span xmlns:foaf="http://xmlns.com/foaf/0.1/"
      about="http://kiwitobes.com/toby.rdf#ts"
      rel="http://xmlns.com/foaf/0.1/homepage"
      href="http://kiwitobes.com" />
  • 例:XHTMLに埋め込み
Toby's nickname is: <span xmlns="http://xmlns.com/foaf/0.1/"
  about="http://kiwitobes.com/toby.rdf#ts"
  property="foaf:nick">kiwitobes</span>


			
			

これら以外のシリアル化形式

RDFLib の紹介
import rdflib
from rdflib.Graph import ConjunctiveGraph
g = ConjunctiveGraph()

#  データを取り込み
g.parse("http://semprog.com/people/colin", format="nt")

# 一覧表示
for triple in g:
    print triple

# クエリ
list( g.triples((None, rdflib.URIRef('http://xmlns.com/foaf/0.1/konws'), None)) )

# ファイル書き出し
outfile = open("colin.xml", "w")
outfile.write(g.serialize(format="pretty-xml"))
  • 書き出したファイル:colin.xml
<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF
  xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
  xmlns:_3='http://xmlns.com/foaf/0.1/'
>
  <_3:Person rdf:about="http://semprog.com/people/colin">
    <_3:name>Colin Evans</_3:name>
    <_3:mbox rdf:resource="mailto:colin@metaweb.com"/>
    <_3:knows>
      <_3:Person>
        <_3:name>Jamie Taylor</_3:name>
        <_3:mbox rdf:resource="mailto:jamie@semprog.com"/>
      </_3:Person>
    </_3:knows>
    <_3:knows>
      <_3:Person rdf:about="http://kiwitobes.com/toby.rdf#ts">
        <_3:name>Toby Segaran</_3:name>
        <_3:mbox rdf:resource="mailto:toby@segaran.com"/>
      </_3:Person>
    </_3:knows>
  </_3:Person>
</rdf:RDF>

import rdflib
from rdflib.Graph import ConjunctiveGraph
newg = ConjunctiveGraph()
newg.parse("colin.xml")
print newg.serialize(format="n3")
  • N3出力
@prefix _3: <http://xmlns.com/foaf/0.1/>.
@prefix _4: <http://kiwitobes.com/toby.rdf#>.
@prefix _6: <http://semprog.com/people/>.
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.

 _6:colin a _3:Person;
     _3:knows [ a _3:Person;
             _3:mbox <mailto:jamie@semprog.com>;
             _3:name "Jamie Taylor"],
         _4:ts;
     _3:mbox <mailto:colin@metaweb.com>;
     _3:name "Colin Evans". 

 _4:ts a _3:Person;
     _3:mbox <mailto:toby@segaran.com>;
     _3:name "Toby Segaran". 
  • なぜか一致しない…
newg == g
#
newg -= g
len(newg)
#
  • こちらは一致
g.isomorphic(newg)
#
newg.parse("colin.xml")
g.isomorphic(newg)
#
  • トリプルの追加の例
# 
me = URIRef("http://my.uri.com/gose/here")
# 
RDF = rdflib.Namespace("http://www.w3.org/TR/rdf-schema/#")
ref-type-predicate = REF["type"]
#
[ x for x in g.namespaces() ]
# foaf がある。とおもったら、_3 になっていた。
foaf = rdflib.Namespace("http://xmlns.com/foaf/0.1/")
# 
g.add((me, ref-type-predicate, foaf["person"]))
#
g.add(( URIRef("http://semprog.com/people/colin"), foaf["knows"], me))

Persistence with RDFLib

  • MySQLやBerkeleyDB、SQLite でグラフを永続化(=ファイル化)できる
import rdflib
from rdflib import Literal
store = rdflib.plugin.get('SQLite', rdflib.store.Store)('rdf-test.ts')
store.open('.', create = True)
g = rdflib.ConjunctiveGraph(store)
semprog = rdflib.Namespace("http://semprog.org/people/")
foaf = rdflib.Namespace("http://xmlns.com/foaf/0.1/")
g.add((semprog["jamie"], foaf["name"], Literal("Jamie Taylor")))
g.add((semprog["jamie"], foaf["mbox"], Literal("jamie@semprog.com")))
g.serialize(format="nt")
g.commit()
  • 読み込むときは、create=False にする。
import rdflib
store = rdflib.plugin.get("SQLite", rdflib.store.Store)('rdf-test.ts')
store.open(".", create = False)
g = rdflib.ConjunctiveGraph(store)
g.serialize(format='nt')

SPARQL

SELECT クエリフォーム

  • クエリ例:自作映画に出演している監督はだれ? どの映画?
PREFIX fb:<http://rdf.freebase.com/ns/>

SELECT ?who ?film
WHERE {
  ?film fb:film.film.derected_by ?who .
  ?film fb:film.film.starrting ?who .
  • PREFIX で名前空間を定義
  • ? もしくは $ からはじまる文字列が変数束縛

  • クエリ例:ron_shelton の監督映画の最初のリリース日は?
PREFIX fb:<http://rdf.freebase.com/ns/>

SELECT ?film ?reldate
WHERE {
  ?film fb:film.film.directed_by fb:en.ron_shelton .
  OPTIONAL { ?film fb:film.film.initial_release_date ?reldate . }
}
  • ?reldate が無い場合(欠損値の場合)にもマッチするようにするには OPTIONAL をつかう

  • クエリ例:ron_shelton の監督映画の最初のリリース日の記載の無い映画は?
PREFIX fb:<http://rdf.freebase.com/ns/>

SELECT ?film ?reldate
WHERE {
  ?film fb:film.film.directed_by fb:en.ron_shelton .
  OPTIONAL { ?film fb:film.film.initial_release_date ?reldate . }
  FILTER (!bound(?reldate))
}
  • FILTER で?reldateに変数束縛できなかったトリプルだけをとりだす。
  • 絞り込みにつかえる
  • 正規表現がつかえる:ron_shelton監督映画の出演者の中で名前が russell にマッチする人は?
PREFIX fb:<http://rdf.freebase.com/ns/>

SELECT ?film ?reldate
WHERE {
  ?film fb:film.film.directed_by fb:en.ron_shelton .
  ?star fb:type.object.name ?who .
  FILTER regex(?who, "russell", "i")
}
  • 不等号フィルター:
PREFIX fb:<http://rdf.freebase.com/ns/>

SELECT ?film ?when
WHERE {
  ?film fb:film.film.initial_release_date ?when .
  FILTER (?when > "2002")
}

Multiple Graph Patterns

  • WHERE 節に複数の {} (グラフパターン)を書ける。AND がとられる。
  • UNION キーワードをつかうと OR になる。

CONSTRUCTクエリフォーム

  • クエリの返り値でトリプルを形成する

ASK と DESCRIBE クエリフォーム

  • ASK は SELECTとWHEREが一体になっているようなもの
PREFIX fb:<http://rdf.freebase.com/ns/>
PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>

ASK {
  ?film fb:film.film.starring fb:en.bob_saget .
  ?film fb:film.film.starrgin fb:en.harrison_ford .
}
  • DESCRIBE はリソースのサービスについての情報を返す、らしい

SPARQLクエリとRDFLib

from rdflib.Graph import ConjunctiveGraph, Namespace

FBNAMESPACE = Namespace("http://rdf.freebase.com/ns/")
g = ConjunctiveGraph()
g.parse("moviedata-small.n3", format="n3")

results = g.query("SELECT ?film ?year WHERE { ?film fb:film.film.initial_release_date ?year . }", initNs = {'fb':FBNAMESPACE})

for triple in results:
    print triple
  • 返り値
(rdflib.URIRef('http://rdf.freebase.com/ns/en.hollywood_homicide'), rdflib.Literal(u'2003'))
(rdflib.URIRef('http://rdf.freebase.com/ns/en.becoming_dick'), rdflib.Literal(u'2000'))
(rdflib.URIRef('http://rdf.freebase.com/ns/en.k_19_the_widowmaker'), rdflib.Literal(u'2002'))
(rdflib.URIRef('http://rdf.freebase.com/ns/en.the_weight_of_water_2002'), rdflib.Literal(u'2002'))
(rdflib.URIRef('http://rdf.freebase.com/ns/en.body_of_lies'), rdflib.Literal(u'2008'))

便利なクエリ修飾子

  • LIMIT
    • 取り出す数
  • OFFSET
    • マッチの中の取り出す位置
  • ORDER BY
  • LIMIT と OFFSET でページネートを実現できる。
    • でできること:クエリにマッチした全件のうち、10件づつ表示する

  • SQLとは異なり、SPARQLは読み出ししかサポートしていない。(いまのところ)
  • よって、SPARQLでグラフを変更することはできない。
  • メリット:SPARQLエンドポイントを外部に公開してもリードオンリーなのでデータの改変の心配は無い。

Part II. 標準とソース Chapter 5 セマンティックデータのソース

FOAF (Friend of a Friend)

ソーシャルネットのグラフ解析

Linked Data

データのクラウド

FOAF

リンクトデータを消費する

Freebase

アイデンティティーデータベース

RDFインターフェイス

フリーベーススキーマ

MQLインターフェイス

metaweb.pyライブラリを使用する

人と相互作用する

トラックバック - http://lifesciencedb.g.hatena.ne.jp/nakao_mitsuteru/20091021