Pyro 1.4 : MLE と MAP 推定

Pyro 1.4 : MLE と MAP 推定 (翻訳)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 08/07/2020 (1.4.0)

* 本ページは、Pyro の以下のドキュメントを翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

無料セミナー開催中 クラスキャット主催 人工知能 & ビジネス Web セミナー

人工知能とビジネスをテーマにウェビナー (WEB セミナー) を定期的に開催しています。スケジュールは弊社 公式 Web サイト でご確認頂けます。
  • お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
  • Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。

お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。

株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/
Facebook: https://www.facebook.com/ClassCatJP/

 

MLE と MAP 推定

この短いチュートリアルでは Pyro で最尤 (MLE) と最大事後確率 (MAP) 推定をどのように行なうかを見直します。

import torch
from torch.distributions import constraints
import pyro
import pyro.distributions as dist
from pyro.infer import SVI, Trace_ELBO
pyro.enable_validation(True)    # <---- This is always a good idea!

前のチュートリアル でカバーされた単純な「公正なコイン」の例を考えます。

data = torch.zeros(10)
data[0:6] = 1.0

def original_model(data):
    f = pyro.sample("latent_fairness", dist.Beta(10.0, 10.0))
    with pyro.plate("data", data.size(0)):
        pyro.sample("obs", dist.Bernoulli(f), obs=data)

異なる推論テクニック間の比較を円滑にするため、訓練ヘルパーを構築します :

def train(model, guide, lr=0.01):
    pyro.clear_param_store()
    adam = pyro.optim.Adam({"lr": lr})
    svi = SVI(model, guide, adam, loss=Trace_ELBO())

    n_steps = 101
    for step in range(n_steps):
        loss = svi.step(data)
        if step % 50 == 0:
            print('[iter {}]  loss: {:.4f}'.format(step, loss))

 

MLE

モデルは単一の潜在変数 latent_fairness を持ちます。最尤推定を行なうためには潜在変数 latent_fairness を Pyro パラメータに単純に「格下げ (= demote)」します。

def model_mle(data):
    # interval 制約を含める必要があることに注意してください ;
    # original_model() ではこの制約は Beta 分布のサポートで暗黙的に現れます。
    f = pyro.param("latent_fairness", torch.tensor(0.5),
                   constraint=constraints.unit_interval)
    with pyro.plate("data", data.size(0)):
        pyro.sample("obs", dist.Bernoulli(f), obs=data)

どのような潜在変数ももはや持ちませんので、ガイドは empty であり得ます :

def guide_mle(data):
    pass

どのような結果を得るか見ましょう :

train(model_mle, guide_mle)
[iter 0]  loss: 6.9315
[iter 50]  loss: 6.7310
[iter 100]  loss: 6.7301
print("Our MLE estimate of the latent fairness is {:.3f}".format(
      pyro.param("latent_fairness").item()))
Our MLE estimate of the latent fairness is 0.601

こうして MLE で latent_fairness の点推定を得ます。

 

MAP

最大事後確率推定で、潜在変数の点推定をまた得ます。MLE との違いはこれらの推定は事前分布により正則化されることです。

Pyro で MAP を行なうためにガイドのために デルタ分布 を利用します。デルタ分布はその総ての確率質量を単一の値に置くことを思い出してください。デルタ分布は学習可能なパラメータによりパラメータ化されます。

def guide_map(data):
    f_map = pyro.param("f_map", torch.tensor(0.5),
                       constraint=constraints.unit_interval)
    pyro.sample("latent_fairness", dist.Delta(f_map))

この結果が MLE とどのように違うかを見ましょう。

train(original_model, guide_map)
[iter 0]  loss: 5.6719
[iter 50]  loss: 5.6006
[iter 100]  loss: 5.6004
print("Our MAP estimate of the latent fairness is {:.3f}".format(
      pyro.param("f_map").item()))
Our MAP estimate of the latent fairness is 0.536

何が起きているのか理解するためにはモデルの latent_fairness の事前平均が 0.5 であることに注意してください、何故ならばそれは Beta(10.0, 10.0) の平均であるからです。MLE 推定 (これは事前分布を無視します) は raw カウント (6 つの表と 4 つの裏, 例えば) により完全に決定される結果を与えます。対照的に MAP 推定は事前平均に向かって正則化されます、これが何故 MAP 推定が 0.5 と 0.6 の間のどこかにあるかです。

 

以上