季節調整

経済データの季節調整

総務省統計局の公開している「家計調査(家計収支編) 時系列データ(二人以上の世帯)」のデータを分析します。

参考文献:経済産業省 鉱工業指数(生産・出荷・在庫、生産能力・稼働率)、製造工業生産予測指数 季節調整手法

データの前処理

配布されているデータには空白のセルや複数にまたがるセルが含まれていて、このまま処理するのは難しいです。 必要な範囲だけを切り取り数値に変換した new_df を用意します。

import pandas as pd

df = pd.read_csv("./支出金額.csv", encoding="cp932")
df.head(15)
二人以上の世帯_支出金額[円]Unnamed: 1Unnamed: 2Unnamed: 3Unnamed: 4Unnamed: 51234...260261262263264265266267268269
0NaNNaNNaNNaNNaNNaN2000年NaNNaNNaN...NaNNaNNaNNaNNaN2022年NaNNaNNaNNaN
1NaNNaNNaNNaNNaNNaN(平成12年)NaNNaNNaN...NaNNaNNaNNaNNaN(令和4年)NaNNaNNaNNaN
2表側連番階層大分類中分類小分類品目分類1月2月3月4月...8月9月10月11月12月1月2月3月4月5月
31----世帯数分布(抽出率調整)10000100001000010000...10000100001000010000100001000010000100001000010000
42----集計世帯数7887794279347922...7397737874077411741673537315736973577391
53----世帯人員(人)3.323.323.323.32...2.932.932.932.932.922.922.922.922.912.91
64----18歳未満人員(人)0.740.750.750.75...0.550.560.560.550.550.550.550.540.550.55
75----65歳以上人員(人)0.520.530.530.52...0.850.830.840.840.850.840.850.840.840.84
86----うち無職者人員(人)0.410.410.410.41...0.680.670.680.670.670.670.680.660.670.67
97----有業人員(人)1.511.511.511.52...1.331.331.331.341.331.331.311.331.331.34
108----世帯主の年齢(歳)52.452.652.752.6...60.159.959.959.960.26060.260.16060
119----持家率(%)7676.376.275.8...84.184.184.484.484.183.98484.48584.8
1210----家賃・地代を支払っている世帯の割合(%)22.12222.622.2...14.914.613.91414.814.614.913.813.413.8
13111---消費支出309621290663335341335276...266638265306281996277029317206287801257887307261304510287687
141221--食料73580733097972677344...81412766737954378490995187597471655799827701482066

15 rows × 275 columns

new_df = pd.DataFrame(
    {
        "日付": pd.date_range(start="2000/1/1", end="2022/5/1", freq="MS"),
        "消費支出": pd.to_numeric(df.iloc[13][6:]),
    }
)
new_df = new_df.set_index("日付")
new_df["消費支出"] = (new_df["消費支出"] / new_df["消費支出"].mean()) * 100.0

new_df.head(10)
消費支出
日付
2000-01-01105.629546
2000-02-0199.161881
2000-03-01114.404119
2000-04-01114.381944
2000-05-01105.269625
2000-06-01101.544867
2000-07-01111.381122
2000-08-01105.756457
2000-09-01101.138548
2000-10-01105.483531

データをプロットしてみる

import japanize_matplotlib as jm
import matplotlib.pyplot as plt
import seaborn as sns

sns.set(rc={"figure.figsize": (15, 8)})
jm.japanize()
sns.lineplot(data=new_df, x="日付", y="消費支出")
plt.show()

png

傾向変動を取り除く

人口増加などの要因による長期間にわたる変動傾向。移動平均線を用いたり、最小二乗法による直線・曲線のフィッティングなど、統計データによって手法は異なる。

参考:numpy.polyfit — NumPy v1.23 Manual

import numpy as np

idx = [i for i in range(new_df.shape[0])]

傾向変動の関数の係数 = np.polyfit(idx, new_df["消費支出"], 3)
傾向変動の関数 = np.poly1d(傾向変動の関数の係数)
new_df["傾向変動"] = 傾向変動の関数(idx)
new_df["傾向変動調整分"] = new_df["消費支出"] - 傾向変動の関数(idx) + np.mean(傾向変動の関数(idx))

sns.set(rc={"figure.figsize": (15, 8)})
jm.japanize()
sns.lineplot(data=new_df, x="日付", y="消費支出", label="消費支出")
sns.lineplot(data=new_df, x="日付", y="傾向変動", label="傾向変動")
# sns.lineplot(data=new_df, x="日付", y="傾向変動調整分", label="傾向変動調整分")
plt.show()

png

循環変動

キチンサイクルなど、数年周期の変動を指すことが多い。

季節変動

一年を周期とした周期的な変動を総称して「季節変動」と呼ぶ。月別平均法・連環比率法など。

①過去の複数年の月別平均値を求める

new_df["月"] = new_df.index.month
季節ごとの平均値 = new_df.groupby("月").mean()["消費支出"]
季節ごとの平均値
月
1     100.083036
2      92.102619
3     107.280556
4     104.477264
5      97.832924
6      94.348753
7      98.973205
8      99.165835
9      95.138160
10     99.351828
11     96.230671
12    114.934402
Name: 消費支出, dtype: float64

②月別平均値の合計を求める

月別平均値の合計 = 季節ごとの平均値.sum()
print(f"月別平均値の合計 = {月別平均値の合計}")
月別平均値の合計 = 1199.9192545557726

③修正係数を計算する

修正係数 = 1200.0 / 月別平均値の合計
print(f"修正係数 = {修正係数}")
修正係数 = 1.0000672923981517

④月別平均に修正係数を乗じる

修正済みの季節ごとの平均値 = 修正係数 * 季節ごとの平均値
# 各月のデータから修正済みの季節ごとの平均値を引いています
new_df["季節変動調整分"] = new_df["消費支出"] - new_df["月"].apply(lambda m: 修正済みの季節ごとの平均値[m])
new_df.to_csv("支出金額_加工済みデータ.csv", encoding="utf-8-sig")

# グラフを作成
sns.set(rc={"figure.figsize": (15, 8)})
jm.japanize()
sns.lineplot(data=new_df, x="日付", y="消費支出", label="消費支出")
sns.lineplot(data=new_df, x="日付", y="傾向変動", label="傾向変動")
sns.lineplot(data=new_df, x="日付", y="季節変動調整分", label="季節変動調整分")
plt.show()

png