からっぽのしょこ

読んだら書く!書いたら読む!同じ事は二度調べ(たく)ない

【R】ガンマ分布から1次元ガウス分布の生成

はじめに

 機械学習や統計学で登場する各種の確率分布について、「計算式の導出・計算のスクラッチ実装・計算過程や結果の可視化」などの「数式・プログラム・図」を用いた解説により、様々な角度から理解を目指すシリーズです。

 この記事では、ガンマ分布の乱数とガウス分布の関係についてR言語を使って確認します。

【前の内容】

www.anarchive-beta.com

【他の内容】

www.anarchive-beta.com

【今回の内容】

ガンマ分布から1次元ガウス分布の生成

 ガンマ分布(Gamma distribution)に従う乱数をパラメータとして用いることで、1次元ガウス分布(Gaussian distribution・正規分布・Normal distribution)を生成します。この記事では、Rを利用して生成します。
 各種の分布についてはそれぞれの「分布の定義式」、Pythonを利用する場合は「Python版」を参照してください。

 利用するパッケージを読み込みます。

# 利用パッケージ
library(tidyverse)

 この記事では、基本的に パッケージ名::関数名() の記法を使うので、パッケージを読み込む必要はありません。ただし、作図コードについては(ごちゃごちゃしないように)パッケージ名を省略するため、ggplot2 を読み込む必要があります。
 また、ネイティブパイプ(baseパイプ)演算子 |> を使います。(基本的には)magrittrパッケージのパイプ演算子 %>% に置き換えても処理できますが、その場合は magrittr を読み込む必要があります。

確率分布の生成

 ガンマ分布から1次元ガウス分布をサンプリングします。

数式の設定

 形状パラメータ  a、尺度パラメータ  b のガンマ分布  \mathrm{Gam}(\lambda \mid a, b) をパラメータの生成分布とします。
 生成分布からサンプル分布のパラメータ  \lambda_n を生成します。

 \displaystyle
\lambda_n
    \sim
      \mathrm{Gamma}(a, b)

 平均パラメータ  \mu、精度パラメータ  \lambda_n (分散パラメータ  \sigma_n^2 = \lambda_n^{-1} = \frac{1}{\lambda_n} )の1次元ガウス分布  \mathcal{N}(x \mid \mu, \lambda_n^{-1}) をサンプリングした確率分布とします。平均パラメータ  \mu は固定とします。標準偏差パラメータは  \sigma_n = \lambda_n^{-\frac{1}{2}} = \frac{1}{\sqrt{\lambda_n}} で表わせます。

生成分布の設定

 ガンマ分布については「【R】ガンマ分布の作図 - からっぽのしょこ」や「【R】ガンマ分布の乱数生成 - からっぽのしょこ」を参照してください。

 生成分布のパラメータ  a, b を設定します。

# ガンマ分布のパラメータを指定
a <- 5
b <- 2
a; b
[1] 5
[1] 2

 形状に関するパラメータ(正の値)  a \gt 0、尺度に関するパラメータ(正の値)  b \gt 0 を指定します。

 サンプルサイズ  N を指定して、生成分布の乱数(サンプル分布のパラメータ)  \lambda_n を生成します。

# サンプルサイズを指定
N <- 5

# ガンマ分布の乱数を生成
lambda_n <- rgamma(n = N, shape = a, rate = b) |> 
  sort() # 昇順に並べ替え

# パラメータを格納
smp_data_df <- tibble::tibble(
  n      = 1:N,     # サンプル番号
  lambda = lambda_n # サンプル値
)
smp_data_df
# A tibble: 5 × 2
      n lambda
  <int>  <dbl>
1     1   1.53
2     2   2.54
3     3   2.61
4     4   3.38
5     5   4.64

 サンプルサイズ(データ数)  N を指定します。
  N 個のサンプル(ガンマ分布の乱数)  \lambda_1, \cdots, \lambda_N を作成して、サンプル分布(ガウス分布)のパラメータ  \lambda_n として用います。

 生成分布の確率変数  \lambda の作図範囲を設定します。

# λ軸の範囲を設定
lambda_min <- 0
#lambda_max <- 10
u <- 5
lambda_max <- (a/b) |> # 基準値を指定
  (\(.) {. * 4})() |> # 倍率を指定
  (\(.) {max(., lambda_n)})() |> # サンプルと比較
  (\(.) {ceiling(. /u)*u})() # u単位で切り上げ

