ガンマ分布と`torch.distributions.gamma.Gamma.log_prob()` 関数:機械学習タスクでの活用


この解説では、以下の内容を詳しく説明します。

  • 関連する関数と応用例
  • 確率密度関数の可視化
  • 関数パラメータと使用例
  • log_prob() 関数の詳細な説明
  • ガンマ分布とは?

ガンマ分布とは?

ガンマ分布は、確率論における連続確率分布の一つで、非負の値を取るランダム変数を表します。形状パラメータ α と尺度パラメータ β によって定義され、確率密度関数は以下の式で表されます。

f(x; α, β) = (x^(α - 1) * exp(-x / β)) / (β^(α) * Γ(α))

ここで、Γ(α) はガンマ関数と呼ばれる特殊関数です。

ガンマ分布は、以下の特性を持つことが知られています。

  • 形状: 形状パラメータ α を変化させると、分布の形状が変化します。
  • スケーリング: 尺度パラメータ β を変化させると、分布が左右に伸縮します。
  • 柔軟性: 形状パラメータ α と尺度パラメータ β を調整することで、さまざまな形状の分布を生成することができます。
  • 非負性: ガンマ分布は、確率変数が常に非負であることを保証します。

torch.distributions モジュールには、ガンマ分布を扱うための Gamma クラスが用意されています。このクラスは、以下のような機能を提供します。

  • 事後分布の計算
  • パラメータ推定
  • ランダムサンプリング
  • ガンマ分布の確率密度関数の計算

Gamma クラスは、以下の引数を受け取ります。

  • beta: 尺度パラメータ
  • alpha: 形状パラメータ

log_prob() 関数の詳細な説明

log_prob() 関数は、ガンマ分布に従うランダム変数の確率密度関数の対数値を計算します。この関数は、以下の引数を受け取ります。

  • allow_nan: valueNaN が含まれていてもエラーを発生させないかどうかを指定します。デフォルトは False です。
  • value: 確率密度関数を計算したい値

log_prob() 関数は、以下の式に基づいて確率密度関数の対数値を計算します。

log_prob(value; alpha, beta) = (value^(alpha - 1) * torch.exp(-value / beta)) / (beta^(alpha) * torch.lgamma(alpha))

ここで、torch.lgamma() はガンマ関数の対数値を計算する関数です。

関数パラメータと使用例

例 1
特定の値における確率密度関数の対数値を計算する

import torch
import torch.distributions as distributions

alpha = torch.tensor(3.0)
beta = torch.tensor(2.0)
value = torch.tensor(1.5)

distribution = distributions.Gamma(alpha, beta)
log_prob = distribution.log_prob(value)

print(log_prob)

例 2
確率密度関数を可視化する

import torch
import numpy as np
import matplotlib.pyplot as plt

alpha = 3.0
beta = 2.0

x = np.linspace(0, 10, 100)
distribution = distributions.Gamma(alpha, beta)

pdf = distribution.pdf(torch.tensor(x))
plt.plot(x, pdf.numpy())
plt.xlabel('x')
plt.ylabel('PDF')
plt.show()

torch.distributions.gamma.Gamma クラスには、以下の関連関数も用意されています。

  • icdf(): 逆累積分布関数を計算します
  • cdf(): 累積分布関数を計算します。


import torch
import numpy as np
import matplotlib.pyplot as plt

alpha = 3.0
beta = 2.0

x = np.linspace(0, 10, 100)
distribution = distributions.Gamma(alpha, beta)

# 確率密度関数 (PDF) を計算
pdf = distribution.pdf(torch.tensor(x))

# 累積分布関数 (CDF) を計算
cdf = distribution.cdf(torch.tensor(x))

# 逆累積分布関数 (ICDF) を計算
icdf = distribution.icdf(torch.tensor(cdf))

# ランダムサンプリング
samples = distribution.rsample(size=100)

# PDF を可視化
plt.plot(x, pdf.numpy(), label='PDF')

# CDF を可視化
plt.plot(x, cdf.numpy(), label='CDF')

# ICDF を可視化
plt.plot(cdf.numpy(), x, label='ICDF')

# ランダムサンプルを可視化
plt.scatter(samples.numpy(), np.zeros_like(samples), alpha=0.5, label='Samples')

# 凡例を追加
plt.legend()

# 軸ラベルを設定
plt.xlabel('x')

