Python

Python②時系列データ処理と多項式回帰

前回はcsvのデータをグラフに書き出しました. 今回はデータのフィッティングです. といってもエラーバー付きのデータに尤もなモデル関数でフィッティングを行いカイ二乗の値を確認する...などの代物でなく, 単純なプロットをなんとなく多項式でフィットして遊ぶだけです. まずはcsvデータをpandasで時系列データとして加工していきます.

下ごしらえ

ここでは東京都オープンデータカタログサイトの東京都_新型コロナウィルス要請患者発表データを題材にしてみます.
ヘッダーの指定ととりあえず第1列をインデックスに指定しデータをまず確認してみます.

import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("130001_tokyo_covid19_patients.csv",
                 header=0,
                 index_col=0)
df

2020/01/24から公表されているようです. これは日毎の感染者数をまとめたものでなく, 感染に関する様々な情報を一人一人時系列順に網羅した非常に詳細なデータです. ここから今回知りたい一日の感染者数の推移を抽出していきます.

まずこのままでは扱いづらいので, 第4列の"公表_年月日"を時系列型(Pythonの場合datetime64[ns]型が一般的)に変換します.
また念のため都道府県名が"東京都"のデータのみを抽出してTokyo_dfというデータフレームに作り直します.

df["公表_年月日"] = pd.to_datetime(df["公表_年月日"])
Tokyo_df = df[df.都道府県名=="東京都"]

知りたいのは昇順(時系列データの場合古いものから新しいもの)に並んでいる日毎の感染者数合計なので, 以下のメソッドでカウントし簡単のためseries型に書き出します.

sr = Tokyo_df.公表_年月日.value_counts(sort=True) # 感染者数の日毎の合計を算出し, 多い日付順に並べる.
print(sr)

このままでは感染者数合計が多かった日付順に並んでいるため, sort_indexメソッドで今回のindexである時系列情報の昇順(古いものから新しいもの順)に並び替えます.

sr = sr.sort_index() # 時系列型indexの昇順に並び替える.

日毎の感染者合計値が時系列にまとまりました.
ちなみにseries型はplotメソッドで以下のように手軽にグラフが出力できます.

フィッティング

さっそくフィッティングを行いたいところですが, 上のデータの横軸は2020-01-24から2021-10-3までの86400秒(1日)刻みのdatetime64型配列になっています. これをまず通常の例えばfloat型などに変換しないとfittingライブラリは処理してくれません.
次のように時系列配列をfloat型配列xarrayに変換します.

data   = np.array(sr)
length = len(data)
# srのindexはdatetime型
# フィッティングしてグラフに書き出す際に1970/01/01/00:00:00から数えて何日目(86400秒で割り日数に変換)
# から何日目までのデータなのか変換する必要が出てくる.
initial_day = pd.to_datetime(str(sr.index[0])).timestamp()/86400 # 初日
final_day   = pd.to_datetime(str(sr.index[-1])).timestamp()/86400 # 最終日
#print(initial_day,final_day)
xarray             = np.linspace(initial_day,final_day,length)

コメントにもあるようにdatetime64型は1970年1月1日00時00分から一秒ずつ値を取るよう実装されています.

あとはNumpyのpolyfitクラスでフィッティングし, 得た多項式係数配列をpoly1dクラスに渡しグラフに描き出します.

# np.polyfitとnp.poly1dによるfitting
highest_order      = 70
fitting_polynomial = np.polyfit(xarray, data, highest_order)
fitting_function   = np.poly1d(fitting_polynomial)

plt.plot(xarray,
         fitting_function(xarray),
         label = str(highest_order) + " order polyfit",color='red')

sr.plot(label='data')

plt.xlabel("Date")
plt.ylabel("sum per day")
plt.title("daily # tested positive and fitting by polynomials")
plt.legend(loc='best')

70次もの多項式ですが全くデータの傾向に追従できていません. 感染症患者数推移に限らず人文社会学系のデータ解析ではどうのようなモデル関数が使われるのでしょう...

-Python

Copyright© ExpPhys_hacks , 2021 All Rights Reserved Powered by AFFINGER5.