# λ軸の値を作成
lambda_vec <- seq(from = lambda_min, to = lambda_max, length.out = 1001)
lambda_min; lambda_max; head(lambda_vec)
[1] 0
[1] 10
[1] 0.00 0.01 0.02 0.03 0.04 0.05

 この例では、変数の期待値  \mathbb{E}[\lambda] = \frac{a}{b}、またはサンプル  \lambda_n の最大値、の大きい方の値を使って、範囲を設定しています。

 生成分布の確率密度  \mathrm{Gam}(\lambda \mid a, b) を計算します。

# ガンマ分布の確率密度を計算
gen_dens_df <- tidyr::tibble(
  lambda = lambda_vec, # 確率変数
  dens   = dgamma(x = lambda, shape = a, rate = b) # 確率密度
)
gen_dens_df
# A tibble: 1,001 × 2
   lambda         dens
    <dbl>        <dbl>
 1   0    0           
 2   0.01 0.0000000131
 3   0.02 0.000000205 
 4   0.03 0.00000102  
 5   0.04 0.00000315  
 6   0.05 0.00000754  
 7   0.06 0.0000153   
 8   0.07 0.0000278   
 9   0.08 0.0000465   
10   0.09 0.0000731   
# ℹ 991 more rows

 確率密度を計算して、データフレームに格納します。

 生成分布とサンプルのグラフを作成します。

# ラベル用の文字列を作成
gen_param_lbl <- paste0(
  "list(", 
  "N == ", N, ", ", 
  "a == ", a, ", ", 
  "b == ", b, 
  ")"
) |> 
  parse(text = _)
smp_data_lbl <- paste0(
  "lambda[", 1:N, "] == ", round(lambda_n, digits = 2)
) |> 
  parse(text = _)

# ガンマ分布を作図
ggplot() + 
  geom_line(
    data = gen_dens_df, 
    mapping = aes(x = lambda, y = dens), 
    linewidth = 1
  ) + # 生成分布
  geom_point(
    data = smp_data_df, 
    mapping = aes(x = lambda, y = 0, color = factor(n)), 
    alpha = 0.5, size = 5
  ) + # サンプル
  scale_color_hue(labels = smp_data_lbl) + # (凡例の表示用)
  guides(
    color = guide_legend(override.aes = list(alpha = 1, size = 4))
  ) + 
  labs(
    title = "Gamma distribution", 
    subtitle = gen_param_lbl, 
    color = "sample", 
    x = expression(lambda), 
    y = "density"
  )

ガンマ分布とサンプルのグラフ

 生成分布  \mathrm{Gam}(\lambda \mid a, b) を曲線、 N 個のサンプル  \lambda_n を色付けした点として描画します。

サンプル分布の作図

 1次元ガウス分布については「【R】1次元ガウス分布の作図 - からっぽのしょこ」を参照してください。

 サンプル分布の固定するパラメータ  \mu を設定します。

# ガウス分布のパラメータを指定
mu <- 0
mu
[1] 0

 平均  \mu を指定します。

 サンプル分布の確率変数  x の作図範囲を設定します。

# x軸の範囲を設定
#x_min <- -5
#x_max <- 5
u <- 2.5
x_size <- (1/sqrt(lambda_n)) |> # 基準値を指定
  max() |> 
  (\(.) {. * 1})() |> # 倍率を指定
  (\(.) {ceiling(. /u)*u})() # u単位で切り上げ
x_min <- mu - x_size
x_max <- mu + x_size

# x軸の値を作成
x_vec <- seq(from = x_min, to = x_max, length.out = 1001)
x_min; x_max; head(x_vec)
[1] -2.5
[1] 2.5
[1] -2.500 -2.495 -2.490 -2.485 -2.480 -2.475

 この例では、標準偏差のサンプル  \sigma_n の最大値を使って、範囲を設定しています。

 サンプル  \lambda_n ごとにサンプル分布の確率密度  \mathcal{N}(x \mid \mu, \lambda_n^{-1}) を計算します。

# ガウス分布の確率密度を計算
smp_dens_df <- tidyr::expand_grid(
  n = 1:N,   # サンプル番号
  x = x_vec, # 確率変数
) |> # サンプルごとに変数を複製
  dplyr::mutate(
    mu     = mu,             # 平均パラメータ
    lambda = lambda_n[n],    # 精度パラメータ
    sigma  = 1/sqrt(lambda), # 標準偏差パラメータ
    dens   = dnorm(x = x, mean = mu, sd = sigma) # 確率密度
  )
