ホーム » コードあり (ページ 15)
「コードあり」カテゴリーアーカイブ
2021 Q1(3)
変数変換を用いて二つの分布の和の確率密度関数を求めました。
コード
数式を使った計算
# 2024 Q1(3) 2024.8.19
import sympy as sp
# シンボリック変数の定義
x, z = sp.symbols('x z')
# 確率密度関数の定義
f_X = sp.exp(-x) # f_X(x) = e^(-x)
f_Y = sp.Piecewise((1, (z - x >= 0) & (z - x <= 1)), (0, True)) # f_Y(z - x) for 0 < z - x < 1
# 一般的な積分の設定
f_Z_integral = sp.integrate(f_X * f_Y, (x, 0, z))
# 結果の簡略化
f_Z_general = sp.simplify(f_Z_integral)
# 結果の表示
display(f_Z_general)
簡単のため、zの範囲を指定して再度計算
# 2024 Q1(3) 2024.8.19
import sympy as sp
# シンボリック変数の定義
x, z = sp.symbols('x z')
# 確率密度関数の定義
f_X = sp.exp(-x) # f_X(x) = e^(-x)
f_Y = 1 # f_Y(y) = 1 (0 < y < 1)
# 各範囲での計算
# 1. z <= 0 の場合
f_Z_1 = 0 # z <= 0 の場合は f_Z(z) = 0
# 2. 0 < z <= 1 の場合
f_Z_2_integral = sp.integrate(f_X * f_Y, (x, 0, z))
f_Z_2 = sp.simplify(f_Z_2_integral)
# 3. z > 1 の場合
f_Z_3_integral = sp.integrate(f_X * f_Y, (x, z-1, z))
f_Z_3 = sp.simplify(f_Z_3_integral)
# 結果の表示
print(f"f_Z(z) for z <= 0:")
display(f_Z_1)
print(f"f_Z(z) for 0 < z <= 1:")
display(f_Z_2)
print(f"f_Z(z) for z > 1:")
display(f_Z_3)
プロット
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import quad
# 確率密度関数 f_X(x) と f_Y(y)
def f_X(x):
return np.exp(-x) if x > 0 else 0
def f_Y(y):
return 1 if 0 < y < 1 else 0
# Z = X + Y の確率密度関数 f_Z(z) の計算
def f_Z(z):
integrand = lambda x: f_X(x) * f_Y(z - x)
return quad(integrand, max(0, z-1), z)[0] #積分範囲を限定する場合
#return quad(integrand, 0, z, epsabs=1e-8, epsrel=1e-8)[0] #積分範囲を広くする場合
# z の範囲を設定し、f_Z(z) を計算
z_values = np.linspace(0, 5, 1000) # 増加させたサンプル数
f_Z_values = np.array([f_Z(z) for z in z_values])
# グラフの描画
plt.plot(z_values, f_Z_values, label='f_Z(z) = X + Y')
plt.xlabel('z')
plt.ylabel('確率密度')
plt.title('X + Y の確率密度関数')
plt.legend()
plt.grid(True)
plt.show()
2021 Q1(1)(2)
指数分布と一様分布の期待値と、それらが独立な場合の積の期待値を求めました。
コード
数式を使った計算
# 2021 Q1(1)(2) 2024.8.18
import numpy as np
from scipy.integrate import quad
# Xの期待値の計算
def fx(x):
return x * np.exp(-x)
E_X, _ = quad(fx, 0, np.inf)
# Yの期待値の計算
def fy(y):
return y
E_Y, _ = quad(fy, 0, 1)
# XYの期待値の計算(独立の場合)
E_XY = E_X * E_Y
print(f"E[X] = {E_X}")
print(f"E[Y] = {E_Y}")
print(f"E[XY] (独立の場合) = {E_XY}")
E[X] = 0.9999999999999998
E[Y] = 0.5
E[XY] (独立の場合) = 0.4999999999999999
シミュレーションによる計算
# 2021 Q1(1)(2) 2024.8.18
import numpy as np
# シミュレーションの設定
num_samples = 1000000 # サンプル数
# Xの乱数生成(指数分布)
X_samples = np.random.exponential(scale=1.0, size=num_samples)
# Yの乱数生成(一様分布)
Y_samples = np.random.uniform(0, 1, size=num_samples)
# (1) XとYの期待値の計算
E_X_simulation = np.mean(X_samples)
E_Y_simulation = np.mean(Y_samples)
# (2) XYの期待値の計算(独立な場合)
E_XY_simulation = np.mean(X_samples * Y_samples)
print(f"E[X] = {E_X_simulation}")
print(f"E[Y] = {E_Y_simulation}")
print(f"E[XY] = {E_XY_simulation}")
E[X] = 1.0001064255963075
E[Y] = 0.4998284579940602
E[XY] = 0.4998038319582688
2022 Q5(5)
欠損値がある場合の、分散分析に於けるF検定の影響に関する問をもう一問やりました。
コード
シミュレーションによる計算
# 2022 Q5(5) 2024.8.17
import numpy as np
# シミュレーションの設定
np.random.seed(42)
n = 5 # サンプル数
X = np.random.normal(10, 2, n) # Xの観測値
# Y1が非常に大きな値を取るケースを考慮
Y = np.random.normal(15, 2, n)
Y[0] = 1000 # Y1が非常に大きな値を取る設定
# 全体平均とY2:nの平均
Y_bar = np.mean(Y) # 全体の平均
Y_bar_2n = np.mean(Y[1:]) # Y2:n の平均
X_bar_2n = np.mean(X[1:]) # X2:n の平均
# θの推定値
theta_hat = Y_bar_2n - X_bar_2n
# SAの計算(Y1を含める場合)
SA_with_Y1 = np.sum(((X[1:] + Y[1:] - theta_hat) / 2 - X_bar_2n) ** 2) + (Y[0] - Y_bar) ** 2
SA_with_Y1 += np.sum(((X[1:] + Y[1:] + theta_hat) / 2 - Y_bar) ** 2)
# SAの計算(Y1を除く場合)
SA_without_Y1 = np.sum(((X[1:] + Y[1:] - theta_hat) / 2 - X_bar_2n) ** 2)
SA_without_Y1 += np.sum(((X[1:] + Y[1:] + theta_hat) / 2 - Y_bar_2n) ** 2)
# 結果を表示
{
"Y1を含めた場合の要因A平方和 (SA)": SA_with_Y1,
"Y1を除いた場合の要因A平方和 (SA)": SA_without_Y1
}
{'Y1を含めた場合の要因A平方和 (SA)': 774276.0933538243,
'Y1を除いた場合の要因A平方和 (SA)': 1.6720954914667048}
2022 Q5(4)
欠損値がある場合の、分散分析に於けるF検定の影響に関する問をやりました。
コード
シミュレーションによる計算
# 2022 Q5(4) 2024.8.16
import numpy as np
# シミュレーションのための設定
np.random.seed(42)
n = 5 # サンプル数
X = np.random.normal(10, 2, n) # Xの観測値
Y = np.random.normal(15, 2, n) # Yの観測値
# ケース1: Y1を含めた場合の計算
mu_0_1 = Y[0] # Y1に対応する μ_0
mu_i_with_Y1 = (X[1:] + Y[1:]) / 2 # 残りの μ_i の計算
SE_with_Y1 = np.sum((X[1:] - mu_i_with_Y1) ** 2) + np.sum((Y[1:] - mu_i_with_Y1) ** 2)
# Y1に対する特別な処理
SE_with_Y1 += (Y[0] - mu_0_1) ** 2 # Y1 の影響を追加
# ケース2: Y1を除いた場合の計算
mu_i_without_Y1 = (X[1:] + Y[1:]) / 2 # Y1を除いた場合の μ_i の計算
SE_without_Y1 = np.sum((X[1:] - mu_i_without_Y1) ** 2) + np.sum((Y[1:] - mu_i_without_Y1) ** 2)
# 要因Bに関する平方和(SB)の計算
mu_B_with_Y1 = np.mean(Y[1:]) # Y1を含めた場合のBの平均
mu_B_without_Y1 = np.mean(Y[1:]) # Y1を除いた場合のBの平均
# Y1専用の平均を計算してY1の寄与を計算
mu_0_Y1 = Y[0] # Y1専用の平均はY1自体
SB_with_Y1 = np.sum((Y[1:] - mu_B_with_Y1) ** 2)
SB_with_Y1 += (Y[0] - mu_0_Y1) ** 2 # Y1の寄与を専用の平均で追加
SB_without_Y1 = np.sum((Y[1:] - mu_B_without_Y1) ** 2)
# 結果を表示
{
"Y1を含めた場合の残差平方和 (SE)": SE_with_Y1,
"Y1を除いた場合の残差平方和 (SE)": SE_without_Y1,
"Y1を含めた場合の要因B平方和 (SB)": SB_with_Y1,
"Y1を除いた場合の要因B平方和 (SB)": SB_without_Y1,
}
{'Y1を含めた場合の残差平方和 (SE)': 71.28917221001626,
'Y1を除いた場合の残差平方和 (SE)': 71.28917221001626,
'Y1を含めた場合の要因B平方和 (SB)': 8.53547835010338,
'Y1を除いた場合の要因B平方和 (SB)': 8.53547835010338}
コメント
Y[0] – mu_0_1 と Y[0] – mu_0_Y1 が0になるので、Y1の有無が結果に影響しない。
2022 Q5(3)
分散分析の各要因の効果を検定する検定量と帰無分布を求めました。
コード
シミュレーションによる計算
# 2022 Q5(3) 2024.8.15
import numpy as np
import pandas as pd
import scipy.stats as stats
# シミュレーションのための設定
np.random.seed(42)
n = 10 # 因子Aの水準数
mu_A = [5, 10, 15] # 因子Aの水準ごとの平均
mu_B = [7, 12] # 因子Bの水準ごとの平均
sigma = 2 # 標準偏差
n_samples = n * 2 # 各水準ごとのサンプル数
# データ生成
data = np.zeros((n, 2))
for i in range(n):
data[i, 0] = np.random.normal(mu_A[i % len(mu_A)], sigma) # 因子A
data[i, 1] = np.random.normal(mu_B[i % len(mu_B)], sigma) # 因子B
# データフレームにまとめる
df = pd.DataFrame(data, columns=['A', 'B'])
# 全平均
m = df.mean().mean()
# 各水準での平均
m_Ai = df['A'].mean()
m_Bj = df['B'].mean()
# 偏差平方和の計算
SA = np.sum((df['A'] - m_Ai) ** 2)
SB = np.sum((df['B'] - m_Bj) ** 2)
SE = np.sum((df.values - m_Ai - m_Bj + m) ** 2)
# 自由度
phi_A = n - 1
phi_B = 1
phi_E = n - 1
# 分散分析の統計量
F_A = (SA / phi_A) / (SE / phi_E)
F_B = (SB / phi_B) / (SE / phi_E)
# p値の計算
p_A = 1 - stats.f.cdf(F_A, phi_A, phi_E)
p_B = 1 - stats.f.cdf(F_B, phi_B, phi_E)
# 結果の表示
{
"F_A": F_A,
"p_A": p_A,
"F_B": F_B,
"p_B": p_B,
"SA": SA,
"SB": SB,
"SE": SE,
"df_A": phi_A,
"df_B": phi_B,
"df_E": phi_E
}
{'F_A': 0.5528514017044434,
'p_A': 0.8047382043674255,
'F_B': 4.023821861099081,
'p_B': 0.07582222108466219,
'SA': 139.17265361165713,
'SB': 112.54902298706004,
'SE': 251.73609614190576,
'df_A': 9,
'df_B': 1,
'df_E': 9}
2022 Q5(2)
分散分析モデルのパラメータを求める問題をやりました。
コード
# 2022 Q5(2) 2024.8.14
import sympy as sp
# サンプル数を具体的な数値に設定
n = 3 # 例として n = 3 とする
# シンボリック変数の定義
mu = sp.symbols(f'mu_1:{n+1}') # mu_1, mu_2, mu_3 を定義
theta, nu = sp.symbols('theta nu')
a = sp.symbols(f'a_1:{n+1}') # a_1, a_2, a_3 を定義
b1, b2 = sp.symbols('b1 b2')
# 制約条件
constraint_a = sp.Eq(sum(a), 0)
constraint_b = sp.Eq(b1 + b2, 0)
# Z_{i1} = X_i の関係式
eq1 = sp.Eq(nu + a[0] + b1, mu[0])
# Z_{i2} = Y_i の関係式
eq2 = sp.Eq(nu + a[0] + b2, mu[0] + theta)
# b1, b2 の解を求める
solution_b = sp.solve([constraint_b, b2 - b1 - theta], (b1, b2))
b1_solution = solution_b[b1]
b2_solution = solution_b[b2]
# νとa_iを求めるための方程式
nu_a_eq = eq1.subs({b1: b1_solution})
# νを求める
nu_solution = sp.solve(nu_a_eq, nu)[0]
# a_iの解
a_solution = [mu[i] - sp.symbols('mu_bar') for i in range(n)]
# 結果を表示
display(nu_solution, a_solution, b1_solution, b2_solution)
2022 Q5(1)
正規分布の差の分布を求める問題をやりました。
コード
シミュレーションによる計算
# 2022 Q4(5) 2024.8.13
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as stats
# パラメータの設定
mu_i = 5.0 # 平均値 mu_i
theta = 3.0 # シフトパラメータ θ
sigma = 1.0 # 標準偏差 σ
n = 1000 # サンプル数
# X_i と Y_i のサンプル生成
X_i = np.random.normal(mu_i, sigma, n)
Y_i = np.random.normal(mu_i + theta, sigma, n)
# D_i の計算
D_i = Y_i - X_i
# シミュレーション結果の平均と分散を計算
mean_simulation = np.mean(D_i)
variance_simulation = np.var(D_i)
# 理論上の平均と分散
mean_theoretical = theta
variance_theoretical = 2 * sigma**2
# 結果の表示
print(f"シミュレーション結果: 平均 = {mean_simulation}, 分散 = {variance_simulation}")
print(f"理論値: 平均 = {mean_theoretical}, 分散 = {variance_theoretical}")
# サンプルのヒストグラムを作成
plt.hist(D_i, bins=30, density=True, alpha=0.6, color='g', label='サンプルデータ')
# 理論上の分布を重ねる
x = np.linspace(min(D_i), max(D_i), 1000)
plt.plot(x, stats.norm.pdf(x, mean_theoretical, np.sqrt(variance_theoretical)), 'r', label='理論的な確率密度関数')
plt.title("差 $D_i = Y_i - X_i$ の分布")
plt.xlabel("$D_i$")
plt.ylabel("密度")
plt.legend()
plt.show()
シミュレーション結果: 平均 = 2.975536685240219, 分散 = 2.005575154363111
理論値: 平均 = 3.0, 分散 = 2.0
2022 Q4(5)
パラメータの推定量の期待値と分散を求めました。
コード
数式を使った計算
# 2022 Q4(5) 2024.8.12
import sympy as sp
# シンボリック変数の定義
gamma = sp.Symbol('gamma', positive=True)
x = sp.Symbol('x', positive=True)
# 確率密度関数 f_X(x) の定義
f_X = (1/gamma) * x**(-(1/gamma + 1))
# E[log X] の計算
E_log_X = sp.integrate(sp.log(x) * f_X, (x, 1, sp.oo))
# E[(log X)^2] の計算
E_log_X2 = sp.integrate((sp.log(x))**2 * f_X, (x, 1, sp.oo))
# V[log X] の計算
V_log_X = E_log_X2 - E_log_X**2
# E[hat_gamma] と V[hat_gamma] の計算
n = sp.Symbol('n', positive=True, integer=True)
E_hat_gamma = E_log_X
V_hat_gamma = V_log_X / n
# 結果の表示
display(E_hat_gamma, V_hat_gamma)
# LaTeXで表示できなときは、こちら
#sp.pprint(E_hat_gamma, use_unicode=True)
#sp.pprint(V_hat_gamma, use_unicode=True)
シミュレーションによる計算
# 2022 Q4(5) 2024.8.12
import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt
# パラメータ設定
gamma_true = 1.0 # 真のγの値
n = 100 # サンプルサイズ
num_simulations = 10000 # シミュレーションの回数
# 最尤推定量 \hat{gamma} を格納するリスト
gamma_hats = []
# シミュレーションの実行
for _ in range(num_simulations):
# 累積分布関数 F(x) に従う乱数を生成
X = np.random.uniform(size=n)**(-gamma_true)
# \hat{gamma} の計算
gamma_hat = np.mean(np.log(X))
gamma_hats.append(gamma_hat)
# シミュレーション結果の期待値と分散
E_hat_gamma_sim = np.mean(gamma_hats)
V_hat_gamma_sim = np.var(gamma_hats)
# 理論値を計算
# 理論値の計算は、sympyを使って導出した結果を使用
E_hat_gamma_theoretical = 1 / gamma_true # gammaが1の場合は1が期待値になります
V_hat_gamma_theoretical = (np.pi ** 2) / (6 * n * gamma_true**2)
# 結果の表示
print(f"シミュレーションによる期待値 E[hat_gamma]: {E_hat_gamma_sim}")
print(f"シミュレーションによる分散 V[hat_gamma]: {V_hat_gamma_sim}")
print(f"理論値による期待値 E[hat_gamma]: {E_hat_gamma_theoretical}")
print(f"理論値による分散 V[hat_gamma]: {V_hat_gamma_theoretical}")
# ヒストグラムのプロット
plt.hist(gamma_hats, bins=50, density=True, alpha=0.6, color='g')
plt.axvline(E_hat_gamma_sim, color='r', linestyle='dashed', linewidth=2, label='シミュレーション平均')
plt.axvline(E_hat_gamma_theoretical, color='b', linestyle='dashed', linewidth=2, label='理論値')
plt.xlabel(r'$\hat{\gamma}$の値')
plt.ylabel('密度')
plt.title(r'$\hat{\gamma}$の分布')
plt.legend()
plt.show()
シミュレーションによる期待値 E[hat_gamma]: 0.9995206635186084
シミュレーションによる分散 V[hat_gamma]: 0.010015979040467726
理論値による期待値 E[hat_gamma]: 1.0
理論値による分散 V[hat_gamma]: 0.016449340668482262
アルゴリズム
サンプル生成:
X = np.random.uniform(size=n)**(-gamma_true)
で累積分布関数 F(x) に従う乱数を生成します。逆関数法を使用しています。
最尤推定量の計算:
gamma_hat = np.mean(np.log(X))
で各サンプルから計算された をリストgamma_hats
に格納します。
シミュレーション結果の期待値と分散:
- シミュレーション結果の期待値と分散を
E_hat_gamma_sim
とV_hat_gamma_sim
に計算し、理論値と比較します。
理論値との比較:
- 理論値を計算して表示し、シミュレーション結果と比較します。
2022 Q4(4)
対数で変数変換した場合の分布を求めました。
コード
数式を使った計算
# 2022 Q4(4) 2024.8.11
import sympy as sp
# シンボリック変数の定義
t, gamma = sp.symbols('t gamma', positive=True)
x = sp.symbols('x', real=True, positive=True)
# 累積分布関数 F_X(x) の定義
F_X = sp.Piecewise((0, x <= 1), (1 - x**(-1/gamma), x > 1))
# F_T(t) の計算
F_T = F_X.subs(x, sp.exp(gamma * t))
# f_T(t) の計算(F_T(t) を t で微分)
f_T = sp.diff(F_T, t)
# 結果の表示
display(F_T, f_T)
# LaTeXで表示できなときは、こちら
#sp.pprint(F_T, use_unicode=True)
#sp.pprint(f_T, use_unicode=True)
シミュレーションによる計算
# 2022 Q4(4) 2024.8.11
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as stats
# パラメータ設定
gamma = 1.0 # γの値(例えば1)
num_samples = 10000 # サンプルサイズ
# 累積分布関数 F(x) に従う乱数を生成
X = (np.random.uniform(size=num_samples))**(-gamma)
# T = (1/γ) * log(X) の計算
T = (1/gamma) * np.log(X)
# ヒストグラムをプロット
plt.hist(T, bins=50, density=True, alpha=0.6, color='g', label="シミュレーションによる T")
# 理論的な指数分布の密度関数をプロット
x = np.linspace(0, 8, 100)
pdf = stats.expon.pdf(x) # 指数分布(λ=1)の密度関数
plt.plot(x, pdf, 'r-', lw=2, label='指数分布の理論値')
# グラフの設定(日本語でキャプションとラベルを設定)
plt.xlabel('Tの値')
plt.ylabel('確率密度')
plt.title(r'$T = \frac{1}{\gamma} \log X$ のヒストグラムと指数分布の比較')
plt.legend()
plt.show()
2022 Q4(3)
対数尤度関数を用いてパラメータの最尤推定量を求めました。
コード
数式を使った計算
# 2022 Q4(3) 2024.8.10
import sympy as sp
# シンボリック変数の定義
gamma = sp.Symbol('gamma', positive=True)
n = 10 # 具体的なサンプル数を設定
X = sp.symbols('X1:%d' % (n+1), positive=True) # X1, X2, ..., Xn を定義
# 尤度関数の定義
L_gamma = sp.prod((1/gamma) * X[i]**(-(1/gamma + 1)) for i in range(n))
# 対数尤度関数の定義
log_L_gamma = sp.log(L_gamma)
# 對数尤度関数を γ で微分
diff_log_L_gamma = sp.diff(log_L_gamma, gamma)
# 微分した結果を 0 に等しいとおいて解く
gamma_hat_eq = sp.Eq(diff_log_L_gamma, 0)
gamma_hat = sp.solve(gamma_hat_eq, gamma)
# 結果の表示
sp.pprint(gamma_hat[0], use_unicode=True)
シミュレーションによる計算
# 2022 Q4(3) 2024.8.10
import numpy as np
# 観測データ(例としてランダムに生成)
n = 1000 # データ点の数
gamma_true = 0.5 # 実際の γ (例として)
# CDFの逆関数
X = (np.random.uniform(size=n))**(-gamma_true)
# 最尤推定量 gamma_hat} の計算
log_X = np.log(X)
gamma_hat = np.mean(log_X)
print(f"観測(ランダム)データからの最尤推定量 gamma_hat: {gamma_hat}")
観測(ランダム)データからの最尤推定量 gamma_hat: 0.4984974482026361