用 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()

留言

這個網誌中的熱門文章

可轉移性、普遍性、代表性和外部有效性

頻率學派 vs 貝氏學派

貝氏分析計算器