smp_dens_df
# A tibble: 5,005 × 6
       n     x    mu lambda sigma    dens
   <int> <dbl> <dbl>  <dbl> <dbl>   <dbl>
 1     1 -2.5      0   1.53 0.809 0.00418
 2     1 -2.50     0   1.53 0.809 0.00426
 3     1 -2.49     0   1.53 0.809 0.00434
 4     1 -2.48     0   1.53 0.809 0.00443
 5     1 -2.48     0   1.53 0.809 0.00451
 6     1 -2.48     0   1.53 0.809 0.00460
 7     1 -2.47     0   1.53 0.809 0.00468
 8     1 -2.46     0   1.53 0.809 0.00477
 9     1 -2.46     0   1.53 0.809 0.00486
10     1 -2.46     0   1.53 0.809 0.00496
# ℹ 4,995 more rows

 expand_grid() により、 N 個のパラメータ  m_n ごとに確率密度を計算して、データフレームに格納します。

 サンプル分布のグラフを作成します。

# ラベル用の文字列を作成
smp_param_lbl <- paste0(
  "list(", 
  "mu == ", mu, ", ", 
  "lambda[", 1:N, "] == ", round(lambda_n, digits = 2), 
  ")"
) |> 
  parse(text = _)

# ガウス分布を作図
ggplot() + 
  geom_line(
    data = smp_dens_df, 
    mapping = aes(x = x, y = dens, color = factor(n)), 
    linewidth = 1
  ) + # サンプル分布
  scale_color_hue(labels = smp_param_lbl) + # (凡例の表示用)
  guides(
    color = guide_legend(override.aes = list(linewidth = 0.5))
  ) + 
  labs(
    title = "Gaussian distribution", 
    subtitle = gen_param_lbl, 
    color = "parameter", 
    x = expression(x), 
    y = "density"
  )

ガウス分布のグラフ

  N 個のサンプル  \lambda_n を精度パラメータ(  \lambda_n の逆数を分散パラメータ)として用いたガウス分布  \mathcal{N}(x \mid \mu, \lambda_n^{-1}) を色付けした曲線として描画します。

 以上で、基本的な確率分布の生成の処理を確認しました。続いて、生成分布のサンプルとサンプル分布の関係を図で確認します。

スポンサードリンク

サンプルとパラメータの対応関係

 生成分布とサンプル分布の対応関係を図で表します。

精度パラメータの場合

 生成分布とサンプル分布における精度パラメータの対応関係を図にします。

・作図コード(クリックで展開)

## 作図データの作成

# パラメータを格納
smp_data_df <- tibble::tibble(
  n        = 1:N,            # サンプル番号
  lambda   = lambda_n,       # サンプル値
  sigma    = 1/sqrt(lambda), # 標準偏差パラメータ
  dens_max = dnorm(x = mu, mean = mu, sd = sigma) # 最頻値における確率密度
)

# 変換曲線の座標を計算
adapt_line_df <- tibble::tibble(
  lambda   = lambda_vec,     # 生成分布の確率変数
  sigma    = sqrt(1/lambda), # 標準偏差
  dens_max = dnorm(x = mu, mean = mu, sd = sigma) # 最頻値における確率密度
)

# 確率密度軸の範囲を設定
u <- 0.05
smp_dens_max <- adapt_line_df |> 
  dplyr::pull(dens_max) |> 
  max() |> 
  (\(.) {ceiling(. /u)*u})() # u単位で切り上げ

## 生成分布の作図

# 生成分布のラベルを作成
gen_param_lbl <- paste0(
  "list(", 
  "a == ", a, ", ", 
  "b == ", b, 
  ")"
) |> 
  parse(text = _)

# サンプルのラベルを作成
smp_data_lbl <- paste0(
  "lambda[", 1:N, "]"
) |> 
  parse(text = _)

