データ解析初心者がpandasの勉強として、1世帯当りのアイスクリーム支出額と気温との関係を調べてみました。(なんとなく結果は見えていますが...)
参考にしたのは「Pythonによるデータ解析入門」と以下の2つのサイトです。
上のサイトに掲載されている2018年のデータを用いました。
Webスクレイピングでデータを取り出し
import pandas as pd
import math
import matplotlib.pyplot as plt
import statsmodels.api as sm
ice_url = 'http://www.icecream.or.jp/biz/data/expenditures.html'
temp_url = 'http://www.data.jma.go.jp/obd/stats/etrn/view/monthly_s3.php?%20prec_no=44&block_no=47662'
ice = pd.read_html(ice_url)[0]
temp = pd.read_html(temp_url)[0]
# [0]で1つ目のテーブルを指定している
ice_2018 = ice.iloc[1:13, 5].astype(float)
temp_2018 = temp.iloc[144, 1:13].astype(float)
# 2018年のデータのみ取り出して数値型に変換
month = pd.DataFrame([i for i in range(13)])
# n月を用意しておく
これで2018年の1世帯当りのアイスクリーム支出金額と月間平均気温を取り出せました。
相関を求める
icecream = pd.concat([month, ice_2018, temp_2018], axis=1)[1:]
# n月とアイス支出金額、平均気温を結合
x_data, y_data = icecream[144], icecream[5]
avetem, aveex = x_data.sum() / 12, y_data.sum() / 12
# 年間平均気温(avetem)とアイスクリーム支出(aveex)が求められた
相関係数は共分散 $S_{xy}$ などを用いて以下のように表されました。
r = \frac{S_{xy}}{\sqrt{S_{xx}S_{yy}}}
この式に従って相関係数 $r$ を以下のように愚直に求めました。(もっと良いやり方があると思います)
for i in range(len(icecream)):
ex = icecream.iloc[i,1] - aveex
tem = icecream.iloc[i,2] - avetem
extem += ex*tem
ex0 += ex**2
tem0 += tem**2
extem0 = math.sqrt(ex0)*math.sqrt(tem0)
r = extem / extem0
# r = 0.8955143151163499
この結果からアイスクリームの支出と気温の間に強い相関があることが分かります。
回帰分析
最後にpandasのolsを用いて回帰分析をしてみます。
X = sm.add_constant(x_data) # 切片を求めるには必要らしい
model = sm.OLS(y_data, X)
results = model.fit()
a, b = results.params[0], results.params[1]
# a:切片、b:傾き
plt.plot(x_data, a+b*x_data)
plt.scatter(icecream[144], icecream[5])
結果、図のような回帰直線が得られました。
なるほど、暑くなるとアイスを食べたくなるようです。