ホーム » 分布 (ページ 3)
「分布」カテゴリーアーカイブ
2016 Q4(1)
n個の標準正規分布に従う乱数が0以上1以下となる個数が従う分布を求めました。また乱数が0以上1以下となる確率の推定値の分散を求めました。
コード
この実験では、標準正規分布N(0,1)と、n個の標準正規分布に従う乱数のうち0以上1以下となる個数Xの分布、およびその確率を推定する量の分布を確認します。
# 2016 Q4(1) 2024.11.23
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import binom, norm
# ---- グラフ 1: 標準正規分布 N(0,1) と範囲 (0 < Z < 1) ----
# パラメータの設定
n_samples = 10000 # サンプル数
z_min, z_max = 0, 1 # 条件の範囲 (0 < Z < 1)
# 標準正規分布 N(0,1) に従う乱数を生成します
samples = np.random.normal(0, 1, n_samples)
# 理論的な標準正規分布の確率密度関数を計算します
x1 = np.linspace(-4, 4, 500)
pdf_theoretical = norm.pdf(x1, loc=0, scale=1)
# ---- グラフ 2: X の分布(二項分布) ----
# シミュレーションの設定
n_trials = 1000 # シミュレーションの試行回数
n = 50 # サンプルサイズ (1試行あたりの乱数生成数)
theta = 0.3413 # 真の成功確率 (0 < Z < 1)
# X の分布を計算
X_values = []
for _ in range(n_trials):
samples_trial = np.random.normal(0, 1, n)
X = np.sum((samples_trial > z_min) & (samples_trial < z_max))
X_values.append(X)
# 理論的な二項分布
x2 = np.arange(0, n + 1)
binomial_pmf = binom.pmf(x2, n, theta)
# ---- グラフ 3: θ̂1 の分布と理論分布 ----
# θ̂1 = X / n を計算
theta_hat_1_values = [X / n for X in X_values]
# 理論分布用のデータ
x3 = np.linspace(0, 1, 100)
binomial_pdf = norm.pdf(x3, loc=theta, scale=np.sqrt(theta * (1 - theta) / n))
# ---- 3つのグラフを描画 ----
plt.figure(figsize=(10, 10)) # グラフ全体のサイズを指定
# グラフ 1
plt.subplot(3, 1, 1)
plt.hist(samples, bins=50, density=True, alpha=0.5, label='全データ (N(0,1))', color='purple')
plt.axvspan(z_min, z_max, color='orange', alpha=0.3, label='0 < Z < 1 の領域')
plt.plot(x1, pdf_theoretical, 'r-', label='理論分布 (N(0,1))', linewidth=2)
plt.title('N(0,1) に従う乱数のヒストグラムと領域', fontsize=14)
plt.xlabel('Z 値', fontsize=12)
plt.ylabel('確率密度', fontsize=12)
plt.legend(fontsize=12)
plt.grid(alpha=0.3)
# グラフ 2
plt.subplot(3, 1, 2)
plt.hist(X_values, bins=np.arange(0, n + 2) - 0.5, density=True, alpha=0.6, color='green', label='X の分布 (シミュレーション)')
plt.plot(x2, binomial_pmf, 'ro-', label='理論分布 (Binomial)', markersize=4)
plt.title('X の分布と理論分布の比較', fontsize=14)
plt.xlabel('X 値', fontsize=12)
plt.ylabel('確率密度', fontsize=12)
plt.legend(fontsize=12)
plt.grid(alpha=0.3)
# グラフ 3
plt.subplot(3, 1, 3)
plt.hist(theta_hat_1_values, bins=10, density=True, alpha=0.6, color='blue', label='$\\hat{\\theta}_1$ の分布 (シミュレーション)')
plt.plot(x3, binomial_pdf, 'r-', label='理論分布 $N(\\theta, V[\\hat{\\theta}_1])$', linewidth=2)
plt.title('$\\hat{\\theta}_1$ の分布と理論分布の比較', fontsize=14)
plt.xlabel('$\\hat{\\theta}_1$ 値', fontsize=12)
plt.ylabel('確率密度', fontsize=12)
plt.legend(fontsize=12)
plt.grid(alpha=0.3)
# グラフを表示
plt.tight_layout() # 全体を整える
plt.show()
この実験によってXが二項分布B(n,θ)に従うことと、が正規分布に従うことが確認できました。
2016 Q2(4)
指数分布の上側確率の推定量が、ガンマ分布に従う確率変数の式で表され、それが不偏推定量であることを示しました。
コード
はnによらずに近づきます。nを1~20に変化させてシミュレーションして確認してみます。
# 2016 Q2(4) 2024.11.19
import numpy as np
import matplotlib.pyplot as plt
# パラメータ設定
lambda_value = 2 # 固定されたλ
c = 1.0 # 定数c
n_values = range(1, 21) # nを1から20まで変化させる
sample_size = 1000 # シミュレーションのサンプルサイズ
simulated_expectations = [] # シミュレーション期待値を格納するリスト
theoretical_expectations = [] # 理論値を格納するリスト
# 修正版コード
for n in n_values:
# ガンマ分布のサンプルを生成 (Y ~ Gamma(n, λ))
Y_samples = np.random.gamma(shape=n, scale=1/lambda_value, size=sample_size)
# 条件付きで (1 - c/Y)^(n-1) を計算
values = np.where(Y_samples >= c, (1 - c / Y_samples)**(n - 1), 0)
# シミュレーション期待値を計算
simulated_expectations.append(np.mean(values))
# 理論値 e^(-λc) を計算
theoretical_expectations.append(np.exp(-lambda_value * c))
# グラフの描画
plt.figure(figsize=(10, 6))
plt.plot(n_values, theoretical_expectations, 'r-o', label='理論値: e^(-λc)', linewidth=2)
plt.plot(n_values, simulated_expectations, 'b-s', label='シミュレーション期待値', linewidth=2)
# グラフの設定
plt.title('理論値とシミュレーション期待値の比較 (n を変化)', fontsize=16)
plt.xlabel('n (形状パラメータ)', fontsize=14)
plt.ylabel('期待値', fontsize=14)
plt.legend(fontsize=12)
plt.grid(True)
# プロットの表示
plt.show()
はnによらずに近づきました。グラフの縦軸の範囲が0.13~0.15と非常に狭いため、誤差が拡大して表示されているように見えます。実際の差異はごくわずかです。
2016 Q2(4)
指数分布の和がガンマ分布になることを示しました。
コード
指数分布に従う確率変数X1~Xnの和がガンマ分布に従うのをかを確かめるため、シミュレーションを行いました。この実験では、まずn=5の場合について確かめました。
# 2016 Q2(4) 2024.11.18
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gamma
# パラメータ設定
lambda_value = 2 # 真のλ
n = 5 # 指数分布の和の数 (ガンマ分布の形状パラメータ)
sample_size = 10000 # シミュレーションのサンプルサイズ
# 1. 指数分布の和をシミュレーション
sum_of_exponentials = np.sum(np.random.exponential(scale=1/lambda_value, size=(sample_size, n)), axis=1)
# 2. ガンマ分布の理論値を計算
x = np.linspace(0, max(sum_of_exponentials), 1000)
gamma_pdf = gamma.pdf(x, a=n, scale=1/lambda_value)
# 3. ヒストグラムと理論的なガンマ分布をプロット
plt.figure(figsize=(10, 6))
plt.hist(sum_of_exponentials, bins=50, density=True, alpha=0.6, color='skyblue', label='シミュレーション (指数分布の和)')
plt.plot(x, gamma_pdf, 'r-', label='理論的なガンマ分布', linewidth=2)
# グラフの設定
plt.title('指数分布の和 (n=5) とガンマ分布の比較', fontsize=16)
plt.xlabel('値', fontsize=14)
plt.ylabel('密度', fontsize=14)
plt.legend(fontsize=12)
plt.grid(True)
# プロット表示
plt.show()
5つの指数分布の和は、形状パラメータが5のガンマ分布に一致することが確認できました。
次に、nを変化させてシミュレーションを行い、分布の形状の変化を観察します。また、それらの分布がガンマ分布と一致するかを確認します。
# 2016 Q2(4) 2024.11.18
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gamma
# パラメータ設定
lambda_value = 2 # 真のλ
n_values = [2, 5, 10, 20] # nの値を変化させる
sample_size = 10000 # シミュレーションのサンプルサイズ
# 2x2のグリッドでプロット
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
axes = axes.flatten()
for i, n in enumerate(n_values):
# 指数分布の和をシミュレーション
sum_of_exponentials = np.sum(np.random.exponential(scale=1/lambda_value, size=(sample_size, n)), axis=1)
# ガンマ分布の理論値を計算
x = np.linspace(0, 20, 1000) # 横軸の範囲を0~20に設定
gamma_pdf = gamma.pdf(x, a=n, scale=1/lambda_value)
# ヒストグラムと理論的なガンマ分布をプロット
ax = axes[i]
ax.hist(sum_of_exponentials, bins=50, range=(0, 20), density=True, alpha=0.6, color='skyblue', label='シミュレーション (指数分布の和)')
ax.plot(x, gamma_pdf, 'r-', label='理論的なガンマ分布', linewidth=2)
# グラフの設定
ax.set_title(f'n={n}', fontsize=14)
ax.set_xlabel('値', fontsize=12)
ax.set_ylabel('密度', fontsize=12)
ax.legend(fontsize=10)
ax.grid(True)
# 全体のレイアウト調整
plt.suptitle('nを変化させた指数分布の和とガンマ分布の比較', fontsize=16)
plt.tight_layout(rect=[0, 0, 1, 0.96])
plt.show()
nが小さいときは分布が右に裾が長くなり、nが大きくなるにつれて左右対称に近づいています。また、どのnにおいても形状パラメータnのガンマ分布とよく一致していることが確認できました。
2016 Q2(3)
指数分布のλと、上側α点を返す関数の最尤推定量を求め、不偏であるか確認しました。
コード
最尤推定量をシミュレーションし、理論値と比較します。共にグラフに描画し、どの程度一致しているか確認します。
# 2016 Q2(3) 2024.11.17
import numpy as np
import matplotlib.pyplot as plt
# パラメータ設定
lambda_value = 2 # 真のλ
n = 100 # サンプル数
c = 1.0 # Q(c) を計算するための c の値
alpha_values = [0.1, 0.25, 0.5, 0.75, 0.9] # αの値
# 1. 指数分布からサンプルを生成
samples = np.random.exponential(scale=1/lambda_value, size=n)
# 2. λの最尤推定量を計算
lambda_hat = n / np.sum(samples)
# 3. Q(c) の最尤推定量を計算
Q_hat_c = np.exp(-lambda_hat * c)
Q_theoretical_c = np.exp(-lambda_value * c)
# 4. u(α) の最尤推定量を計算
u_hat_alpha = [-np.mean(samples) * np.log(alpha) for alpha in alpha_values]
u_theoretical_alpha = [-np.log(alpha) / lambda_value for alpha in alpha_values]
# グラフ作成部分
plt.figure(figsize=(10, 6))
# 理論値と最尤推定量の u(α) をプロット
plt.plot(alpha_values, u_theoretical_alpha, 'r-o', label='u(α) 理論値', linewidth=2)
plt.plot(alpha_values, u_hat_alpha, 'b--s', label='u(α) 最尤推定量', linewidth=2) # 'b--s' で破線とマーカーを指定
# グラフの設定
plt.title('u(α) の理論値と最尤推定量の比較', fontsize=16)
plt.xlabel('α', fontsize=14)
plt.ylabel('u(α)', fontsize=14)
plt.legend(fontsize=12)
plt.grid(True)
plt.xticks(alpha_values)
# グラフの表示
plt.show()
はわずかに誤差があるものの概ね一致しました。また誤差はαが大きくなるにつれて小さくなります。その理由は、αが大きくなるとu(α)の値が小さくなり、分布の高密度な部分にサンプルが集中するためと考えられます。
2016 Q2(2)
指数分布の上側α点を返す関数を求めました。
コード
パラメータλ=2の指数分布において、Q(c)=P(X>c)をシミュレーションによって求め、理論値と比較します。c=1とします。また、P(X>u(α))=αとなるu(α)も同様に比較します。
# 2016 Q2(2) 2024.11.16
import numpy as np
import matplotlib.pyplot as plt
# パラメータ設定
lambda_value = 2 # λの値
sample_size = 10000 # シミュレーションに使用するサンプル数
c = 1.0 # 上側確率を計算するための定数 c
alpha_values = [0.1, 0.25, 0.5, 0.75, 0.9] # 上側 100α% 点を確認する α の値
# 1. 上側確率 Q(c) のシミュレーション
random_samples = np.random.exponential(scale=1/lambda_value, size=sample_size)
empirical_prob_c = np.mean(random_samples > c) # シミュレーションによる上側確率
theoretical_prob_c = np.exp(-lambda_value * c) # 理論的な上側確率
# 結果表示
print("上側確率 Q(c) のシミュレーション結果")
print(f"理論的な Q(c) = {theoretical_prob_c:.4f}")
print(f"シミュレーションによる Q(c) = {empirical_prob_c:.4f}\n")
# 2. 上側 100α% 点 u(α) の確認
alpha_results = []
for alpha in alpha_values:
u_alpha = -np.log(alpha) / lambda_value # 理論的な上側 100α% 点
empirical_prob_alpha = np.mean(random_samples > u_alpha) # u(α) を超える割合
alpha_results.append((alpha, u_alpha, empirical_prob_alpha))
# 結果表示
print("上側 100α% 点 u(α) のシミュレーション結果")
for alpha, u_alpha, empirical_prob_alpha in alpha_results:
print(f"α = {alpha:.2f} | 理論的な u(α) = {u_alpha:.4f} | 理論的確率P(X>u(α)) = {alpha:.2f} | シミュレーション確率 = {empirical_prob_alpha:.4f}")
# ヒストグラムのプロット
plt.figure(figsize=(10, 6))
plt.hist(random_samples, bins=50, density=True, alpha=0.6, color='skyblue', label='サンプルのヒストグラム')
# 理論的な確率密度関数
x = np.linspace(0, max(random_samples), 1000)
theoretical_pdf = lambda_value * np.exp(-lambda_value * x)
plt.plot(x, theoretical_pdf, 'r-', label='理論的な確率密度関数', linewidth=2)
# 上側 100α% 点 u(α) のプロット
for alpha, u_alpha, _ in alpha_results:
plt.axvline(u_alpha, linestyle='dashed', label=f'u({alpha}) = {u_alpha:.2f}')
# グラフ設定
plt.title(f'指数分布 Exp({lambda_value}) のシミュレーションと理論分布')
plt.xlabel('x')
plt.ylabel('密度')
plt.legend(fontsize=10)
plt.grid(True)
# プロット表示
plt.show()
上側確率 Q(c) のシミュレーション結果
理論的な Q(c) = 0.1353
シミュレーションによる Q(c) = 0.1365
上側 100α% 点 u(α) のシミュレーション結果
α = 0.10 | 理論的な u(α) = 1.1513 | 理論的確率P(X>u(α)) = 0.10 | シミュレーション確率 = 0.1035
α = 0.25 | 理論的な u(α) = 0.6931 | 理論的確率P(X>u(α)) = 0.25 | シミュレーション確率 = 0.2480
α = 0.50 | 理論的な u(α) = 0.3466 | 理論的確率P(X>u(α)) = 0.50 | シミュレーション確率 = 0.4962
α = 0.75 | 理論的な u(α) = 0.1438 | 理論的確率P(X>u(α)) = 0.75 | シミュレーション確率 = 0.7513
α = 0.90 | 理論的な u(α) = 0.0527 | 理論的確率P(X>u(α)) = 0.90 | シミュレーション確率 = 0.9011
Q(c)=P(X>c)とP(X>u(α))の理論値とシミュレーション結果は非常によく一致しました。
2016 Q2(1)
指数分布の期待値を求めました。
コード
指数分布Exp(λ)に従うXの確率密度関数をとするとき、Xのシミュレーションを行い、その分布のヒストグラムと理論的な確率密度関数のグラフを重ねて描画してみます。λ=2とします。
# 2016 Q2(1) 2024.11.15
import numpy as np
import matplotlib.pyplot as plt
# シミュレーションとプロット
def simulate_and_plot_exponential(lambda_value=2, sample_size=50000, bins=100):
# 指数分布に従う乱数を生成
random_samples = np.random.exponential(scale=1/lambda_value, size=sample_size)
# 理論的な確率密度関数を計算
x = np.linspace(0, 5, 1000)
theoretical_pdf = lambda_value * np.exp(-lambda_value * x)
# サンプルのヒストグラムを描画
plt.figure(figsize=(10, 6))
plt.hist(random_samples, bins=bins, density=True, alpha=0.6, color='skyblue', label='サンプルのヒストグラム')
# 理論的な確率密度関数を重ねる
plt.plot(x, theoretical_pdf, 'r-', label='理論的な確率密度関数', linewidth=2)
# 期待値を計算
simulated_mean = np.mean(random_samples)
theoretical_mean = 1 / lambda_value
# 期待値を直線でプロット
plt.axvline(simulated_mean, color='green', linestyle='dashed', linewidth=2, label=f'シミュレーション期待値: {simulated_mean:.2f}')
plt.axvline(theoretical_mean, color='blue', linestyle='dotted', linewidth=2, label=f'理論期待値: {theoretical_mean:.2f}')
# グラフの設定
plt.title(f'指数分布のシミュレーションと理論分布 (λ={lambda_value})', fontsize=16)
plt.xlabel('x', fontsize=14)
plt.ylabel('密度', fontsize=14)
plt.legend(fontsize=12)
plt.grid(True)
# プロットを表示
plt.show()
# 実行
simulate_and_plot_exponential()
Xの分布は、確率密度関数とよく一致しており、シミュレーションで得られた期待値も理論値に非常に近い値となりました。
では、次にλを変化させて同様の実験を行い、グラフの形状の変化と期待値がどのように変化するかを確認します。
# 2016 Q2(1) 2024.11.15
import numpy as np
import matplotlib.pyplot as plt
# シミュレーションとプロット
def simulate_and_plot_adjusted_lambdas(lambdas=[0.5, 1, 2, 3], sample_size=50000, bins=100):
fig, axes = plt.subplots(2, 2, figsize=(12, 10), sharex=True, sharey=True)
x = np.linspace(0, 6, 1000) # 横軸の範囲を0~6に限定
for i, lambda_value in enumerate(lambdas):
row, col = divmod(i, 2)
ax = axes[row, col]
# 乱数生成と理論値計算
random_samples = np.random.exponential(scale=1/lambda_value, size=sample_size)
theoretical_pdf = lambda_value * np.exp(-lambda_value * x)
# ヒストグラムと理論分布
ax.hist(random_samples, bins=bins, range=(0, 6), density=True, alpha=0.6, color='skyblue', label='サンプルのヒストグラム')
ax.plot(x, theoretical_pdf, 'r-', label='理論的な確率密度関数', linewidth=2)
# 期待値を計算してプロット
simulated_mean = np.mean(random_samples)
theoretical_mean = 1 / lambda_value
ax.axvline(simulated_mean, color='green', linestyle='dashed', linewidth=2, label=f'シミュレーション期待値: {simulated_mean:.2f}')
ax.axvline(theoretical_mean, color='blue', linestyle='dotted', linewidth=2, label=f'理論期待値: {theoretical_mean:.2f}')
# グラフ設定
ax.set_xlim(0, 6) # 横軸を0~6に限定
ax.set_title(f'λ={lambda_value}', fontsize=14)
ax.set_xlabel('x', fontsize=12)
ax.set_ylabel('密度', fontsize=12)
ax.legend(fontsize=10)
ax.grid(True)
# 全体のタイトルと調整
plt.suptitle('異なるλにおける指数分布のシミュレーションと理論分布', fontsize=16)
plt.tight_layout(rect=[0, 0, 1, 0.96]) # タイトルとの重なり防止
plt.show()
# 実行
simulate_and_plot_adjusted_lambdas()
λが大きくなるにつれて分布の形状は急こう配になり期待値が小さくなることが確認できました。λの増加によって小さい値が観測される確率が高くなるためだと考えられます。
2017 Q5(3)
独立した二つの自由度1のカイ二乗分布の差を幾何平均と2でスケールした式の確率密度関数を導出しました。
コード
Tについてシミュレーションし、確率密度関数と一致するか確認をします。
# 2017 Q5(3) 2024.11.10
import numpy as np
import matplotlib.pyplot as plt
# サンプルサイズ
n_samples = 100000
# 自由度1のカイ二乗分布からサンプルを生成
X = np.random.chisquare(df=1, size=n_samples)
Y = np.random.chisquare(df=1, size=n_samples)
# 確率変数 T = (X - Y) / (2 * sqrt(X * Y)) の計算
T = (X - Y) / (2 * np.sqrt(X * Y))
# 理論的な確率密度関数 h(t) の定義
def theoretical_h(t):
return 1 / (np.pi * (1 + t**2))
# x 軸の範囲を設定し、h(t) を計算
x = np.linspace(-10, 10, 100)
h_t = theoretical_h(x)
# グラフの描画
plt.hist(T, bins=200, density=True, alpha=0.5, range=(-10, 10), label='シミュレーションによる $T$')
plt.plot(x, h_t, 'r-', label='理論的な $h(t) = \\frac{1}{\\pi(1+t^2)}$')
plt.xlabel('$T$')
plt.ylabel('密度')
plt.legend()
plt.title('確率変数 $T$ のシミュレーションと理論密度関数')
plt.show()
Tの分布は確率密度関数と一致することが確認できました。
なお、Tの分布は標準コーシー分布と呼ばれます。
2017 Q5(2)
独立した二つの自由度1のカイ二乗分布の比の確率密度関数を導出し、F(1,1)分布と同じであることを確認しました。
コード
Sについてシミュレーションし、確率密度関数と一致するか確認をします。
# 2017 Q5(2) 2024.11.9
import numpy as np
import matplotlib.pyplot as plt
# サンプルサイズ
n_samples = 100000
# 自由度1のカイ二乗分布からサンプルを生成
X = np.random.chisquare(df=1, size=n_samples)
Y = np.random.chisquare(df=1, size=n_samples)
# 確率変数 S = X / Y の計算
S = X / Y
# 理論的な確率密度関数 g(s) の定義
def theoretical_g(s):
return (1 / (np.pi * np.sqrt(s) * (1 + s)))
# x 軸の範囲を設定し、g(s) を計算
x = np.linspace(0.01, 10, 100) # 0.01から10の範囲に制限
g_s = theoretical_g(x)
# ヒストグラムの描画
plt.hist(S, bins=200, density=True, alpha=0.5, range=(0, 10), label='シミュレーションによる $S=X/Y$')
plt.plot(x, g_s, 'r-', label='理論的な $g(s) = \\frac{1}{\\pi \\sqrt{s}} \\cdot \\frac{1}{1+s}$')
plt.xlabel('$S$')
plt.ylabel('密度')
plt.legend()
plt.title('確率変数 $S=X/Y$ のシミュレーションと理論密度関数')
plt.show()
Sの分布は確率密度関数と一致することが確認できました。
2017 Q5(1)
標準正規分布から自由度1のカイ二乗分布の確率密度関数を導出しました。
コード
Vについてシミュレーションし、確率密度関数と一致するか確認をします。
# 2017 Q5(1) 2024.11.8
import numpy as np
import matplotlib.pyplot as plt
# サンプルサイズ
n_samples = 10000
# 標準正規分布 N(0, 1) からサンプルを生成
Z = np.random.normal(0, 1, n_samples)
# Z を二乗して V を計算
V = Z**2
# 導いた理論的な確率密度関数 f(v) の定義
def theoretical_pdf(v):
return (1 / np.sqrt(2 * np.pi)) * (1 / np.sqrt(v)) * np.exp(-v / 2)
# x 軸の範囲を設定し、f(v) を計算
x = np.linspace(0.01, 10, 100) # 0に近い値での計算エラーを避けるため0.01から
f_v = theoretical_pdf(x)
# ヒストグラムの描画
plt.hist(V, bins=200, density=True, alpha=0.5, label='シミュレーションによる $V=Z^2$')
plt.plot(x, f_v, 'r-', label='理論的な $f(v) = \\frac{1}{\\sqrt{2\\pi}} \\cdot \\frac{1}{\\sqrt{v}} e^{-v/2}$')
plt.xlabel('$V$')
plt.ylabel('密度')
plt.legend()
plt.title('自由度1のカイ二乗分布に従う $V=Z^2$ のシミュレーションと理論密度関数')
plt.show()
Vの分布は確率密度関数と一致することが確認できました。
2017 Q4(4)
線形関係のある確率変数の条件付き確率分布を求めました。
コード
X|Z=zがに従うかシミュレーションし確かめます。
# 2017 Q4(4) 2024.11.7
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
# 定数の設定
a = 1
k = 2
num_samples = 1000000
z_fixed = 3 # 条件として与える Z の値
# シミュレーション
Y = np.random.normal(0, 1, num_samples)
X = np.random.normal(0, 1, num_samples)
Z = a + k * X + Y
# Z = z_fixed に条件を付けた X の分布を抽出
X_given_Z = (X[np.abs(Z - z_fixed) < 0.05])
# 理論値の計算
mean_conditional = (k / (k**2 + 1)) * (z_fixed - a)
std_dev_conditional = np.sqrt(1 / (k**2 + 1))
# シミュレーションによる値の計算
mean_simulation = np.mean(X_given_Z)
std_dev_simulation = np.std(X_given_Z)
# 理論値とシミュレーション値を出力
print(f"理論上の期待値 (X | Z = {z_fixed}): {mean_conditional}")
print(f"シミュレーションによる期待値: {mean_simulation}")
print(f"理論上の標準偏差: {std_dev_conditional}")
print(f"シミュレーションによる標準偏差: {std_dev_simulation}")
# 条件付き分布のヒストグラム
plt.hist(X_given_Z, bins=50, density=True, alpha=0.6, color='b', label=f"シミュレーション X | Z = {z_fixed}")
# 理論分布をプロット
x_vals = np.linspace(min(X_given_Z), max(X_given_Z), 100)
plt.plot(x_vals, norm.pdf(x_vals, mean_conditional, std_dev_conditional), 'r', label="理論分布")
# グラフの装飾
plt.title(f"条件付き分布 X | Z = {z_fixed}")
plt.xlabel("X の値")
plt.ylabel("密度")
plt.legend()
plt.show()
X|Z=zはに従うことが確認できました。