# 生成分布を作図
gen_graph <- ggplot() + 
  geom_vline(
    data    = smp_data_df, 
    mapping = aes(xintercept = lambda, color = factor(n)), 
    linewidth = 1, linetype = "dotted", show.legend = FALSE
  ) + # サンプルの位置
  geom_line(
    data    = gen_dens_df, 
    mapping = aes(x = lambda, y = dens, linetype = "generator"), 
    linewidth = 1
  ) + # 生成分布
  geom_point(
    data    = smp_data_df, 
    mapping = aes(x = lambda, y = 0, color = factor(n)), 
    size = 5
  ) + # サンプル
  scale_x_continuous(
    sec.axis = sec_axis(
      trans  = ~ ., 
      breaks = lambda_n, 
      labels = smp_data_lbl, 
    ) # サンプルのラベル
  ) + 
  scale_linetype_manual(
    breaks = "generator", 
    values = "solid", 
    labels = gen_param_lbl, 
    name   = "generator"
  ) + # (凡例の表示用)
  guides(
    color    = "none", 
    linetype = guide_legend(override.aes = list(linewidth = 0.5))
  ) + 
  coord_cartesian(
    xlim = c(lambda_min, lambda_max)
  ) + # (軸の対応用)
  labs(
    title = "Gamma distribution", 
    subtitle = parse(text = paste0("N == ", N)), 
    x = expression(lambda), 
    y = expression(p(lambda ~"|"~ a, b))
  )

## サンプル分布の作図

# サンプルのラベルを作成
smp_data_lbl <- paste0(
  "p(x == mu ~'|'~ mu, lambda[", 1:N, "]^{-1})"
) |> 
  parse(text = _)
smp_param_lbl <- paste0(
  "list(", 
  "mu == ", mu, ", ", 
  "lambda[", 1:N, "] == ", round(lambda_n, digits = 2), 
  ")"
) |> 
  parse(text = _)

# サンプル分布を作図
smp_graph <- ggplot() + 
  geom_hline(
    data    = smp_data_df, 
    mapping = aes(yintercept = dens_max, color = factor(n)), 
    linewidth = 1, linetype = "dotted", show.legend = FALSE
  ) + # サンプルとの対応
  geom_line(
    data    = smp_dens_df, 
    mapping = aes(x = x, y = dens, color = factor(n)), 
    linewidth = 1
  ) + # サンプル分布
  scale_y_continuous(
    sec.axis = sec_axis(
      trans  = ~ ., 
      breaks = smp_data_df[["dens_max"]], 
      labels = smp_data_lbl, 
    ) # サンプルのラベル
  ) + 
  scale_color_hue(labels = smp_param_lbl) + # (凡例の表示用)
  guides(
    color = guide_legend(override.aes = list(linewidth = 0.5))
  ) + 
  coord_cartesian(
    xlim = c(x_min, x_max), 
    ylim = c(0, smp_dens_max)
  ) + # (軸の対応用)
  labs(
    title = "Gaussian distribution", 
    color = "sample", 
    x = expression(x), 
    y = expression(p(x ~"|"~ mu, lambda[n]^{-1}))
  )

## 軸変換の作図

# 軸変換を作図
adapt_graph <- ggplot() + 
  geom_line(
    data    = adapt_line_df, 
    mapping = aes(x = lambda, y = dens_max), 
    linewidth = 1
  ) + # 変換曲線
  geom_segment(
    data    = smp_data_df, 
    mapping = aes(x = lambda, y = Inf, xend = lambda, yend = dens_max, color = factor(n)), 
    linewidth = 1, linetype = "dotted", show.legend = FALSE
  ) + # 生成分布との対応
  geom_segment(
    data    = smp_data_df, 
    mapping = aes(x = lambda, y = dens_max, xend = Inf, yend = dens_max, color = factor(n)), 
    linewidth = 1, linetype = "dotted", show.legend = FALSE
  ) + # サンプル分布との対応
  geom_point(
    data    = smp_data_df, 
    mapping = aes(x = lambda, y = dens_max, color = factor(n)), 
    size = 5
  ) + # 変換点
  guides(color = "none") + 
  coord_cartesian(
    xlim = c(lambda_min, lambda_max), 
    ylim = c(0, smp_dens_max)
  ) + # (軸の対応用)
  labs(
    x = expression(lambda), 
    y = expression(p(x == mu ~"|"~ mu, lambda^{-1}))
  )

## 対応関係の作図
  
# 凡例を取得
gen_legend <- cowplot::get_legend(gen_graph)
smp_legend <- cowplot::get_legend(smp_graph)

# 凡例の表示用の図を作成
legend_graph <- cowplot::plot_grid(
  gen_legend, smp_legend, 
  NULL, # (凡例の位置の調整用)
  nrow = 1, ncol = 3
) + 
  theme(
    plot.background = element_rect(fill = "white", color = NA) # (透過背景の対策用)
  )

