はじめに
先日twitterで7日間移動平均で新型コロナウイルスの感染者数を見ている、というツイートを何件か見かけました。
自分でオープンデータ等から可視化までしてみたかったのでやってみました。
今回使用したデータは東京都が公開しているデータとなります。
グラフ
まずグラフを見てもらうのがはやいと思います。
青軸の棒グラフがその日明らかになった陽性患者さんの数、ピンクの折れ線グラフが7日間移動平均をとった陽性患者さんの数です。
油断はもちろんいけませんし、これだけを見て一概にコロナの封じ込めに成功しているとは言えませんが、折れ線グラフは右肩下がりになっているように見えます。
移動平均
統計学で用いられるもので、
時系列データにおいて、ある一定区間ごとの平均値を区間をずらしながら求めたものです。
引用先:https://bellcurve.jp/statistics/blog/15528.html
つまり、以下のようなデータがあった時、3項の移動平均はそれぞれ前後1つずつの値の平均を計算するので、
1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|
以下のようになります。
1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|
X | 2 | 3 | 4 | 5 | 6 | X |
今回は±3日間の7日間移動平均をとったので、前後3日間の平均をとっています。
numpyを使った移動平均の取得
こちらのサイトを参考にさせていただきました。
numpy.convolve
を使います。
numpy.convolve(ndaaray, karnel, mode)
引数 | 内容 |
---|---|
ndaaray | 時系列データのnumpy配列 |
karnel | カーネル関数(何点で移動平均を求めるかで決定) |
mode | same:時系列データと同じ要素数で結果出力, valid:時系列データよりも短い要素数で結果出力 |
データの可視化
からあげさんの記事で公開されていたGoogle Colab をまるまる使わせていただきました。ありがとうございます。
話はそれますがからあげさんという方は自分の研究分野でもあるロボット関係の方でもよく記事を参考にさせていただいています。いつもありがとうございます。(急に信者)
からあげさんのものからの変更部分だけ抜粋して以下に記載します。
まず、完全に個人的な好みでseabornをimportしました。
【変更】日付データの読み込み
ここはx軸のラベルをきれいにしたかったのでdatetime型にしました。
date_data = np.array([])
for i in range(len(data['inspection_persons']['labels'])):
date_data = np.append(date_data, pd.to_datetime(data['inspection_persons']['labels'][i][0:10]))
print(date_data)
【追加】7日間移動平均の計算
もともとあった陽性の患者さんの配列をnumpy配列にして、上記の移動平均を計算しています。
また、±3日分をnp.nan
で埋めています
# 7日間の移動平均
n=7
patients_data_np_array = np.array(patients_data)
patients_data_move_ave = np.convolve(patients_data_np_array, np.ones(n)/float(n), 'valid')
nan_array = np.array([np.nan,np.nan,np.nan])
patients_data_move_ave = np.insert(patients_data_move_ave,0,nan_array)
patients_data_move_ave = np.insert(patients_data_move_ave,len(patients_data_move_ave),nan_array)
【変更】データ可視化部分
上記の7日間移動平均を折れ線グラフでいれました。
plt.figure(figsize=(9,6))
plt.bar(date_data, patients_data,label='number of patients')
plt.plot(date_data, patients_data_move_ave,color='salmon', linewidth = 3.0,label='moving average of number of patients')
plt.legend()
すべてのプログラム
以下、今回のプログラムです。
環境はGoogle Colabratoryとなるので最初のbashはマジックコマンド(!)を付けて実行するものです。
普通にwgetしているだけなのでGoogle Colabratoryでなくとも使えます。
!wget --no-check-certificate --output-document=covid19_tokyo.json 'https://raw.githubusercontent.com/tokyo-metropolitan-gov/covid19/development/data/data.json'
以下がPythonプログラムです。
# ライブラリのとデータの読み込み
import pandas as pd
import numpy as np
data = pd.read_json('covid19_tokyo.json')
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
# 日付データ
date_data = np.array([])
for i in range(len(data['inspection_persons']['labels'])):
date_data = np.append(date_data, pd.to_datetime(data['inspection_persons']['labels'][i][0:10]))
# 陽性患者データ
patients_data = []
for i in range(len(data['inspection_persons']['labels'])):
patients_data.append(data['patients_summary']['data'][i]['小計'])
# 7日間移動平均の計算
n=7
patients_data_np_array = np.array(patients_data)
patients_data_move_ave = np.convolve(patients_data_np_array, np.ones(n)/float(n), 'valid')
# nanで埋める
nan_array = np.array([np.nan,np.nan,np.nan])
patients_data_move_ave = np.insert(patients_data_move_ave,0,nan_array)
patients_data_move_ave = np.insert(patients_data_move_ave,len(patients_data_move_ave),nan_array)
# 可視化
plt.figure(figsize=(9,6))
plt.bar(date_data, patients_data,label='number of patients')
plt.plot(date_data, patients_data_move_ave,color='salmon', linewidth = 3.0,label='moving average of number of patients')
plt.legend()
結果は以下のグラフになります。
おわりに
twitterで見かけたものをすぐ自分で可視化できたのもデータを公開していただいている東京都のおかげであったり、データの収集方法や移動平均の手法を公開していただいている皆さんのおかげだと感じることができました。
これからもやろう!と思ったらすぐやれるように色々知識をつけていきたいです。
参考にさせていただいたサイト
移動平均
移動平均 統計WEB 統計学の時間
移動平均の計算方法 統計WEB ブログ
可視化
新型コロナウイルス感染症(COVID-19)のオープンデータをGoogle Colaboratoryで手軽に可視化・分析する方法
上記記事のGoogleClobratory