Markets & Python & ...

機関投資家の卵がPythonのコードと共に金融マーケットについて浅くつぶやきます

(季節調整値って何やねん...)

本題の前に

もう数回目の記事なので、これまでと少しだけ違った角度から話をしようと思う。
このブログは、果たしてどの層に需要があるのかよくわからないがとりあえずは、
・金融・経済の話題について
・汎用プログラミング言語Python」を用いて
・実際の経済データを分析しながら
取り上げていきたいと考えている。

その為、「金融や経済に興味がある人」や「Pythonというプログラミング言語に興味がある人」や「実際のデータにもとづいてデータ分析をしたい人・グラフを見たり描いたりして分析っぽいことをするのが好きな人」が読者になることを想定して独り言を綴っている。
これはいわゆる「AND条件」つまり条件全てに当てはまる人を対象にしている、というわけではなく「OR条件」つまりどれかに当てはまる人を対象にしているブログのつもりである。

娯楽のつもりで

自分はとある街の小さな金融機関に勤める「機関投資家の卵」のポジションに昨年就いたばかりであって、上記の各スペシャリストではない。
もしも金融・経済の第一線で活躍したいのなら経済誌を毎日読みこなすなりスペシャリストのドキュメントを読むなりすべきだ。
エンジニア を目指すなら非エンジニアの記事よりもエンジニアの記事を読んだ方が絶対に良い。
データ分析に興味がある・データサイエンティストになりたい人は某Gグル社で働く現役データサイエンティスト・TJO氏のブログを読むなりtwitterをフォローするなりした方が良い。

tjo.hatenablog.com

このブログの内容はそれらと比べると専門性に乏しい。
ただPythonはわかるけど金融はわからん、金融はわかるけど統計学は知らん、
そういう方々が、本来ならリンクしているはずなのに知識が乏しい分野に触れられる機会にできればいいと思ってこれから書こうと考えている。
もちろん、自分も勉強しながら。
娯楽だと思って読んで欲しい。

季節調整値って何やねん...

さて本題に入ると、自分を含め「季節調整値」が何をどう調整したものかわからないまま鵜呑みにしている金融サイドの人や、わからないので信用しない金融サイドの人が、少数かもしれないが一定程度いるような気がしている。
季節調整をしないとどういうことになるかを示したのが以下の図だ。
f:id:hiroshimaeasy:20200615011143p:plain

アメリカの州ごとのCOVID-19の新規感染者数を表した積み上げ面グラフだが、上下が激しく運動していて何だかよくわからない。
これは日本と同様、特定の曜日が他の曜日と比べて検査数が少ない為に、陽性者数の絶対値が少ない傾向がある為にギザつくのだと思われる。
そこで7日間平均を表すトレンドラインをプロットすると、
f:id:hiroshimaeasy:20200615011635p:plain このように傾向がわかるのだ。

特にファイナンスデータなどで特に多く見られる「時系列データ」は、「特定の曜日」「特定の月日」など、分析にあたってまず真っ先に季節特性を排除する必要がある場合が多い。

本来はこういうdata setならplotlyを推薦したい

だがしかしはっきり言って、matplotlibでこの大きなグラフを描いても同じ色が何個もあってどれがどれだかわからない。
matplotlib以外にもplotlyというインタラクティブなグラフをプロットできるツールがあって、見る方がそちらの方がわかりやすいのだがはてなブログに埋め込みできない。
plotlyのグラフ描画は別に機会を設けるとしよう。

コードスニペット

import pandas as pd
import numpy as np
import pprint
import datetime
import matplotlib.pyplot as plt
import seaborn as sns


row_data = pd.read_csv('https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_US.csv')
states_df = row_data.groupby('Province_State')

df_list = []
for dl in states_df:
    pd.DataFrame(dl)
    df_list.append(dl)
    
daily_list = []
for i in range(len(df_list)):
    daily_list.append(df_list[i][1].T[11:].sum(axis=1))
daily_df = pd.DataFrame(daily_list).T

states_list = []
for dl in range(len(df_list)):
    states_list.append(df_list[dl][0])
daily_df.columns = states_list    
daily_cases = daily_df.diff().dropna()
daily_cases.where(daily_cases > 0, 0, inplace=True)

# 何だかわからない、生データのプロット
fig, ax = plt.subplots(figsize=(4.2,3), dpi=290)
daily_cases.set_index(daily_cases.index).plot.area(
    ax=ax,
    alpha=0.75,
    lw=0.5,
    stacked=True)
plt.xticks(fontsize=4)
plt.yticks(fontsize=4)
plt.legend(loc='upper left',
           bbox_to_anchor=(1, 1))
plt.rc('legend', fontsize=2)
plt.show()

# 季節調整を施したトレンドプロット
day_cas_rol = daily_cases.rolling(7).mean().dropna()
fig, ax = plt.subplots(figsize=(4.2,3), dpi=300)
day_cas_rol.set_index(day_cas_rol.index).plot.area(
    ax=ax,
    alpha=0.75,
    lw=0.5,
    stacked=True)
plt.xticks(fontsize=4)
plt.yticks(fontsize=4)
plt.legend(loc='upper left',
           bbox_to_anchor=(1, 1))
plt.rc('legend', fontsize=2)
plt.show()