# 凡例を除去
tmp_gen_graph <- gen_graph + 
  theme(legend.position = "none")
tmp_smp_graph <- smp_graph + 
  theme(legend.position = "none")

# グラフを並べて描画
comb_graph <- cowplot::plot_grid(
  tmp_gen_graph, legend_graph, 
  adapt_graph,   tmp_smp_graph, 
  nrow = 2, ncol = 2, 
  align = "hv" # (グラフ位置のズレ対策用)
)
comb_graph

ガンマ分布のサンプルとガウス分布の最大値の関係のグラフ

 左下の図は、ガンマ分布の確率変数  \lambda に対して、ガウス分布の確率密度の最大値(最頻値における確率密度)をプロットしたものです。 \lambda の関数の曲線(グラフ)と言えます。
 精度  \lambda が大きいほど、分散  \sigma^2 = \frac{1}{\lambda} が小さくなるので、ガウス分布の確率密度の最大値が大きく(山が高く)なることを示しています。

 パラメータの生成分布(ガンマ分布)のサンプル  \lambda_n と、サンプル分布(ガウス分布)の最頻値  \mathrm{mode}[x] = \mu における確率密度  \mathcal{N}(x = \mu \mid \mu, \lambda_{n}^{-1}) が、対応するのを確認できます。

標準偏差パラメータの場合

 生成分布とサンプル分布における標準偏差パラメータの対応関係を図にします。

・作図コード(クリックで展開)

## 作図データの作成

# パラメータを格納
smp_data_df <- tibble::tibble(
  n      = 1:N,            # サンプル番号
  lambda = lambda_n,       # サンプル値
  sigma  = 1/sqrt(lambda), # 標準偏差パラメータ
  x      = mu + sigma      # 期待値から標準偏差1つ分離れたx座標
)

# 変換曲線の座標を計算
adapt_line_df <- tibble::tibble(
  lambda = lambda_vec,    # 生成分布の確率変数
  sigma  = sqrt(1/lambda) # 標準偏差
)

# σ軸の範囲を設定
sigma_min <- x_min - mu
sigma_max <- x_max - mu

## 生成分布の作図

# 生成分布のラベルを作成
gen_param_lbl <- paste0(
  "list(", 
  "a == ", a, ", ", 
  "b == ", b, 
  ")"
) |> 
  parse(text = _)

# サンプルのラベルを作成
smp_data_lbl <- paste0(
  "lambda[", 1:N, "]"
) |> 
  parse(text = _)

# 生成分布を作図
gen_graph <- ggplot() + 
  geom_vline(
    data    = smp_data_df, 
    mapping = aes(xintercept = lambda, color = factor(n)), 
    linewidth = 1, linetype = "dotted", show.legend = FALSE
  ) + # サンプルの位置
  geom_line(
    data    = gen_dens_df, 
    mapping = aes(x = lambda, y = dens, linetype = "generator"), 
    linewidth = 1
  ) + # 生成分布
  geom_point(
    data    = smp_data_df, 
    mapping = aes(x = lambda, y = 0, color = factor(n)), 
    size = 5
  ) + # サンプル
  scale_x_continuous(
    sec.axis = sec_axis(
      trans  = ~ ., 
      breaks = lambda_n, 
      labels = smp_data_lbl, 
    ) # サンプルのラベル
  ) + 
  scale_linetype_manual(
    breaks = "generator", 
    values = "solid", 
    labels = gen_param_lbl, 
    name   = "generator"
  ) + # (凡例の表示用)
  guides(
    color    = "none", 
    linetype = guide_legend(override.aes = list(linewidth = 0.5))
  ) + 
  coord_cartesian(
    xlim = c(lambda_min, lambda_max)
  ) + # (軸の対応用)
  labs(
    title = "Gamma distribution", 
    subtitle = parse(text = paste0("N == ", N)), 
    x = expression(lambda), 
    y = expression(p(lambda ~"|"~ a, b))
  )

## サンプル分布の作図

# サンプルのラベルを作成
# smp_data_lbl <- paste0(
#   "sqrt(lambda[", 1:N, "]^{-1})"
# ) |> 
#   parse(text = _)
smp_data_lbl <- paste0(
  "lambda[", 1:N, "]^{-frac(1, 2)}"
) |>
  parse(text = _)
smp_param_lbl <- paste0(
  "list(", 
  "mu == ", mu, ", ", 
  "lambda[", 1:N, "] == ", round(lambda_n, digits = 2), 
  ")"
) |> 
  parse(text = _)

