データの分布
手持ちデータの分布は、統計解析を行う上で重要であるが、暗黙の内に正規分布が採用されることが多いと思う。
以前の記事では、正規性の検定を行ったが、それでは、正規性が仮定できないとき、データがどのような分布に従うのかに興味が出てくる。
fitter
ここではpythonライブラリのfitterを用いて、自動で様々な確率分布から最適なものを選ぶ方法を記載する。
fitterのinstall
installしていない場合は、いつものように
pip install fitter
でインストールしておく。
データは何でもいいので、引き続きドル円の始値、高値などのデータを用いる。
fitterの使い方
超簡単で、以下のように数行のコードで自動で解析してくれる。数十秒程度時間を要する。
from fitter import Fitter
USDJPY_DAY = pd.read_csv("/Users/Documents/USDJPY_DAY.csv")
USDJPY_DAY["date"] = pd.to_datetime(USDJPY_DAY["date"])
value_list = {"opening", "high", "low", "closing"}
USDJPY_DAY["CO"] = USDJPY_DAY["closing"]-USDJPY_DAY["opening"]
f = Fitter(USDJPY_DAY["CO"])
f.fit()
best_fit = f.get_best()
print(best_fit)
f.summary()
最後のf.summaryを実行すると、フィッティングの高い順に5個の分布と、自動的で分布の図も出力してくれる。これを見るとベイズ情報量基準(BIC)の低いものを選択していることがわかる。
print(best_fit)
{'laplace_asymmetric': {'kappa': 0.9797633591359995, 'loc': 6.378459304395541e-07, 'scale': 0.44991385531786626}}
f.summary()
sumsquare_error aic bic kl_div \
laplace_asymmetric 0.056573 1178.561651 -44287.525528 inf
dweibull 0.063914 1194.387839 -43803.057212 inf
laplace 0.064440 1175.191762 -43778.767565 inf
gennorm 0.066269 1165.765988 -43659.323253 inf
dgamma 0.066464 1194.293913 -43647.674222 inf
ks_statistic ks_pvalue
laplace_asymmetric 0.019966 0.083221
dweibull 0.018880 0.116417
laplace 0.022742 0.032396
gennorm 0.023703 0.022705
dgamma 0.015222 0.313171
最も当てはまりの良い分布は、非対称ラプラス分布になる。
非対称ラプラス分布とはなにか
ラプラス分布は\(y\)軸を中心に対称な分布であるが、非対称ラプラス分布は以下のようにパラメータ\(\kappa\)の値に応じて非対称な分布を形成する。
\(\kappa = 1\)のときは青い分布で、対称であるが、\(\kappa = 2\)のときは赤い実践で、右に歪んだ分布になっている。\(\displaystyle \kappa = \frac{1}{2}\)のときは、逆に左に歪んだ分布になっている。ベイズ解析の事前分布で、分布にある程度の信念(事前情報)があるときにはよく用いられる。
翻ってドル円の分布を見ると、中心パラメータ(”loc”)はほとんど\(0\)であるが、\(\kappa\)はわずかに\(1\)よりも小さく、左に歪んだ分布であることがわかる。これは、「終値-始値」が正になる確率がわずかながら高いことを意味している。
上の\(5\)つの候補の中に正規分布が含まれていないことは言及しておくべきだろう。ここでも一応QQプロットを描いておく。コードは以下。
# QQ plot (laplace_asymmetric)
ald = stats.laplace_asymmetric(loc = 6.378459304395541e-07, scale = 0.44991385531786626, kappa = 0.9797633591359995)
data_sorted = np.sort(USDJPY_DAY["CO"])
percentiles = np.linspace(0, 1, len(data_sorted))
q_theoretical = ald.ppf(percentiles)
plt.figure(figsize=(8, 8))
plt.plot(q_theoretical, data_sorted, 'o')
plt.plot([np.min((q_theoretical.min(),data_sorted.min())), np.max((q_theoretical.max(),data_sorted.max()))],
[np.min((q_theoretical.min(),data_sorted.min())), np.max((q_theoretical.max(),data_sorted.max()))], 'r--')
plt.xlabel('Theoretical Quantiles')
plt.ylabel('Ordered Values')
plt.title('QQ Plot')
plt.show()
関連記事
統計モデルにどのような確率分布を採用するか
与えられたデータの分布について確認する
変動値の従う分布について。正規分布と正規性の検定手法
コメント