Python

【Python】家計を見直してみた part3

こんにちは。

前回のPart2での分析から、最後月ごとの最大支出などを調べていきます。

一応今回で一旦最後にしますが、また調査した内容を投稿するかもしれないです。

今回は以下の内容について調べてみました。

  1. 合計支出と1決済あたりの最大支出の相関係数
  2. ブートストラップ法を用いた95%信頼区間の算出





1.合計支出と1決済あたりの最大支出の相関係数

まずは、月ごとの最大支出をdictに入れていきます。

#月ごとの最大支出額
data_outcome_max_by_month = {}
for month in months:
  data_outcome_max_by_month[month] = -(data_drop_income[data_drop_income['日付'].str.startswith(month)]['金額']).min()
data_outcome_max_by_month.items()
>dict_items([('2019/05', 40600), ('2019/06', 5880), ('2019/07', 29376), ('2019/08', 25077),
('2019/09', 5850), ('2019/10', 9394), ('2019/11', 70990), ('2019/12', 27180), ('2020/01', 26440),
('2020/02', 55000), ('2020/03', 7800), ('2020/04', 10070), ('2020/05', 22408), ('2020/06', 70990),
('2020/07', 19466), ('2020/08', 30000), ('2020/09', 14654), ('2020/10', 20071), ('2020/11', 30000),
('2020/12', 25420), ('2021/01', 45907), ('2021/02', 165000), ('2021/03', 120000), ('2021/04', 121500),
('2021/05', 121500), ('2021/06', 121500), ('2021/07', 364500), ('2021/08', 32780), ('2021/09', 19920),
('2021/10', 39540), ('2021/11', 87000), ('2021/12', 87000), ('2022/01', 131370), ('2022/02', 87870),
('2022/03', 87870), ('2022/04', 87870), ('2022/05', 87870), ('2022/06', 87870), ('2022/07', 164800),
('2022/08', 87870), ('2022/09', 87870), ('2022/10', 87870)])

データは揃ったので、相関係数を求めていきます。

#合計支出と最大支出の相関係数を算出
import seaborn as sns
df_outcome_total = pd.DataFrame(data_total_by_month.values(), columns=["outcome_total"])
df_outcome_max = pd.DataFrame(data_outcome_max_by_month.values(), columns=["outcome_max"])
df = pd.concat([df_outcome_total, df_outcome_max], axis=1)
corr = df.corr()
corr

indexoutcome_totaloutcome_max
outcome_total1.00.93414386570948
outcome_max0.934143865709481.0

相関係数を算出できました。

これをグラフで見ていきましょう。

plt.scatter(data_total_by_month.values(), data_outcome_max_by_month.values())

X軸が1決済あたりの最大支出で、Y軸がその月の合計支出です。

グラフを見ると、1つ桁外れに支出が大きいデータがあることがわかります。

これを外れ値として取り除いて、再度相関係数を算出してみます。

外れ値を取り除く
del data_outcome_max_by_month['2021/07']
del data_total_by_month['2021/07']

df_outcome_total = pd.DataFrame(data_total_by_month.values(), columns=["outcome_total"])
df_outcome_max = pd.DataFrame(data_outcome_max_by_month.values(), columns=["outcome_max"])
df = pd.concat([df_outcome_max, df_outcome_total], axis=1)
df.corr()
indexoutcome_maxoutcome_total
outcome_max1.0000000.862786
outcome_total0.8627861.000000

外れ値を取り除いたとしても、相関関係はありそうです。

グラフでも見ていきます。

plt.scatter(data_total_by_month.values(), data_outcome_max_by_month.values())

当たり前かもしれませんが、大きな買い物をしたときはその月の支出額が多い傾向にあります。

逆に言えば、大きな買い物をしない限り、普段の生活は平均的なものになっているのですかね。

それでは、合計支出と最大支出を除いた合計支出の散らばりを見ていきましょう。

#合計支出から最大支出を引いた値を算出(外れ値の2021/07を除く)
data_total_without_maxoutcome = {}
months_new = ['2019/05', '2019/06', '2019/07', '2019/08', '2019/09', '2019/10', '2019/11', '2019/12', '2020/01', '2020/02', '2020/03', '2020/04', '2020/05', '2020/06', '2020/07', '2020/08', '2020/09', '2020/10', '2020/11', '2020/12', '2021/01', '2021/02', '2021/03', '2021/04', '2021/05', '2021/06', '2021/08', '2021/09', '2021/10', '2021/11', '2021/12', '2022/01', '2022/02', '2022/03', '2022/04', '2022/05', '2022/06', '2022/07', '2022/08', '2022/09', '2022/10']
for i in range(0, len(months_new)):
 data_total_without_maxoutcome[months_new[i]] = data_total_by_month.get(months_new[i]) - data_outcome_max_by_month.get(months_new[i])