# サンプル分布を作図
smp_graph <- ggplot() + 
  geom_vline(
    data    = smp_data_df,
    mapping = aes(xintercept = x, color = factor(n)),
    linewidth = 1, linetype = "dotted", show.legend = FALSE
  ) + # サンプルとの対応
  geom_line(
    data    = smp_dens_df, 
    mapping = aes(x = x, y = dens, color = factor(n)), 
    linewidth = 1
  ) + # サンプル分布
  scale_x_continuous(
    sec.axis = sec_axis(
      trans  = ~ ., 
      breaks = c(mu, mu + 1/sqrt(lambda_n)), 
      labels = c(expression(mu), smp_data_lbl), 
    ) # サンプルのラベル
  ) + 
  scale_color_hue(labels = smp_param_lbl) + # (凡例の表示用)
  guides(
    color = guide_legend(override.aes = list(linewidth = 0.5))
  ) + 
  coord_cartesian(
    xlim = c(x_min, x_max)
  ) + # (軸の対応用)
  labs(
    title = "Gaussian distribution", 
    color = "sample", 
    x = expression(x), 
    y = expression(p(x ~"|"~ mu, lambda[n]^{-1}))
  )

## 恒等関数の作図

# 恒等関数を作図
identity_graph <- ggplot() + 
  geom_line(
    data    = adapt_line_df, 
    mapping = aes(x = lambda, y = lambda), 
    linewidth = 1
  ) + # 恒等関数
  geom_segment(
    data    = smp_data_df, 
    mapping = aes(x = lambda, y = Inf, xend = lambda, yend = lambda, color = factor(n)), 
    linewidth = 1, linetype = "dotted", show.legend = FALSE
  ) + # 生成分布との対応
  geom_segment(
    data    = smp_data_df, 
    mapping = aes(x = lambda, y = lambda, xend = Inf, yend = lambda, color = factor(n)), 
    linewidth = 1, linetype = "dotted", show.legend = FALSE
  ) + # 変換曲線との対応
  geom_point(
    data    = smp_data_df, 
    mapping = aes(x = lambda, y = lambda, color = factor(n)), 
    size = 5
  ) + # 変換点
  guides(color = "none") + 
  coord_cartesian(
    xlim = c(lambda_min, lambda_max), 
    ylim = c(lambda_min, lambda_max)
  ) + # (軸の対応用)
  labs(
    x = expression(lambda), 
    y = expression(lambda)
  )

## 軸変換の作図

# 軸変換を作図
adapt_graph <- ggplot() + 
  geom_line(
    data    = adapt_line_df, 
    mapping = aes(x = sigma, y = lambda), 
    linewidth = 1
  ) + # 変換曲線
  geom_segment(
    data    = smp_data_df, 
    mapping = aes(x = -Inf, y = lambda, xend = sigma, yend = lambda, color = factor(n)), 
    linewidth = 1, linetype = "dotted", show.legend = FALSE
  ) + # 恒等関数との対応
  geom_segment(
    data    = smp_data_df, 
    mapping = aes(x = sigma, y = lambda, xend = sigma, yend = Inf, color = factor(n)), 
    linewidth = 1, linetype = "dotted", show.legend = FALSE
  ) + # サンプル分布との対応
  geom_point(
    data    = smp_data_df, 
    mapping = aes(x = sigma, y = lambda, color = factor(n)), 
    size = 5
  ) + # 変換点
  guides(color = "none") + 
  coord_cartesian(
    xlim = c(sigma_min, sigma_max), 
    ylim = c(lambda_min, lambda_max)
  ) + # (軸の対応用)
  labs(
    x = expression(sigma == frac(1, sqrt(lambda))), 
    y = expression(lambda == frac(1, sigma^2))
  )

## 対応関係の作図

# 凡例を取得
gen_legend <- cowplot::get_legend(gen_graph)
smp_legend <- cowplot::get_legend(smp_graph)

# 凡例の表示用の図を作成
legend_graph <- cowplot::plot_grid(
  gen_legend, smp_legend, 
  NULL, NULL, # (凡例の位置の調整用)
  nrow = 4, ncol = 1
  ) + 
  theme(
    plot.background = element_rect(fill = "white", color = NA) # (透過背景の対策用)
  )

# 凡例を除去
tmp_gen_graph <- gen_graph + 
  theme(legend.position = "none")
