Python
matplotlib

e-Stat(政府統計)のAPI機能をつかってpythonでグラフを書いたりしてみる

はじめに

この記事は、e-Stat APIを初めて使ってみようというのがメインで他はおまけです。
消費者物価指数とか、経済系の統計データをあれこれ見て遊びたかったのです。
試しにぐぐってみると、e-Statというサービスがあることに気づいたので使ってみた経緯をまとめました。

なお、100倍詳しい記事が以下などにあるようですので100番煎じです。

https://qiita.com/mima_ita/items/44f358dc1bc4000d365d
https://qiita.com/R_Linux/items/e22d1ec28ab653f01f75

丁寧すぎて長くて読むの面倒くさいよ! という人向けということにさせてください。

e-Stat API

ユーザー登録 と アプリケーションIDの取得

以下のページを見ると、ユーザー登録が必要なようなのでとりあえず登録。
https://www.e-stat.go.jp/api/api-guide

登録にはメルアドとパスワード以外不要なのでとっても簡単でした。

APIの利用にはアプリケーションIDの取得が必要です。
ログインしてマイページ→API機能(アプリケーションID発行)とたどって、
名称とURLを指定する必要があります。
入力後、発行ボタンをクリックすると、アプリケーションIDはすぐに発行されます。

データの選択と取得

アプリケーションIDが取得てきたら、トップページから適当にリンクをたどってみましょう。
https://www.e-stat.go.jp/

例えば、警察庁のコンテンツには政府の犯罪統計なんかがあったりします。(というかこれくらいしかないです)
https://www.e-stat.go.jp/dbview?sid=0003194969
このページ上で簡単なグラフ表示なんかも出来ますし、csv形式などでダウンロードも出来ます。
そのまま取ってきてエクセルでグラフを書かせたり、Rで読み込ませたり。。なんてことも簡単にできるでしょう。

しかし、今回はあえてAPIを使いたいと思います。
上のアドレスの画面上の、APIボタンをクリックすると統計に対応するURLが表示されます。
例えばこんな感じ

http://api.e-stat.go.jp/rest/2.1/app/getStatsData?appId=&lang=J&statsDataId=0003194969&metaGetFlg=Y&cntGetFlg=N&sectionHeaderFlg=1

このappID= のあとの部分に先程取得したアプリケーションIDを入れたURLで、http getすると欲しいデータが手に入るというわけです。
実際に、先程取得したアプリケーションIDを設定したURLでブラウザでアクセスすると、XMLファイルが取得できます。

ここまで来れば、プログラム側でいろいろいじり放題ですね。

APIの仕様

さて、APIの詳細な仕様が知りたくなるわけですが、以下のページに情報があります。
https://www.e-stat.go.jp/api/api-spec

本稿筆記時点での最新版APIである、バージョン2.1の仕様は以下のURLのpdfファイルです。
https://www.e-stat.go.jp/api/sites/default/files/uploads/2016/07/API-specVer2.1.pdf

例えば、APIボタンをクリックして出てきたURLの例だと、
statsDataId= : 統計表ID
metaGetFlg=Y : メタデータを一緒に取得するか(Yes)
cntGetFlg=N : 件数のみ取得するか(No)
sectionHeaderFlg : csv形式のときにセクションヘッダを出力する
などという設定だということが分かります。

また
/app/getStatsDatas? : XML
/app/json/getStatsDatas? : JSON
/app/getSimpleStatsDatas? : csv
と形式が変えられることも分かります。

試しに以下のような感じのURLにすると、ちゃんとjson形式でデータが取得できました。(appのあとに/json/を加えている)
(appid=の後の部分はご自身で取得したものを入れてください。)

http://api.e-stat.go.jp/rest/2.1/app/json/getStatsData?appId=&lang=J&statsDataId=0003194969&metaGetFlg=Y&cntGetFlg=N&sectionHeaderFlg=1

なお、このAPIの利用時にはクレジットの表示が必要らしいですのでお気をつけを。
https://www.e-stat.go.jp/api/credit/

Pythonからの利用

とりあえず巷のワイドショーで言われているように凶悪犯罪が近年本当に増加の一途?
なのかを調べるために、pythonからデータを取得してmatplotlibで書かせてみましょう。

python3とmatplotlibなどの便利なものは適当にpip install してあることが前提です。
(Anacondaか何かを入れてあること前提)

なんとなくjson形式で取得することにしましょう。
以下の例はAnaconda上の、jupyter-notebookで行っています。

%matplotlib inline
import urllib
import urllib.request
import json
import matplotlib.pyplot as plt

#取得したアプリケーションIDを設定
appId = ""

#e-StatのURL
url = "http://api.e-stat.go.jp/rest/2.1/app/json/getStatsData?"

#設定するキー
keys = {
        "appId"            : appId,
        "lang"             : "J" ,
        "statsDataId"      : "0003191360" ,
        "metaGetFlg"       : "Y" ,
        "cntGetFlg"        : "N",
        "sectionHeaderFlg" : "1"
}

#keysからパラメータの文字列を生成
paramStr = urllib.parse.urlencode(keys)

#JSONデータの取得
rObj   = urllib.request.urlopen(url + paramStr)
resStr = rObj.read()

#json形式として読み込む
res = json.loads(resStr)

x_data = []
y_data = []
for value in res["GET_STATS_DATA"]["STATISTICAL_DATA"]["DATA_INF"]["VALUE"]:
    if value["@cat01"] == "100" and value["@cat02"] == "100": #cat01=100 は認知件数 cat02:100 は重要犯罪を表す。
        x_data.append(value["@time"])
        y_data.append(value["$"])

plt.plot(x_data,y_data)

で、こんなグラフが得られます。

hanzai.png

ついでなので、検挙件数のグラフも重ねてみましょう

x_data_total  = []
y_data_total  = []
x_data_arrest = []
y_data_arrest = []

for value in res["GET_STATS_DATA"]["STATISTICAL_DATA"]["DATA_INF"]["VALUE"]:
    if value["@cat01"] == "100" and value["@cat02"] == "100":
        x_data_total.append(value["@time"])
        y_data_total.append(value["$"])
    elif value["@cat01"] == "110" and value["@cat02"] == "100":
        x_data_arrest.append(value["@time"])
        y_data_arrest.append(value["$"])

plt.plot(x_data_total,y_data_total)
plt.plot(x_data_arrest,y_data_arrest)

arrest.png

最初のグラフは縦軸が恣意的(よくない例)だったので今回はy軸を0からにしました。

ここは政治ブログではないので分析は控えますが、まぁ例えばこんな結果が簡単に得られました。
Pythonすごい!(?)

ちょっとデータが揃ってなかったりとかも多いので、総務省にアクセスしないと無かったり、
PDFでしか無かったりするデータもきちんと一通り公開してくれると、
これだけで適当な論文とか書けちゃいそうで、みんなハッピーですね。