data_total_without_maxoutcome.items()
>dict_items([('2019/05', 110957), ('2019/06', 60471), ('2019/07', 91829), ('2019/08', 132166),
('2019/09', 91433), ('2019/10', 79035), ('2019/11', 148026), ('2019/12', 212320), ('2020/01', 164830), 
('2020/02', 115329), ('2020/03', 92285), ('2020/04', 69843), ('2020/05', 97752), ('2020/06', 110129), 
('2020/07', 154875), ('2020/08', 198973), ('2020/09', 82068), ('2020/10', 92580), ('2020/11', 147236), 
('2020/12', 139329), ('2021/01', 165771), ('2021/02', 185841), ('2021/03', 211282), ('2021/04', 351184), 
('2021/05', 213970), ('2021/06', 190060), ('2021/08', 255124), ('2021/09', 195307), ('2021/10', 139442), 
('2021/11', 177887), ('2021/12', 177111), ('2022/01', 230353), ('2022/02', 105024), ('2022/03', 248140), 
('2022/04', 253572), ('2022/05', 210348), ('2022/06', 257529), ('2022/07', 238046), ('2022/08', 158430), 
('2022/09', 182691), ('2022/10', 137072)])

最大支出を除いた合計値をdictにつめています。

分散と標準偏差を求めてみます。

ライブラリを使えば問題ないです。

import statistics
print(f'分散:  {statistics.pvariance(list(data_total_by_month.values()))}')
print(f'分散(最大支出除く):  {statistics.pvariance(list(data_total_without_maxoutcome.values()))}')
print(f'標準偏差:  {statistics.pstdev(list(data_total_by_month.values()))}')
print(f'標準偏差(最大支出除く):  {statistics.pstdev(list(data_total_without_maxoutcome.values()))}')
>分散:  9503126592.497322
分散(最大支出除く):  4002429009
標準偏差:  97483.98120972143
標準偏差(最大支出除く):  63264.753291228444

最大支出を除いた合計支出の方が散らばりが少なそうです。

大きなお買い物はできるだけ控えて、する場合は分割で払ったほうが支出は少なくて済む気がしてきました。

これ以上の分析はどうやったらいいか分からないので、ここで止めておきます。

続いて、ブートストラップ法を用いて、合計支出額の95%信頼区間を求めていきます。





2.ブートストラップ法を用いた95%信頼区間の算出

そもそもブートストラップ法とは何なのかというのは、下記のサイトで説明しています。

以下のコードによって、95%信頼区間を求めることができました。

from scipy import stats

#サンプルデータ抽出のため、月ごとの合計支出をDataFrameに入れる
outcome_df = pd.DataFrame(list(data_total_by_month.values()), index=data_total_by_month.keys(), columns=['金額']).T
outcome_df

#空データの作成
sample_mean_data = []
df_sample_mean_data = pd.DataFrame(index=[], columns=[])
n=12
for i in range(1, 1000):
  #合計支出のうち、12個だけサンプリング
  sample_data = outcome_df.sample(axis=1, n=12, replace=True)
  #サンプリングしたデータの平均を取る
  sample_mean_data = sample_data.mean(axis=1)
  #取った平均をdataframeに入れていく
  df_sample_mean_data = df_sample_mean_data.append(sample_mean_data, ignore_index=True)

#ヒストグラムの作成
df_sample_mean_data.hist()

#95%信頼区間を算出
sample_var = stats.tvar(df_sample_mean_data)
print(stats.norm.interval(alpha=0.95, loc=df_sample_mean_data.mean(), scale=np.sqrt(sample_var/n)))
>(array([206337.5328835]), array([238054.0004832]))

処理としては、合計支出から12個サンプリングして、その平均値を繰り返し取得しています。

95%信頼区間は(array([206337.5328835]), array([238054.0004832]))となっているため、合計支出額の平均の95%は20万〜24万円弱に該当しそうです。

ヒストグラムは以下の通りとなりました。

この解釈が合っているのかはわかりませんが、最近ブートストラップ法を学んだので、実際に使ってみました。

これからも、いろんなデータを使って調べていこうと思います。

Google広告