tmp_smp_graph <- smp_graph + 
  theme(legend.position = "none")

# グラフを並べて描画
tmp_comb_graph <- cowplot::plot_grid(
  tmp_gen_graph,  tmp_smp_graph, 
  identity_graph, adapt_graph, 
  nrow = 2, ncol = 2, 
  align = "hv" # (グラフ位置のズレ対策用)
)
comb_graph <- cowplot::plot_grid(
  tmp_comb_graph, legend_graph, 
  nrow = 1, ncol = 2, 
  rel_widths = c(1, 0.2) # (凡例の位置の調整用)
)
comb_graph

ガンマ分布のサンプルとガウス分布の標準偏差の関係のグラフ

 左下の図は、 \lambda の恒等関数  \lambda = f(\lambda) のグラフです。横軸と縦軸を入れ替えています。
 右下の図は、ガンマ分布の確率変数  \lambda に対して、ガウス分布の標準偏差パラメータをプロットしたものです。 \lambda \sigma を変換する曲線(対応関係のグラフ)と言えます。
 精度  \lambda が大きいほど、標準偏差  \sigma = \frac{1}{\sqrt{\lambda}} が小さくなることを示しています。

 パラメータの生成分布(ガンマ分布)のサンプル  \lambda_n と、サンプル分布(ガウス分布)の平均  \mu から標準偏差  \sigma_n = \frac{1}{\sqrt{\lambda_n}} の1つ分の位置  \mu + \sigma_n が、対応するのを確認できます。

 (右上の図に関して、x軸の第2軸に表示しているサンプルのラベルは、 x = \mu + \lambda^{-\frac{1}{2}} のように表記すべきですが、あまりにごちゃごちゃして識別できなくなるのでやむを得ず  \mu を省略しています。)

スポンサードリンク

ハイパーパラメータの影響

 次は、生成分布のパラメータ(ハイパーパラメータ・超パラメータ)の値を少しずつ変化させて、生成分布とサンプル分布のグラフの変化をアニメーションで確認します。
 作図コードについては「Probability-Distribution/code/gamma/generate_gaussian.R at main · anemptyarchive/Probability-Distribution · GitHub」を参照してください。

ハイパーパラメータとサンプル分布の関係

 生成分布(ガンマ分布)  \mathrm{Gam}(\lambda \mid a, b) における累積確率が等間隔になるように  N 個のパラメータ(サンプル)  \lambda_n を作成し、それぞれを精度パラメータとする  N 個のサンプル分布(ポアソン分布)  \mathcal{N}(x \mid \mu, \lambda_n^{-1}) を描画して、ハイパーパラメータ  a, b を変化させます。
 また、生成分布の期待値と、期待値をパラメータとするサンプル分布を赤色の破線で示します。

 形状パラメータ  a を変化させたときの生成分布とサンプル分布の変化をアニメーションにします。

  a が大きくなるほど、生成分布のサンプル・サンプル分布の精度  \lambda_n が大きくなりやすく(標準偏差  \sigma が小さくなりやすく)なり、サンプル分布の平均  \mu 付近の確率密度が大きく(散らばり具合が小さく)なるのが分かります。

 尺度パラメータ  b による変化をアニメーションにします。

  b が大きくなるほど、生成分布のサンプル・サンプル分布の精度  \lambda_n が小さくなりやすく(標準偏差  \sigma が大きくなりやすく)なり、サンプル分布の平均  \mu 付近の確率密度が小さく(散らばり具合が大きく)なるのが分かります。

 以上で、ハイパーパラメータの影響を確認しました。

 この記事では、ガンマ分布からポアソン分布を生成しました、次の記事では、1次元ガウス分布を生成します。

参考文献

おわりに

  • 2025.11.03:加筆修正の際に「ガンマ分布からポアソン分布の生成」から記事を独立しました。

 分布間の関係の説明的にはポアソン分布と一緒にした方が分かりやすい気もするのですが、図を増やしたことでコードの解説の流れが悪くなったのと、ポアソン分布のベイズ推論に繋げる意図で書いた記事なので、それと無関係なガウス分布の件は分けたかったという事情がありました。

2025年11月3日は、AMEFURASSHIの結成7周年の日です!!!!

 リリイベなどでのミニライブは何度か観る機会があったのですが、フルのライブはまだ観られてないので、いつか絶対に行きたいです。

【次の内容】

www.anarchive-beta.com