見出し画像

【データの集めかた講座】PythonでLinked Open Dataを取得する-オリンピックデータを探索-

はじめに

ご高覧いただきありがとうございます.
ソフトウェアエンジニアのKitaharaです.
本日は葛飾北斎をテーマに「とりあえず基本的なことなら書ける」を
目標にSPARQLの基本文法を解説します!

SPARQLが初めてという方へ

SPARQLは便利ではあるのですが少しマイナーな言語です.
そこでSPARQLは何かや基礎文法をまとめた記事を作りました!
まずはこちらから見てみてください!

SPARQLとは何か

SPARQLの基礎文法

使用する言語・ライブラリ・エディタ等の説明

PythonライブラリのSPARQLWrapperをインストールするとSPARQLを簡単に実行することができますのでそれを使っていきます.

  • SPARQLWrapper

    • PythonでSPARQLを使うためのライブラリです.

    • pip install ですぐに使うことができます.

    • 公式ドキュメント

  • Python

    • プログラミング言語のひとつです.

    • 型宣言等が無く, 初心者にも扱いやすい言語だと言われています

    • 近年Deep Learningのライブラリが豊富であることから注目を集めている人気の言語です

    • 公式ドキュメント

  • Google Colab

    • Googleが提供するPythonの実行環境です

    • 主要なライブラリがインストールされている状態で使うことができます

    • Chromeでアクセスするだけで利用することができます

      • 環境構築が不要です

      • 無料で使うことができます

環境構築

SPARQLWrapper

下記のコードをGoogle Colubで実行してください

# Google Colubでコマンドを打つときは「!」を先頭に付ける
!pip install sparqlwrapper

これで今回使うライブラリはすべて揃いました!

問題設定

今回は日本でのオリンピックについて調べてみることにします
どこでいつ行われたかと大会の概要と取得することを目標にします.

SPARQLでデータ探索

データ探索

まずは日本と関係性のあるオリンピック大会のデータを入手してみましょう
日本と関係のある対象のうち, オリンピックを含むものを表示してみます.

(dbpj:日本) -- (?p) --> (?o)
に当てはまるグラフデータのうち, ?oに当てはまるものだけを検索します.

from SPARQLWrapper import SPARQLWrapper

sparql = SPARQLWrapper(endpoint='http://ja.dbpedia.org/sparql', returnFormat='json')
sparql.setQuery("""
    PREFIX dbpj: <http://ja.dbpedia.org/resource/>
    PREFIX dbp-owl: <http://dbpedia.org/ontology/>
    PREFIX dbp-prop: <http://ja.dbpedia.org/property/>

    SELECT ?p, ?o
    WHERE {
        dbpj:日本 ?p ?o
        FILTER REGEX (?o, "オリンピック")
    }
""")
results = sparql.query().convert()

コードで少し難しいところはsparqlというSPARQLWrapperクラスのインスタンスを作り動かしている部分だと思います.

4行目ではSPARQLWrapperクラスのインスタンスに対してクラス内メソッド, setQuery()を使ってクエリを定義しています. 

15行目ではクラス内メソッドquery()で実行したものをクラス内メソッドconvert()でコンバートして変数resultsに代入しています.

実行して問題が無ければ以下のコードを動かしてみてください.

INPUT

for i in range(len(results["results"]["bindings"])):
    print(results["results"]["bindings"][i]["p"]["value"],results["results"]["bindings"][i]["o"]["value"])

OUTPUT

http://dbpedia.org/ontology/wikiPageWikiLink http://ja.dbpedia.org/resource/1912年ストックホルムオリンピック
http://dbpedia.org/ontology/wikiPageWikiLink http://ja.dbpedia.org/resource/1912年ストックホルムオリンピックの日本選手団
http://dbpedia.org/ontology/wikiPageWikiLink http://ja.dbpedia.org/resource/1940年東京オリンピック
http://dbpedia.org/ontology/wikiPageWikiLink http://ja.dbpedia.org/resource/1964年東京オリンピック
http://dbpedia.org/ontology/wikiPageWikiLink http://ja.dbpedia.org/resource/1972年札幌オリンピック
http://dbpedia.org/ontology/wikiPageWikiLink http://ja.dbpedia.org/resource/1998年長野オリンピック
http://dbpedia.org/ontology/wikiPageWikiLink http://ja.dbpedia.org/resource/2020年東京オリンピック
http://dbpedia.org/ontology/wikiPageWikiLink http://ja.dbpedia.org/resource/オリンピック聖火
http://dbpedia.org/ontology/wikiPageWikiLink http://ja.dbpedia.org/resource/日本オリンピック委員会
http://dbpedia.org/ontology/wikiPageWikiLink http://ja.dbpedia.org/resource/近代オリンピック