# グラフタイトルを設定
plt.title('Gamma Distribution (α={}, β={})'.format(alpha, beta))

# グラフを表示
plt.show()
  1. ガンマ分布のパラメータ αβ を設定します。
  2. numpy ライブラリを使用して、可視化に使用する x 配列を作成します。
  3. torch.distributions.gamma.Gamma クラスを使用して、ガンマ分布を作成します。
  4. pdf 変数に確率密度関数 (PDF) を計算します。
  5. cdf 変数に累積分布関数 (CDF) を計算します。
  6. icdf 変数に逆累積分布関数 (ICDF) を計算します。
  7. distribution.rsample() 関数を使用して、ガンマ分布から 100 個のランダムサンプルを生成します。
  8. matplotlib ライブラリを使用して、PDF、CDF、ICDF、およびランダムサンプルを可視化します。
  9. グラフに軸ラベルとタイトルを追加します。
  10. グラフを表示します。


ベイジアン推論

ベイジアン推論では、事後分布を計算するために確率密度関数が使用されます。torch.distributions.gamma.Gamma.log_prob() 関数は、ガンマ分布に従うパラメータの事後分布を計算するために使用できます。


あるコインの裏表をランダムにサンプリングする確率を推定したいとします。コインの裏表の確率を θ と仮定し、ガンマ分布で事前分布を表現します。

import torch
import torch.distributions as distributions

alpha = torch.tensor(1.0)
beta = torch.tensor(1.0)

# データ
data = torch.tensor([1, 0, 1, 0])

# 事前分布
prior = distributions.Gamma(alpha, beta)

# 事後分布を計算
posterior = prior.update(data)

# 事後分布の確率密度関数を可視化
x = torch.linspace(0, 1, 100)
pdf = posterior.log_prob(x)
plt.plot(x, pdf.numpy())
plt.xlabel('θ')
plt.ylabel('Log Probability Density')
plt.show()

この例では、事前分布としてガンマ分布を使用し、コインの裏表の確率を推定しています。データに基づいて事後分布を計算し、コインの裏表の確率が約 0.5 であることがわかります。

混合分布

混合分布は、複数の確率分布を組み合わせて新しい分布を生成する手法です。torch.distributions.gamma.Gamma.log_prob() 関数は、ガンマ分布を混合分布の一部として使用するために使用できます。


2 つのガンマ分布を混合して、混合分布を作成します。

import torch
import torch.distributions as distributions

alpha1 = torch.tensor(2.0)
beta1 = torch.tensor(1.0)

alpha2 = torch.tensor(3.0)
beta2 = torch.tensor(2.0)

# ガンマ分布
distribution1 = distributions.Gamma(alpha1, beta1)
distribution2 = distributions.Gamma(alpha2, beta2)

# 混合分布
mixed_distribution = distributions.Mixture(
    distributions.Categorical([0.5, 0.5]), [distribution1, distribution2]
)

# 混合分布の確率密度関数を可視化
x = torch.linspace(0, 10, 100)
pdf = mixed_distribution.log_prob(x)
plt.plot(x, pdf.numpy())
plt.xlabel('x')
plt.ylabel('Log Probability Density')
plt.show()

この例では、2 つのガンマ分布を混合して、混合分布を作成しています。混合分布の確率密度関数は、2 つのガンマ分布の確率密度関数の組み合わせを示しています。

パラメータ推定

パラメータ推定では、データに基づいて確率分布のパラメータを推定します。torch.distributions.gamma.Gamma.log_prob() 関数は、最大尤度推定法を使用してガンマ分布のパラメータを推定するために使用できます。


あるデータセットから、ガンマ分布に従う値のサンプルを生成します。

import torch
import torch.distributions as distributions
import numpy as np

# データ
data = torch.tensor(np.random.gamma(2.0, 1.0, size=100))

# パラメータ推定
optimizer = torch.optim.Adam([
    torch.nn.Parameter(torch.tensor(1.0)),
    torch.nn.Parameter(torch.tensor(1.0))
])

for _ in range(1000):
    alpha = optimizer.param_groups[0]['params'][0]
    beta = optimizer.param_groups[1]['params'][0]

    distribution = distributions.Gamma(alpha, beta)
    log_prob = distribution.log_prob(data).sum()

    optimizer.zero_grad()
    log_prob.backward()
    optimizer.step()

print('推定されたα:', alpha.item())
print('推定されたβ:', beta.item