ホーム » モーメント母関数

モーメント母関数」カテゴリーアーカイブ

投稿一覧

2014 Q2(2)

ガンマ分布の平均と分散をモーメント母関数から求めました。

 

コード

形状パラメータm、スケールパラメータ1のガンマ分布について、期待値と分散が共にmになる様子をシミュレーションで確認し、確率密度の形を視覚的に確かめます。

# 2014 Q2(2)  2025.1.1

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gamma

# パラメータ m の値を変化させる
m_values = [1, 2, 5, 10]  # ガンマ分布の形状パラメータ
colors = ["blue", "orange", "green", "red"]  # 各 m に対応する色
x = np.linspace(0, 20, 1000)  # x の範囲
num_samples = 10000  # シミュレーションで生成する乱数の数

# グラフの描画
plt.figure(figsize=(12, 8))

for m, color in zip(m_values, colors):
    # ガンマ分布の確率密度関数 (PDF)
    pdf = gamma.pdf(x, a=m, scale=1)  # a=m, scale=1 に対応
    
    # 乱数生成
    random_samples = gamma.rvs(a=m, scale=1, size=num_samples)
    
    # ヒストグラムを描画
    plt.hist(random_samples, bins=50, density=True, alpha=0.5, color=color, label=f"ヒストグラム (m={m})")
    
    # PDF を描画
    plt.plot(x, pdf, color=color, linewidth=2, label=f"PDF (m={m})")
    
    # 期待値の線
    mean = m  # ガンマ分布の期待値
    plt.axvline(mean, color=color, linestyle="--", alpha=0.7, label=f"期待値 (m={m})")

# グラフの装飾
plt.title("ガンマ分布のPDFとシミュレーションによるヒストグラム", fontsize=16)
plt.xlabel("$x$", fontsize=14)
plt.ylabel("確率密度", fontsize=14)
plt.legend(fontsize=12)
plt.grid()
plt.show()

形状パラメータmと期待値が一致し、また、mが大きくなるにつれて分布が広がっている様子が確認できました。分散がmになることを直接確認していませんが、分布の広がりがmと連動していることが示唆されています。

2014 Q2(1)

ガンマ分布のモーメント母関数を求めました。

 

コード

求めたモーメント母関数を用いてガンマ分布の期待値と分散の理論値を求め、それをシミュレーション結果と一致するか確認します。

# 2014 Q2(1)  2024.12.31

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gamma
import sympy as sp
from IPython.display import display

# モーメント母関数を定義 (シンボリック)
t, m = sp.symbols('t m', real=True, positive=True)
M_X_t = (1 - t)**(-m)  # モーメント母関数

# 期待値 (モーメント母関数の一次微分を t=0 に代入)
M_X_prime = sp.diff(M_X_t, t)
theoretical_mean_expr = M_X_prime.subs(t, 0)

# 分散 (モーメント母関数の二次微分を t=0 に代入し、期待値の2乗を引く)
M_X_double_prime = sp.diff(M_X_prime, t)
theoretical_variance_expr = M_X_double_prime.subs(t, 0) - theoretical_mean_expr**2

# 理論値をシンボリックに表示
print("理論値の計算式:")
print("期待値 (モーメント母関数の一次微分を t=0 に代入):")
display(theoretical_mean_expr)
print("\n分散 (モーメント母関数の二次微分を t=0 に代入し、期待値の2乗を引く):")
display(theoretical_variance_expr)

# 実際のシミュレーション
m_values = [1, 2, 5, 10]  # ガンマ分布の形状パラメータ
num_samples = 10000  # 乱数のサンプル数

# 理論値とシミュレーション結果を格納するリスト
theoretical_means = []
theoretical_variances = []
simulated_means = []
simulated_variances = []

for m_val in m_values:
    # 理論値の計算
    mean_value = float(theoretical_mean_expr.subs(m, m_val))
    variance_value = float(theoretical_variance_expr.subs(m, m_val))
    theoretical_means.append(mean_value)
    theoretical_variances.append(variance_value)
    
    # シミュレーション (乱数生成)
    random_samples = gamma.rvs(a=m_val, scale=1, size=num_samples)  # scale=1 に対応
    simulated_mean = np.mean(random_samples)
    simulated_variance = np.var(random_samples)
    simulated_means.append(simulated_mean)
    simulated_variances.append(simulated_variance)

# グラフの描画 (期待値)
plt.figure(figsize=(10, 6))
plt.plot(m_values, theoretical_means, 'o-', label="理論値 (期待値)", color="blue", linewidth=2)
plt.plot(m_values, simulated_means, 's--', label="シミュレーション (期待値)", color="orange", linewidth=2)
plt.title("期待値の比較 (理論値 vs シミュレーション)", fontsize=16)
plt.xlabel("形状パラメータ $m$", fontsize=14)
plt.ylabel("期待値", fontsize=14)
plt.legend(fontsize=12)
plt.grid()
plt.show()

# グラフの描画 (分散)
plt.figure(figsize=(10, 6))
plt.plot(m_values, theoretical_variances, 'o-', label="理論値 (分散)", color="blue", linewidth=2)
plt.plot(m_values, simulated_variances, 's--', label="シミュレーション (分散)", color="orange", linewidth=2)
plt.title("分散の比較 (理論値 vs シミュレーション)", fontsize=16)
plt.xlabel("形状パラメータ $m$", fontsize=14)
plt.ylabel("分散", fontsize=14)
plt.legend(fontsize=12)
plt.grid()
plt.show()

