本当は怖いHPC

HPC屋の外部記憶装置。メモ書き。ちゃんとしたものは別のところに書く予定です

読書メモ:ベイズ推論による機械学習入門(1) 2章

Pythonで実装したり手計算したりしながら読む緑ベイズ。

2章 2.1.5 サンプリングによる期待値の近似計算

初歩的で恥ずかしいが、式 (2.14)

\displaystyle{
\langle f(\mathbf{x}) \rangle_{p(\mathbf{x})} \approx \frac{1}{L} \sum_{l=1}^{L} f(\mathbf{x}^{(l)})
}

に対して、エントロピーの定義 (2.10) を適用するのに混乱してしまった

自分が混乱したのは、

  • 確率変数というのは暗黙のうちに確率変数としての使い方と、確率密度関数(確率質量関数)としての使い方が同一表記で行われる
  • サンプリングの式を使ってエントロピーを近似計算するにあたっては、 \displaystyle{
\mathbf{x}^ {(l)}
} の計算に「確率変数」を使って値を作って、それに \displaystyle{
f
} として確率質量関数を使うということ。
# 2.1.5 サンプリングによる期待値の近似計算
import random
import math
from abc import ABC, abstractmethod

class DiscreteProb(ABC):
  @abstractmethod
  def pmf(self, x: int):
    pass

  @abstractmethod
  def __call__(self):
    pass

class MyDist(DiscreteProb):
  def pmf(self, x: int) -> float:
    assert x in [0, 1]
    if x == 0:
      return 2./3
    else:
      return 1./3

  def __call__(self) -> int:
    if random.random() < 2./3:
      return 0
    else:
      return 1


def sample_expect(p, L, f=None):
  # p: 確率分布
  # f: 関数
  # L: サンプル数
  if f is None:
    f = lambda x: x
  return sum([f(p()) for _ in range(L)]) / L

p = MyDist()

-sample_expect(p, 1000, lambda x: math.log(p.pmf(x)))

# ==> 0.6452940325819064