littlewing

人間とコンピューターとメディアの接点をデザインするために考えたこと

オープンデータの基礎(5)-SPARQLを使ってみる

http://ja.dbpedia.org/statics/ja_dbpedia_logo.png

SPARQLで何ができるのか?

  • SPARQL言語を使うことで、LODクラウド上のデータを自由に取得・加工することができます。
  • LODクラウドデータベース用のSQL言語のようなものです。
  • 各LODにはSPARQLエンドポイントが存在しており(無い場合もあります)、そこに対してSPARQLを実行することで実行結果を取得できます。
  • 実行結果はXML,JSON,HTMLtableなど加工しやすいフォーマットで取得できます。

ひとまず、SPARQLのサンプルクエリを淡々と紹介

  • ja.dbpedia.orgのエンドポイントであるVirtuoso SPARQL Query Editorに以下のSPARQLを流し込むことで動作が確認できます。

  • 任意の3つの組を取得する基本構文

select ?s ?p ?o where{?s ?p ?o.} LIMIT 100
  • whereは省略可能(結果は上と一緒です)
select ?s ?p ?o {?s ?p ?o.} LIMIT 100

主語(subject)と目的語(object)を述語(predicate)を指定するので多くのサンプルでは?s ?p ?oと書かれることが多いです。

  • 変数名は自分で決めることができます。
select ?aaa ?bbb ?ccc {?aaa ?bbb ?ccc.} LIMIT 100
  • 「*」で出力内容を個別に指定せずにすべて表示することができます。(SQLと一緒ですね)
select * {?aaa ?bbb ?ccc.} LIMIT 100
  • dbpediaから東京都のデータを取得(主語を固定して、述語、目的語を変数として取得)
