2019年9月18日水曜日

法人しりとりのSPARQLクエリ解説

法人しりとりは、経済産業省の 法人インフォ のSPARQL APIを利用したアプリである。
法人インフォでは、情報処理推進機構が提唱する 共通語彙基盤 を活用してデータモデルを作っており、RDFで実装されLODとして活用できるようになっている。
こちら が公開エンドポイント。
法人しりとりでは、以下のSPARQLクエリをリクエストし、しりとりに必要な情報を取得している。

PREFIX  hj: <http://hojin-info.go.jp/ns/domain/biz/1#>
PREFIX  ic: <http://imi.go.jp/ns/core/rdf#>
SELECT ?s ?corporateName ?corporateKana ?pref ?city
FROM <http://hojin-info.go.jp/graph/hojin>
WHERE{
  ?s hj:法人基本情報 ?key.
  ?key ic:名称 _:keyCorporateName .
     _:keyCorporateName ic:種別 '商号又は名称'.
     _:keyCorporateName ic:表記 ?corporateName .
     _:keyCorporateName ic:カナ表記 ?corporateKana .
  ?key ic:住所 _:keyAddress .
     _:keyAddress ic:種別 '住所' .
     _:keyAddress ic:都道府県 ?pref .
     _:keyAddress ic:市区町村 ?city .
  FILTER(regex(str(?corporateKana), '^ア' ))
}
LIMIT 1
OFFSET 300
(←0から300までの乱数をセット)

上記クエリで、
・法人番号(主語「s」から取得)
・法人名
・法人名カナ
・法人住所(都道府県/市区町村)

を取得する。

ポイントは
FILTER(regex(str(?corporateKana), '^ア' ))
のところ。
正規表現regex関数で、法人名カナの頭文字が「ア」のものを抽出する。
ここの「ア」を変更することにより、しりとりを継続していく。

悩むのがOFFSETの扱い。
しりとりゲームを成立させるにはランダムに法人を抽出する必要があり、OFFSETに整数の乱数をセットすることによりそれを実装する。
しかしながら先頭文字によって法人の数は大きく異なる(アから始まる法人の数とヌから始まる法人の数は大差がある)ので、大きな数をOFFSETにセットすると字によっては法人総数をオーバーしてしまうし、小さな数にすると抽出されない法人が多数出てくる字もある。
解決策は、以下のクエリで各文字の法人数を取得し、その値を最大値とする乱数をセットすること。

PREFIX  hj: <http://hojin-info.go.jp/ns/domain/biz/1#>
PREFIX  ic: <http://imi.go.jp/ns/core/rdf#>
SELECT (COUNT(?corporateKana) AS ?count)
FROM <http://hojin-info.go.jp/graph/hojin>
WHERE{
   ?s hj:法人基本情報 / ic:名称 / ic:カナ表記 ?corporateKana .
   FILTER(regex(str(?corporateKana), '^ア' ))
}


しかしながら上記のようにすると結局2回クエリを送信することになり、時間がかかり、しりとりのゲーム性が大きく損なわれる。
ゲームバランスを考えた結果、OFFSETは全ての文字で0~300で固定とすることとした。
(OFFSETが小さいほど処理が速くなる)

法人インフォのSPARQL APIのレスポンスがもっと速くなったら何の問題もないんですけどね…。


2019年9月4日水曜日

「自治体の未来」のSPARQLクエリ

「自治体の未来」は、政府統計総合窓口(e-Stat)の 統計LOD から、過去の統計調査結果のデータ(国勢調査・人口動態等)を取得しています。
以下のクエリを、統計LODのSPARQL Endpoint にリクエストすると、統計LOD「社会・人口統計体系データセット」から、特定の自治体のあらゆる統計データを取得することができます。当アプリもこのクエリを使っています。
------------------------------------------
PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#>
PREFIX g00200502-dimension:<http://data.e-stat.go.jp/lod/ontology/g00200502/dimension/> 
PREFIX cd-dimension:<http://data.e-stat.go.jp/lod/ontology/crossDomain/dimension/> 
PREFIX sdmx-measure:<http://purl.org/linked-data/sdmx/2009/measure#> 
PREFIX sdmx-dimension:<http://purl.org/linked-data/sdmx/2009/dimension#> 
PREFIX sac:<http://data.e-stat.go.jp/lod/sac/> 
select ?indicatorURI ?indicatorName ?year ?value 
where { 
?s  sdmx-dimension:refArea  sac:C26103-19700401 ; 
    cd-dimension:timePeriod  ?year ;  
    g00200502-dimension:indicator  ?indicatorURI ; 
    sdmx-measure:obsValue  ?value . 
?indicatorURI  rdfs:label  ?indicatorName . 
filter(LANG(?indicatorName)='ja') 
} ORDER BY ASC(?indicatorURI) ASC(?year) 
------------------------------------------

上記は「京都市左京区」の統計データを取得するクエリ。
sac:C26103-19700401 の部分が、京都市左京区の「期間付き標準地域コード」です。
この部分を変えることにより、他の自治体のデータを取得することができます。

(例)
C02201-20070901 青森市
C10201-20090505 前橋市
C13104-19830818 東京都新宿区
C13421-19700401 小笠原村
C23100-20030729 名古屋市
C18201-20060201 福井市
C26103-19700401 京都市左京区

以下のクエリで、2015年時点の全国の「期間付き標準地域コード」一覧を取得することができます。
------------------------------------------
PREFIX sdmx-dimension: <http://purl.org/linked-data/sdmx/2009/dimension#>
PREFIX qb: <http://purl.org/linked-data/cube#>
PREFIX sacs: <http://data.e-stat.go.jp/lod/terms/sacs#>
PREFIX ic: <http://imi.go.jp/ns/core/rdf#>
select distinct ?code ?pref ?area
where {
?s  sdmx-dimension:refArea  ?code ;
    qb:dataSet  <http://data.e-stat.go.jp/lod/dataset/g00200521/d0003148521>.
?code  sacs:prefectureLabel  ?pref ;
       ic:表記  ?area ;
}order by ?code
------------------------------------------