用 Python 模擬贏家的詛咒
# 用 Python 模擬贏家的詛咒
# 贏家的詛咒:低訊號雜訊比、低效果量、低統計檢定力、小樣本的研究容易高估效果量
# 訊號雜訊比: 實際效果量/標準誤
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import ttest_ind
# 模擬設定
np.random.seed(0)
num_experiments = 1000 # 實驗次數
sample_size = 30 # 樣本大小
true_effect_size = 0.3 # 實際效果量(小)
signal_to_noise_ratio = 0.5 # 訊號雜訊比(低)
# 模擬實驗的函數
def simulate_experiment():
# 為控制組和治療組生成數據
control = np.random.normal(0, 1/signal_to_noise_ratio, sample_size)
treatment = np.random.normal(true_effect_size, 1/signal_to_noise_ratio, sample_size)
# 進行t檢定
t_stat, p_val = ttest_ind(treatment, control)
return p_val, np.mean(treatment) - np.mean(control)
# 運行模擬
p_values = []
effect_sizes = []
for _ in range(num_experiments):
p_val, effect_size = simulate_experiment()
p_values.append(p_val)
effect_sizes.append(effect_size)
# 只包括統計上顯著的結果過濾
significant_effect_sizes = [effect_sizes[i] for i in range(num_experiments) if p_values[i] < 0.05]
# 顯著結果的百分比
percentage_significant = (len(significant_effect_sizes) / num_experiments) * 100
print(f"Percentage of significant effects: {percentage_significant:.2f}%")
# 效果量的分佈圖
plt.figure(figsize=(10, 6))
sns.histplot(effect_sizes, color='skyblue', label='All effect sizes')
sns.histplot(significant_effect_sizes, color='salmon', label='Significant effect sized')
plt.axvline(x=true_effect_size, color='green', linestyle='--', label='True effect size')
plt.title('Distribution of effect sizes with winner’s curse')
plt.xlabel('Effect size')
plt.ylabel('Frequency')
plt.legend()
plt.show()
留言
張貼留言