You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

随机图边数的二项分布拟合性统计检验方法咨询

嗨,我来帮你搞定这个分布验证的问题~ 首先得明确:你用nx.gnp_random_graph(n,p)生成的随机图,它的边数理论上本来就服从二项分布——因为每对节点独立以概率p连边,总共有M = n*(n-1)//2个可能的边对,所以边数X ~ Binomial(M, p)。不过既然你想通过统计检验来验证数据是否符合这个分布,下面给你两种实用的方法:

一、为什么scipy.stats.binom_test不适合?

先解释下你遇到的困惑:binom_test是用来检验单个观测事件的发生次数是否符合二项分布的某个概率(比如抛硬币100次正面55次,检验是否是0.5的概率),它针对的是单个样本点,而你有10000个边数样本,要检验整体分布是否匹配,得用拟合优度检验,比如卡方检验或者Kolmogorov-Smirnov检验。

二、方法1:卡方拟合优度检验(最常用的离散分布验证方法)

这个方法的核心是对比观测频数和理论频数的差异,步骤如下:

步骤1:确定理论二项分布的参数

先算出总可能边数:

n = 你生成图时用的n值
p = 你生成图时用的p值
M = n * (n - 1) // 2  # 总可能的边对数

步骤2:准备观测频数和理论频数

从你的样本列表l中统计每个边数区间的观测次数,再计算对应区间的理论次数(基于二项分布的概率质量函数):

import numpy as np
from scipy.stats import binom, chisquare

# 统计观测频数(用auto自动选合适的bins,避免区间频数太少)
obs_counts, bins = np.histogram(l, bins='auto')

# 计算每个bin对应的理论频数
theoretical = []
for i in range(len(bins)-1):
    lower = bins[i]
    upper = bins[i+1]
    # 取区间内所有整数边数,计算它们的概率之和,再乘以样本量10000
    k_vals = np.arange(np.ceil(lower), np.floor(upper) + 1)
    prob_sum = binom.pmf(k_vals, M, p).sum()
    theoretical.append(prob_sum * 10000)

步骤3:修正区间(满足卡方检验的前提)

卡方检验要求每个区间的理论频数≥5,所以需要合并小频数的区间:

merged_obs = []
merged_theo = []
current_obs, current_theo = 0, 0

for o, t in zip(obs_counts, theoretical):
    current_obs += o
    current_theo += t
    if current_theo >= 5:
        merged_obs.append(current_obs)
        merged_theo.append(current_theo)
        current_obs, current_theo = 0, 0

# 把最后剩余的小频数加到最后一个区间
if current_obs > 0:
    merged_obs[-1] += current_obs
    merged_theo[-1] += current_theo

步骤4:执行检验并解读结果

chi2_stat, p_value = chisquare(merged_obs, f_exp=merged_theo)
print(f"卡方统计量: {chi2_stat:.2f}, p值: {p_value:.4f}")
  • 如果p值 > 0.05(常用的显著性水平),说明我们没有足够的证据拒绝“数据服从二项分布”的原假设,也就是支持你的观测符合二项分布的结论。

三、方法2:Kolmogorov-Smirnov检验(对比经验分布和理论分布)

KS检验通过对比经验分布函数(EDF)和理论分布函数(CDF)的差异来验证拟合度,适合大样本:

from scipy.stats import kstest

# 把观测数据排序
l_sorted = np.sort(l)

# 定义理论二项分布的CDF
def binom_cdf(x):
    return binom.cdf(x, M, p)

# 执行KS检验
ks_stat, ks_pvalue = kstest(l_sorted, binom_cdf)
print(f"KS统计量: {ks_stat:.4f}, p值: {ks_pvalue:.4f}")
  • 解读逻辑和卡方检验一致:p值大于0.05则支持分布拟合的结论。

额外小技巧:从数据中估计参数

如果你不想用预设的p,而是想从样本中估计二项分布的参数,可以用样本均值来反推:

estimated_p = np.mean(l) / M  # 二项分布的均值是M*p,所以p=均值/M

然后把上面代码中的p换成estimated_p再做检验即可。


内容的提问来源于stack exchange,提问作者Daniel Chepenko

火山引擎 最新活动