Masamuneブログ

学んだ事を記録していきたいと思います

DBpediaでWikipediaからデータを取得する方法

はじめに

この記事は「フィヨルドブートキャンプ Part 2 Advent Calendar 2021 - Adventar」 17日目の記事です。
先日リリースした自作サービスで、Wikipediaのデータをもとにデータベースを構築する際に使用した、DBpedia(日本語版)の簡単な解説を行いたいと思います。
実際にサービスで使用したのはDBpedia(英語版)でしたが、DBpedia(日本語版)の方がわかりやすいので、今回はDBpedia(日本語版)をもとに説明をいたします。

DBpediaについて

DBpedia(日本語版)から引用させていただきました。

DBpediaはWikipediaから情報を抽出してLOD (Linked Open Data)として公開するコミュニティプロジェクトです.本家のDBpediaは主にWikipedia英語版を対象としています.DBpedia Japanese の目的は,Wikipedia日本語版を対象としたDBpediaを提供することです

DBpedia(日本語版)

https://ja.dbpedia.org/

データを取得する

以下に実際にデータを取得する方法を記載いたしますが、検索に使用するSPARQLについては、簡単な解説にさせていただきます。

織田信長の孫のデータを取得する

DBpediaでデータを抽出する例として、織田信長の孫のデータを取得してみます

  • 以下のSPARQLクエリSPARQL EndpointQuery Textに入力します。
    (SPARQLの簡単な解説については後述します)
    #SPARQLクエリ
          PREFIX dbpj: <http://ja.dbpedia.org/resource/>
          PREFIX dbp-owl: <http://dbpedia.org/ontology/>
          SELECT DISTINCT ?name ?abstract
          WHERE {
              ?child dbp-owl:parent dbpj:織田信長.
              ?grandchild dbp-owl:parent ?child;
              rdfs:label ?name.
              OPTIONAL{ ?grandchild dbp-owl:abstract ?abstract}
          }

    f:id:Masamune_blog:20211214190432p:plain

  • Results Formatで取得したいデータのフォーマットを選択します(今回はHTML形式で取得します)

    f:id:Masamune_blog:20211214190428p:plain

  • Execute Queryで検索を実行します。


    f:id:Masamune_blog:20211214190417p:plain

  • 以下のように、信長の孫の名前と解説が表示されました。
    xmljsonにすればデータベース構築の際にデータの加工が容易になると思います。

    f:id:Masamune_blog:20211214190436p:plain

実行したSPARQLについて簡単な解説

1行目から順番に解説します

  • 1行目
    PREFIX dbpj: <http://ja.dbpedia.org/resource/>
    目的語としてURIを入力する際の共通部分<http://ja.dbpedia.org/resource/>をdbpjとして定義しています。
  • 2行目
    PREFIX dbp-owl: <http://dbpedia.org/ontology/>
    今回利用する述語が定義されているURIをdbp-owlとして定義しています。
  • 3行目
    
                SELECT DISTINCT ?name ?abstract
              
    4行目以降のWHERE節で割り当てられた変数のうち、SELECT句の横に列挙されている変数(今回は?nameと?abstract)が出力として表示されます。
  • 4行目
    
                WHERE {
              
    4行目以降の"WHERE{ }"の部分はWHERE節といい、WHERE節で列挙されているRDFトリプル文がすべて真となるような、変数割り当てが検索されます。
    "RDFトリプル文"については以下で解説いたします。
  • 5行目
    
                ?child dbp-owl:parent dbpj:織田信長.
              
    変数(?child)を主語として、述語に親の意味を持つURI(dbp-owl:parent)、目的語に織田信長の意味を持つURI(dbpj:織田信長)を定義しています。
    これにより、変数(?child)の親は織田信長であるという意味となり、変数(?child)には信長の子供が格納されます。
  • 6行目
    
                ?grandchild dbp-owl:parent ?child;
              
    5行目の信長の位置に信長の子供(?child)が定義されているので、変数(?grandchild)には信長の子供の子供、要するに孫が格納されます。
  • 7行目
    
                rdfs:label ?name.
              
    主語が省略されていますが、ここの主語には6行目の変数(?grandchild)が定義されます。
    よって、変数(?grandchild)の見出し(dfs:label)は変数(?name)であると定義され、信長の孫の記事の見出しが変数(?name)に格納されます。
  • 8行目
    
                OPTIONAL{ ?grandchild dbp-owl:abstract ?abstract}
              
    7行目と同じように解説(dbp-owl:abstract)を変数(?abstract)に格納したいところですが、
    Wkipediaの記事のなかには解説がないものもあります。そこで、検索条件として必須でないトリプル文を入れたいので、Optional句を用います。
    Optional句の中身は、WHERE句で用いたトリプル文とほぼ同じで、
    変数(?grandchild)の解説(dfs:abstract)は変数(?abstract)であると定義され、信長の孫の記事の解説が変数(?abstract)に格納されます。

以上を実行し最終的にWikipediaからデータから、信長の孫の記事の見出し(人の記事の場合その人の名前)と解説を抽出することができました。
今回は信長の孫を検索しましたが、孫の孫の孫の孫の...と繰り返していけば織田信成さん (フィギュアスケート選手)の記事に行き着くかもしれませんね。

終わりに

簡単にDBpediaについて解説しようとしましたが、思いのほかSPARQLの解説が煩雑になってしましました。
今回は信長の孫のデータの抽出を例にしましたが、DBpedia(日本語版)の例にもあるように、"誕生日が1月1日の人物"、"全国の地域限定ゆるキャラ"、"歴史の解説と見出し、位置情報"など、これ以外にも様々なデータをWikipediaから抽出することができます。
また、DBpedia(日本語版)を例にして解説しましたが、記事の数的にはDBpedia(英語版)の方が多いので、抽出するデータによって使い分けるといいかなと思います。