オリンピックに関する情報がたくさん出てきました.
ですが, 私たちが欲しいデータは日本で行われたオリンピックです.
そこで場所で絞れないか調べてみることにします.

INPUT

sparql = SPARQLWrapper(endpoint='http://ja.dbpedia.org/sparql', returnFormat='json')
sparql.setQuery("""
    PREFIX dbpj: <http://ja.dbpedia.org/resource/>
    PREFIX dbp-owl: <http://dbpedia.org/ontology/>
    PREFIX dbp-prop: <http://ja.dbpedia.org/property/>

    SELECT ?p, ?o
    WHERE {
        dbpj:1940年東京オリンピック ?p ?o
    }
""")
results = sparql.query().convert()
for i in range(len(results["results"]["bindings"])):
    print(results["results"]["bindings"][i]["p"]["value"],results["results"]["bindings"][i]["o"]["value"])

OUTPUT

http://www.w3.org/2000/01/rdf-schema#label 1940年東京オリンピック
http://www.w3.org/2000/01/rdf-schema#comment 1940年東京オリンピック(1940ねんとうきょうオリンピック)は、1940年(昭和15年)9月21日から10月6日まで、日本の東京府東京市(現・東京23区)で開催されることが予定されていた夏季オリンピックである。 史上初めて欧米以外の、アジアで行われる五輪大会、そして紀元二千六百年記念行事として準備が進められていたものの、日中戦争(支那事変)の影響等から日本政府が開催権を返上、実現には至らなかった。
http://ja.dbpedia.org/property/主競技場 駒沢競技場(予定)
...
http://ja.dbpedia.org/property/開催都市 東京市(現・東京都区部(東京23区))
...
http://dbpedia.org/ontology/abstract 1940年東京オリンピック(1940ねんとうきょうオリンピック)は、1940年(昭和15年)9月21日から10月6日まで、日本の東京府東京市(現・東京23区)で開催されることが予定されていた夏季オリンピックである。 史上初めて欧米以外の、アジアで行われる五輪大会、そして紀元二千六百年記念行事として準備が進められていたものの、日中戦争(支那事変)の影響等から日本政府が開催権を返上、実現には至らなかった。
http://xmlns.com/foaf/0.1/isPrimaryTopicOf http://ja.wikipedia.org/wiki/1940年東京オリンピック
http://dbpedia.org/ontology/wikiPageLength 13371

「dbp-prop:開催都市」という関係性が見つかりました.
これを使ってデータの絞り込みをします.

データ取得

早速条件に合うデータを取得してみましょう

INPUT

from SPARQLWrapper import SPARQLWrapper
sparql = SPARQLWrapper(endpoint='http://ja.dbpedia.org/sparql', returnFormat='json')
sparql.setQuery("""
    PREFIX dbpj: <http://ja.dbpedia.org/resource/>
    PREFIX dbp-owl: <http://dbpedia.org/ontology/>
    PREFIX dbp-prop: <http://ja.dbpedia.org/property/>
    PREFIX rdf-label: <http://www.w3.org/2000/01/rdf-schema#label>

    SELECT ?name, ?city, ?abs
    WHERE {
        dbpj:日本 ?p ?olympic.
        ?olympic rdf-label: ?name.
        ?olympic dbp-prop:開催都市 ?city.
        ?olympic dbp-owl:abstract ?abs.
        FILTER REGEX (?olympic, "オリンピック")
        FILTER (REGEX (?name, "東京") || REGEX (?name, "長野") || REGEX (?name, "札幌"))
    }
""")
results = sparql.query().convert()

一点補足です.

FILTER (REGEX (?name, "東京") || REGEX (?name, "長野") || REGEX (?name, "札幌"))

の部分は?nameに東京か長野か札幌が含まれているという意味になります.
(通常のSQL文のWHEREにあたります)

データの整形・保存

実行ができたらデータを確認しつつ取り出します.
変数dataに一行ずつデータを入れておきます.
(このようにするとPandasのDataFrameが作りやすいからです.)

INPUT

