Python中加权样本np.std与理论标准差不符问题排查
混合指数分布抽样的标准差不匹配问题
我基于三个指数分布按指定权重抽样,验证抽样逻辑是否符合预期。代码验证显示,生成样本的均值和加权理论均值一致,但用np.std计算的标准差和理论计算的标准差不匹配。我觉得抽样逻辑没问题,不知道差异原因,附上代码求助:
import numpy as np from scipy.stats import expon np.random.seed(42) # 设置固定随机种子 # 定义三个指数分布 par_1 = 2.0 disbn_1 = expon(scale=par_1) disbn_2 = expon(scale=1.0) disbn_3 = expon(scale=0.5) # 设置抽样权重 w_1, w_2, w_3 = 0.4, 0.3, 0.3 weights = np.array([w_1, w_2, w_3]) # 生成样本数量 num_samples = 5000000 # 按权重选择分布并生成样本 selected_distributions = [disbn_1, disbn_2, disbn_3] random_indices = np.random.choice(len(weights), size=num_samples, p=weights) selected_samples = np.choose(random_indices, [dist.rvs(size=num_samples) for dist in selected_distributions]) # 计算生成样本的统计量 mean_generated = np.mean(selected_samples) std_generated = np.std(selected_samples, ddof=0) # 计算理论均值和标准差(原错误逻辑) expected_mean = np.sum(weights * np.array([dist.mean() for dist in selected_distributions])) expected_std = np.sqrt(np.sum(weights * np.array([dist.var() for dist in selected_distributions]))) # 输出结果 print(f"生成样本均值: {mean_generated:.6f}") print(f"理论均值: {expected_mean:.6f}") print() print(f"生成样本标准差: {std_generated:.6f}") print(f"理论标准差(原计算): {expected_std:.6f}")
问题原因与修正方案
问题出在混合分布的方差计算逻辑错误:你当前只计算了各子分布方差的加权和,但混合分布的方差需要同时考虑子分布内部的方差和子分布均值与整体均值的差异(组间方差)。
正确的混合分布方差公式为:
$$\text{Var}(X) = \sum_{i=1}^n w_i \left( \text{Var}(X_i) + (\mu_i - \mu)^2 \right)$$
其中:
- $w_i$是第$i$个分布的权重
- $\text{Var}(X_i)$是第$i$个分布的方差
- $\mu_i$是第$i$个分布的均值
- $\mu$是混合分布的整体均值(即你已经正确计算的
expected_mean)
你的代码漏掉了$\sum w_i (\mu_i - \mu)^2$这部分,导致理论方差被低估,进而标准差不匹配。
修正后的计算代码
替换原代码中expected_std的计算部分:
# 计算各子分布的均值和方差数组 sub_means = np.array([dist.mean() for dist in selected_distributions]) sub_vars = np.array([dist.var() for dist in selected_distributions]) # 计算正确的混合分布方差与标准差 expected_var = np.sum(weights * (sub_vars + (sub_means - expected_mean)**2)) expected_std = np.sqrt(expected_var)
替换后重新运行代码,生成样本的标准差会和理论值完全匹配。
内容的提问来源于stack exchange,提问作者user144464
相关产品推荐
相关产品推荐

