SPARQLとRによるデータ分析と可視化


Linked Open Data チャレンジ Japan 2023では、「みんなで石仏調査 附 みんなで石仏調査LODテクニカルプレビュー」が最優秀賞を頂きました。石造物の参加型オープンデータのプロジェクト「みんなで石仏調査」と、そこで収集されたデータをLinked Open Dataとして公開する「みんなで石仏調査LODテクニカルプレビュー」をセットにしたものです。
そこで、Linked Dataのクエリ言語であるSPARQLと、統計解析ソフトのRを使用して、みんなで石仏調査LODのデータを分析・可視化する方法について書きます。RStudio上で、このようなヒストグラムを表示するのがゴールです。


まずは背景知識として、今回分析の対象とする石造物である庚申塔について説明します。庚申塔は、像が彫られているかどうかで刻像塔と文字塔に分類することができます。文字塔には「庚申」銘が刻まれたものと、主尊(本尊)銘が刻まれたものがあります。庚申塔の主尊になるのは青面金剛と猿田彦が多く、まれに帝釈天が主尊になることもあります。

刻像塔

「庚申」銘 文字塔

「青面金剛」銘 文字塔

「猿田彦」銘 文字塔

青面金剛は仏教系、猿田彦は神道系です。年代によってこれらの塔の造立数がどう変化したのかを、みんなで石仏調査LODのデータを使って分析してみることとします。

青面金剛を主尊とする庚申塔の造立年のリストは以下のSPARQLクエリで取得することができます。

PREFIX sbp: <https://lod.sekibutsu.info/prop/>
SELECT ?year WHERE {
  ?s sbp:type '庚申塔' .
  ?s sbp:principal '青面金剛' .
  ?s sbp:built_year_ce ?year.
}

まず、

?s sbp:type '庚申塔' .
?s sbp:principal '青面金剛' .

で種類が庚申塔、主尊銘が青面金剛であることを指定し、

?s sbp:built_year_ce ?year.

で造立年(西暦)を取得します。

同様に、猿田彦を主尊とする庚申塔の造立年のリストは以下のSPARQLクエリで取得することができます。

PREFIX sbp: <https://lod.sekibutsu.info/prop/>
SELECT ?year WHERE {
  ?s sbp:type '庚申塔' .
  ?s sbp:principal '猿田彦' .
  ?s sbp:built_year_ce ?year.
}

石仏調査LODのSPARQLエンドポイントで実行すると、以下のようになります。

SPARQL文の入力されたテキストエリアの右にあるOptionで、Output formatはHTML Tableになっています。これをTSVに変更し、その下のShow results inlineのチェックを外して実行したときのURLは、TSV形式のデータを返すAPIのURLになります。

RStudioを起動し、以下のR Scriptを作成します。

dat_sarutahiko <- read.csv('https://lod.sekibutsu.info/sparql.php?以下略', header=TRUE, sep='\t')
dat_shomenkongo <- read.csv('https://lod.sekibutsu.info/sparql.php?以下略', header=TRUE, sep='\t')
hist(dat_sarutahiko$year, col="#ff0000", density=20, angle=-30, breaks=seq(1650, 2020, 10), ylim=c(0,120), main="庚申塔の主尊銘", xlab='造立年', ylab='件数')
hist(dat_shomenkongo$year, col="#0000ff",density=20,breaks=seq(1650, 2020, 10), add=T)
legend("topright", legend=c("猿田彦", "青面金剛"), fill=c("#ff0000","#0000ff"), border=c("#ff0000","#0000ff"), angle=c(-30,30), density=c(20,20))

最初の2行では、SPARQLエンドポイントをAPIとして呼び出し、返されたTSVデータをデータフレームに格納します。URLは途中までで略してありますが、先に書いた通り、Output formatをTSVにし、Show results inlineのチェックを外して実行したときのURLです。
APIから返されるTSVにはヘッダ行がありますので、header=TRUEを指定し、TSVはタブ区切りですのでsep='\t'を指定します。

次に、

hist(dat_sarutahiko$year, col="#ff0000", density=20, angle=-30, breaks=seq(1650, 2020, 10), ylim=c(0,120), main="庚申塔の主尊銘", xlab='造立年', ylab='件数')

で猿田彦を主尊とする庚申塔の件数のヒストグラムを描画します。
hist()関数の最初の引数dat_sarutahiko$yearは、対象となるデータフレームと列を指定しています。
col、density、angleは、ヒストグラムの棒の色、斜線の密度と角度を指定します。
breaks=seq(1650, 2020, 10)は、X軸つまり年代を、1650年から2020年まで10年区切りとしています。
ylimでY軸つまり年代毎のデータ件数の範囲を指定し、mainはグラフタイトル、xlab、ylabはX軸とY軸のラベルを指定します。
次の

hist(dat_shomenkongo$year, col="#0000ff",density=20,breaks=seq(1650, 2020, 10), add=T)

では、対象データフレームをdat_shomenkongoとし、棒の色は青に変えています。最後の引数add=Tは、先に描画したヒストグラムに重ねて描画することを指示しています。

最後に、legend()関数で凡例を表示します。
実行すると、以下のようなヒストグラムが表示されます。

庚申塔の主尊銘において、青面金剛より遅れて猿田彦が出現し、1800年代になると青面金剛が減って猿田彦が増えたことが分かります。