モーメント母関数を用いてガンマ分布の期待値と分散の理論値は、シミュレーション結果がよく一致しました。

2017 Q3(3)

ポアソン分布に従う独立した2変数の和の分布を3つの方法で求めました。

 

コード

ポアソン分布に従う独立した2変数X1,X2と、Y=X1+X2の分布をシミュレーションしました。

# 2017 Q3(3)  2024.11.4

import numpy as np
import matplotlib.pyplot as plt

# パラメータ設定
lambda_1 = 3  # X1のポアソン分布のパラメータ
lambda_2 = 4  # X2のポアソン分布のパラメータ
sample_size = 10000  # サンプルサイズ

# X1 と X2 のサンプルを生成
X1_samples = np.random.poisson(lambda_1, sample_size)
X2_samples = np.random.poisson(lambda_2, sample_size)
Y_samples = X1_samples + X2_samples  # Y = X1 + X2 のサンプル

# ヒストグラムをプロット (塗りあり)
plt.figure(figsize=(10, 4.2))  # 高さを70%に縮小
plt.hist(X1_samples, bins=range(0, 20), density=True, alpha=0.5, label=f"X1 ~ ポアソン(λ1 = {lambda_1})", color="blue")
plt.hist(X2_samples, bins=range(0, 20), density=True, alpha=0.5, label=f"X2 ~ ポアソン(λ2 = {lambda_2})", color="green")
plt.hist(Y_samples, bins=range(0, 20), density=True, alpha=0.5, label=f"Y = X1 + X2 ~ ポアソン(λ1 + λ2 = {lambda_1 + lambda_2})", color="red", histtype='stepfilled')

# ヒストグラムのカスタマイズ
plt.xlabel("値")
plt.ylabel("確率密度")
plt.title("ポアソン分布の重ね合わせ (X1, X2, および Y = X1 + X2)")
plt.legend()
plt.grid(True)
plt.show()

# CDFの計算用にPMFを求める
x_values = range(0, 20)
pmf_X1 = [np.exp(-lambda_1) * lambda_1**x / np.math.factorial(x) for x in x_values]
pmf_X2 = [np.exp(-lambda_2) * lambda_2**x / np.math.factorial(x) for x in x_values]
pmf_Y = [np.exp(-(lambda_1 + lambda_2)) * (lambda_1 + lambda_2)**x / np.math.factorial(x) for x in x_values]

# CDFを計算
X1_cdf = np.cumsum(pmf_X1)
X2_cdf = np.cumsum(pmf_X2)
Y_cdf = np.cumsum(pmf_Y)

# CDFのプロット
plt.figure(figsize=(10, 4.2))
plt.step(x_values, X1_cdf, where='mid', label=f"X1 ~ ポアソン(λ1 = {lambda_1}) CDF", color="blue")
plt.step(x_values, X2_cdf, where='mid', label=f"X2 ~ ポアソン(λ2 = {lambda_2}) CDF", color="green")
plt.step(x_values, Y_cdf, where='mid', label=f"Y = X1 + X2 ~ ポアソン(λ1 + λ2 = {lambda_1 + lambda_2}) CDF", linestyle="--", color="red")

# CDFプロットのカスタマイズ
plt.xlabel("値")
plt.ylabel("累積分布関数 (CDF)")
plt.title("ポアソン分布の累積分布関数 (X1, X2, および Y = X1 + X2)")
plt.legend()
plt.grid(True)
plt.show()

X1~Po(λ1),X1~Po(λ2)のときY=X1+X2~Po(λ1+λ2)になることをグラフの形状からも確認できました。

2017 Q3(2)

ポアソン分布のモーメント母関数を求めて、それを使って期待値と分散を求めました。

 

コード

ポアソン分布のパラメータλを変化させシミュレーションし期待と分散が共にλになるか確認しました。

# 2017 Q3(2)  2024.11.3

import numpy as np
import matplotlib.pyplot as plt

# λの範囲を定義
lambda_values = np.arange(1, 21)
sample_size = 10000  # 各λに対するサンプル数

# サンプル平均と分散を格納するリスト
sample_means = []
sample_variances = []

# 各λに対するシミュレーションを実行
for lambda_val in lambda_values:
    # ポアソン分布のサンプルを生成
    samples = np.random.poisson(lambda_val, sample_size)
    
    # サンプルの平均と分散を計算
    sample_means.append(np.mean(samples))
    sample_variances.append(np.var(samples))

# 結果をプロット
plt.figure(figsize=(12, 6))

# サンプル平均と理論値をプロット
plt.plot(lambda_values, sample_means, label="サンプル平均 (期待値)", marker='o')
plt.plot(lambda_values, lambda_values, label="理論値 (期待値)", linestyle='--')

# サンプル分散と理論値をプロット
plt.plot(lambda_values, sample_variances, label="サンプル分散", marker='x')
plt.plot(lambda_values, lambda_values, label="理論値 (分散)", linestyle=':')

# グラフのカスタマイズ
plt.xlabel("λ")
plt.ylabel("期待値 / 分散")
plt.title("ポアソン分布の期待値と分散の可視化 (λの関数として)")
plt.legend()
plt.grid(True)
plt.show()

ポアソン分布の期待と分散が共にλになることが確認できました。