概要
ガンマ-ポアソン分布を使ったベイジアンモデリングを組みたかったので、やってみた。
良い感じのカウントデータを探したが(ポアソン分布使いたかったので)、なかなか見つけられなかったので、
今回は、google trendで「米津玄師」の直近90日間の検索数のcsvを出力した。
https://trends.google.co.jp/trends/?geo=JP
出力データに対して、ベイジアンモデリングを行い、変化点検出を行った。
直近90日の「米津玄師」検索数
結果
pymc3のサンプリング結果。
可視化。ちゃんとトレンド検知できているよう。
コード
import pandas as pd
import numpy as np
import pymc3 as pm
import matplotlib.pyplot as plt
# 前処理
df = pd.read_csv("../desktop/yonezu.csv")
df["日"] = pd.to_datetime(df["日"])
df.index = df["日"]
df.drop(["日"], axis=1, inplace=True)
# モデリング
weeks = df.reset_index().index
with pm.Model() as model:
switchpoint = pm.DiscreteUniform('sp',
lower=weeks.min(),
upper=weeks.max())
lambda1 = pm.Gamma('lambda1', alpha=1, beta=1)
lambda2 = pm.Gamma('lambda2', alpha=1, beta=1)
lambda_ = pm.math.switch(switchpoint>=weeks, lambda1, lambda2)
k = pm.Poisson('k', lambda_, observed = df["米津玄師"].values)
with model:
trace = pm.sample(10000)
burnin = 100
chain = trace[burnin:]
# 出力
pm.traceplot(chain)
df["bayes"] = np.hstack([np.array([chain.lambda1.mean()] * int(chain.sp.mean())), np.array([chain.lambda2.mean()] * (df.index.size - int(chain.sp.mean())))])
df.plot(subplots=False, sharex=True, figsize=(10, 8), title="ベイズによる米津玄師の変化点検知")
感想
変化点検知、実データ分析でかなり有用そうなので、もっと慣れたい。
もっと凝ったことをやりたい。
参考