select distinct * where { <http://ja.dbpedia.org/resource/東京都> ?p ?o . }

distinct で重複する結果をまとめています。

  • prefixで記述を簡素化
PREFIX dbpedia:<http://ja.dbpedia.org/resource/> 
select distinct * where { dbpedia:東京都 ?p ?o . }LIMIT 100

  • 東京都のリーダーの情報を取得(目的語のみが変数になっています。)
PREFIX dbpedia: <http://ja.dbpedia.org/resource/>   
PREFIX dbp-­owl: <http://dbpedia.org/ontology/>    #jpではないことに注意!!
SELECT   ?leaderName     
WHERE    {  dbpedia:東京都 dbp-­owl:leaderName ?leaderName . }
  • 東京都に隣接する都道府県の情報を取得
SELECT DISTINCT ?rinsetsu_label 
WHERE { 
     ?tokyo_uri prop-ja:隣接都道府県 ?rinsetsu_uri . 
     ?tokyo_uri rdfs:label ?tokyo_label. 
     FILTER regex(?tokyo_uri , "東京都") 
     ?rinsetsu_uri rdfs:label ?rinsetsu_label. 
}

*「都道府県とその隣接都道府県数」を検索するためのクエリです。 * 6行目で都道府県名(?todoufuken_label)でグルーピングを行い、2行目で隣接都道府県(?rinsetsu_uri)の数を変数「name_rinsetsu」で参照しています。

SELECT DISTINCT ?todoufuken_label 
   count(?rinsetsu_uri) As ?num_rinsetsu
WHERE {
    ?todoufuken_uri prop-ja:隣接都道府県 ?rinsetsu_uri.
    ?todoufuken_uri rdfs:label ?todoufuken_label. 
} GROUP BY (?todoufuken_label)

漫画家と受賞作品

  • 漫画家一覧
PREFIX dbp:<http://ja.dbpedia.org/resource/> 
PREFIX dbp-owl: <http://dbpedia.org/ontology/>
PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#>
SELECT * 
WHERE{
?creator rdf:type dbp-owl:ComicsCreator.
}
  • そのうち手塚治虫文化賞受賞者一覧
PREFIX dbp:<http://ja.dbpedia.org/resource/> 
PREFIX dbp-owl: <http://dbpedia.org/ontology/>
PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#>
SELECT * 
WHERE{
?creator rdf:type dbp-owl:ComicsCreator;
dbp-owl:award dbp:手塚治虫文化賞 .
}
  • そのうち、長野県出身
PREFIX dbp:<http://ja.dbpedia.org/resource/> 
PREFIX dbp-owl: <http://dbpedia.org/ontology/>
PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#>
SELECT * 
WHERE{
?creator rdf:type dbp-owl:ComicsCreator;
dbp-owl:award dbp:手塚治虫文化賞;
dbp-owl:birthPlace dbp:長野県.
}
  • 受賞者と代表作品一覧
PREFIX dbp:      <http://ja.dbpedia.org/resource/> 
PREFIX dbp-owl: <http://dbpedia.org/ontology/>
PREFIX rdfs:    <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?creatorName ?comics
{
?creator a  dbp-owl:ComicsCreator;
dbp-owl:award dbp:手塚治虫文化賞;
dbp-owl:notableWork ?comic;
rdfs:label ?creatorName.
?comic rdfs:label ?comics .
}

日本の携帯電話のリストを取得する

  • キャリアがドコモの端末一覧
PREFIX dbp:      <http://ja.dbpedia.org/resource/> 
PREFIX dbp-owl: <http://dbpedia.org/ontology/>
PREFIX rdfs:    <http://www.w3.org/2000/01/rdf-schema#>
SELECT *
{
?s prop-ja:キャリア "NTTドコモ"@ja.

}
LIMIT 100
  • 発売日降順で並べるメーカー名も表示
SELECT DISTINCT *
{
?s prop-ja:キャリア "NTTドコモ"@ja;
prop-ja:製造 ?maker;
prop-ja:発売年 ?releaseYear.

}
ORDER BY ASC(?releaseYear)
LIMIT 100

よくわからないと思うので解説

SPARQLはSQLのようで、非なるもの

LODでは、RDF(Resource Description Framework)グラフと呼ばれる、主語(subject)と目的語(object)を述語(predicate)でリンクしたトリプル(triple)で表現します。

WHERE 部分の組み立てに注意

  • WHERE 部分基本的に <主語><述語><目的語>.(ドット)がセットです。自分が何を操作しているのかをつねに意識してください。

;を使うと主語が省略できる

目的語の後は必ず.を書く

rdf:type は a と略すことができる。(必ず小文字のa)

夏目漱石の代表作と発表年を表示するSPARQL

考え方

主語 述語 目的語
夏目漱石 -> 代表作 -> 変数として代表作を取得(複数)
代表作 -> 発売年 -> 変数として年を取得
  • 夏目漱石の代表作と発売年を表示
1: PREFIX dbp:      <http://ja.dbpedia.org/resource/> 
2: PREFIX dbp-owl: <http://dbpedia.org/ontology/>
3: PREFIX rdfs:    <http://www.w3.org/2000/01/rdf-schema#>
4: SELECT DISTINCT ?name ?sakuhinmei ?jidai
5: {
6: dbp:夏目漱石 rdfs:label ?name;
7: dbpedia-owl:notableWork ?sakuhin.
8: ?sakuhin rdfs:label ?sakuhinmei.
9: ?sakuhin dcterms:subject ?x.
10: FILTER regex(?x, "年の小説") .
11: ?x  rdfs:label ?jidai.
12: }
13: ORDER BY ASC (?jidai)
14: LIMIT 100 
  • 1-3行目 :読みやすくするためにPREFIX を設定しています。これでdbp/dbp-owl/rdfsがつかえるようになります。

  • 4行目 出力対象の変数を?name ?sakuhinmei ?jidaiの3つに絞り、かつ重複を除去(distinct)しています。 わからない人は[SELECT *]に入れ替えて結果を比べて見るといいでしょう。

  • 6行目 http://ja.dbpedia.org/resource/%E5%A4%8F%E7%9B%AE%E6%BC%B1%E7%9F%B3(=主語) の rdfs:label(=述語)を変数(?name)(=目的語)として取得しています。PREFIX のdbpを使うことで簡潔に表現。

  • 7行目 6行目で「;」を使うことで主語が省略されていますが、主語はdbp:夏目漱石です。夏目漱石(=主語)の代表作のデータラベル(dbpedia-owl:notableWork)(=述語) を変数名?sakuhinとして取得しています。これによって代表作の一覧が取得できます。

  • 8行目 7行目で取得した代表作の変数?sakuhin を主語として、rdfs:label(=述語)を 変数名?sakuhinmei(=目的語)として取得しています。

  • 9行目 変数?sakuhin のdcterms:subject(=述語)の内容を目的語の変数?xとして取得しています。

  • 10行目 ?x に対して、「年の小説」という文字が含まれるdcterms:subjectのみにフィルターをかけています。

  • 11行目 変数?xを主語として、rdfs:label(=述語)の値をx?jidaiとして取得しています。

  • 13行目 並び順を?jidaiの昇順に並べ替えています。

  • 14行目 取得件数を最大100件で制限をかけています。

取得結果

f:id:pigshape:20150512170359j:plain

参考資料

  • 一番わかりやすかったのは、このサイトでした。

LODとSPARQL入門(1) | 合同会社 緑IT事務所

  • SPARQLの解説資料

活用方法

エンドポイントを見つける

succi.jp

続きます