data = []
for i in range(len(results["results"]["bindings"])):
    print(results["results"]["bindings"][i]["name"]["value"],results["results"]["bindings"][i]["city"]["value"],results["results"]["bindings"][i]["abs"]["value"])
    data.append([results["results"]["bindings"][i]["name"]["value"],results["results"]["bindings"][i]["city"]["value"],results["results"]["bindings"][i]["abs"]["value"]])

OUTPUT

※伏字はnoteの警告が表示されてしまうためです.

1940年東京オリンピック 東京市(現・東京都区部(東京23区)) 1940年東京オリンピック(1940ねんとうきょうオリンピック)は、1940年(昭和15年)9月21日から10月6日まで、日本の東京府東京市(現・東京23区)で開催されることが予定されていた夏季オリンピックである。 史上初めて欧米以外の、アジアで行われる五輪大会、そして紀元二千六百年記念行事として準備が進められていたものの、日中戦争(支那事変)の影響等から日本政府が開催権を返上、実現には至らなかった。
1964年東京オリンピック 東京都 1964年東京オリンピック(1964ねんとうきょうオリンピック)は、1964年(昭和39年)10月10日(後の体育の日)から10月24日までの15日間、日本の東京都で開かれたオリンピック競技大会。 一般的に東京オリンピック(とうきょうオリンピック)と呼称され、東京五輪と略称される。公用文では第十八回オリンピック競技大会の表記もみられる。
1972年札幌オリンピック 札幌 1972年札幌オリンピック(さっぽろオリンピック)は、日本の北海道札幌市で1972年(昭和47年)2月3日から2月13日まで行われた冬季オリンピックである。日本およびアジアでは初めての開催された冬季オリンピックとなった。
1998年長野オリンピック 長野 1998年長野オリンピック(1998ねんながのオリンピック)は、1998年(平成10年)2月7日から2月22日まで日本の長野県長野市を中心とする地域を会場として開催された20世紀最後の冬季オリンピックである。冬季オリンピックの歴代開催地の中では、長野は最も南に位置する緯度の地域だった。 72の国(地域)から選手・役員4638人が参加し、延べ144万2700人の観客が会場に集った。 長野オリンピックの競技会場は長野市、白馬村、山ノ内町、軽井沢町、野沢温泉村に配置され、このうち人口が最も多く県庁所在地である長野市が主催都市(Host city)だった。そのため、1994年リレハンメルオリンピックおよび長野オリンピックの閉会式では、いずれも次回開催地への引き継ぎセレモニーで当時の長野市長だった塚田佐が出席した 。
2020年東京オリンピック 東京都 2020年東京オリンピック(2020ねんとうきょうオリンピック)は、2021年(令和3年)7月23日から8月8日までの17日間、日本の東京都で開催される予定のオリンピック競技大会。***********の世界的流行を受けて、2020年夏の開催日程から1年延期となった()。 一般的には東京オリンピック(とうきょうオリンピック)と呼称され、東京五輪(とうきょうごりん)と略称される。また、東京2020(とうきょう2020)オリンピック競技大会やTOKYO 2020という呼称も使用される。大会延期により開催年は変わるが、後述の通り「東京2020」の名称に変更はない。なお、公用文では第三十二回オリンピック競技大会(だいさんじゅうにかいオリンピックきょうぎたいかい)の表記が用いられている。 東京での五輪開催は、1964年(昭和39年)以来、56年ぶり(延期のため実際は57年ぶり)となる。大会組織委員会は東京オリンピック・パラリンピック競技大会組織委員会(TOCOG)。

データフレームにして保存します.
Pandasは最初からGoogle Colabに入っているのでinstallは不要です.

encodingですが, Macの方はutf-8にしてください. 文字化けします. また, shift-jisの場合はColabで表示しようとすると文字化けになります必要に応じて変えてください.

import pandas as pd

df = pd.DataFrame(data, columns=['name','city','abs'])
display(df)
df.to_csv('olympic_data.csv',encoding='shift-jis')
左下のファイルのアイコンを押してファイルが作成されたかを確認

ファイルを取得してみましょう.

取得したデータを確認

無事取得できました!

おわりに

今回はPythonとSPARQLを使ってLinked Open Dataを取得する方法を解説しました!参考になったという方はぜひハートボタンを押してください!

モチベーションが上がります!

記事内で不明な点等ございましたら気軽にご連絡ください.

Twitter: @kitahara_dev
email: kitahara.main1@gmail.com

おまけ

Google Colabの共有でコードを見れるようにしました!

本日取得したデータです

参考文献



この記事が気に入ったらサポートをしてみませんか?