You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于scipy.stats.kstest的大样本均匀性测试及技术疑问

硬件熵生成样本均匀性评估问题

我正在研究硬件熵生成方案,采用12-16位分辨率的A2D采集环境传感器数据,假设采样值的低位包含足够噪声与真实熵,可作为PRNG的种子。我的思路是逐步截断采样值的高位,直到结果呈现均匀分布,再将这些低位“随机”位组合成更大的随机整数。

暂不讨论该方案的合理性,我当前的核心问题是评估截断后样本分布的均匀性。最初尝试Chi-Square(卡方)检验,但它不适用于大样本(每个传感器有10k样本);转而使用Kolmogorov-Smirnov Test(KS检验),通过将整数样本归一化到0-1区间来适配scipy.stats.kstest()的要求,但低比特宽度时样本仍高度离散(如2位截断仅含0.0、0.25、0.5、0.75)。

我编写了测试代码:

import random
import math
from scipy.stats import kstest 

if __name__ == '__main__':  
    samples = 1000
    random.seed(0)
    print('samples: {}'.format(samples))

    for bits in range(1, 16):
        max_val = (2 ** bits) - 1
        obs = []
        for i in range(samples):
            int_val = random.randint(0, max_val)
            obs.append(float(int_val) / max_val)
        stat, p = kstest(obs, 'uniform')
        print('{:3} bits : p={}'.format(bits, p))

测试结果显示低比特时检验效果差,比特数增加后p值波动大。我的疑问:

  1. 针对0到2^n的整数样本,尤其是1-4位低比特场景,是否有更优的均匀性评估方法?求可量化评估的Python代码。
  2. 我对KS检验的应用是否正确?为何比特数超过5-6位后p值仍大幅波动?

问题1:低比特整数样本的均匀性评估方案

对于1-4位的离散整数样本(取值范围小、类别少),卡方检验是更合适的选择——你之前对它的误解是错误的,卡方检验对大样本反而更可靠,只要每个类别的期望频数≥5即可(10k样本下,哪怕1位只有2个类别,每个类别的期望是5k,远大于5)。同时可以搭配频率偏差评估(计算每个类别实际频率与理论频率的最大偏差、平均偏差)作为直观的量化指标。

实现代码

import random
from scipy.stats import chisquare

def evaluate_uniformity(int_samples, num_bits):
    num_categories = 2 ** num_bits
    # 统计每个类别的出现次数
    counts = [0] * num_categories
    for val in int_samples:
        counts[val] += 1
    # 卡方检验
    chi_stat, chi_p = chisquare(counts)
    # 计算频率偏差
    expected_freq = len(int_samples) / num_categories
    freq_deviations = [abs(c - expected_freq) / expected_freq for c in counts]
    max_deviation = max(freq_deviations)
    avg_deviation = sum(freq_deviations) / num_categories
    return {
        "chi_p_value": chi_p,
        "max_freq_deviation": max_deviation,
        "avg_freq_deviation": avg_deviation
    }

if __name__ == '__main__':
    samples = 10000
    random.seed(0)
    print(f"samples: {samples}")
    
    for bits in range(1, 5):
        max_val = (2 ** bits) - 1
        int_samples = [random.randint(0, max_val) for _ in range(samples)]
        results = evaluate_uniformity(int_samples, bits)
        print(f"{bits:3} bits:")
        print(f"  卡方检验p值: {results['chi_p_value']:.6f}")
        print(f"  最大频率偏差: {results['max_freq_deviation']:.4f}")
        print(f"  平均频率偏差: {results['avg_freq_deviation']:.4f}")

结果说明

  • 卡方检验p值:若p>0.05,在95%置信度下无法拒绝“样本服从均匀分布”的假设;
  • 频率偏差:直接量化每个类别与理论均匀分布的差异,数值越小说明分布越均匀,适合快速直观判断。

问题2:KS检验的正确性与p值波动问题

你的KS检验应用是否正确?

不完全正确。KS检验原本是针对连续分布的检验,你把离散整数归一化到0-1区间后,样本仍然是离散的(比如2位只有4个取值),这会导致KS检验的统计量计算出现偏差——KS检验的核心是比较经验分布函数与理论分布函数的最大差异,离散样本的经验分布是阶梯状的,和连续均匀分布的拟合度天生就差,所以低比特时检验效果差是正常现象。

比特数增加后p值波动大的原因

  1. 样本量与离散程度的平衡:当比特数增加(比如5-6位,对应32/64个类别),样本离散程度降低,KS检验的统计量会更接近连续分布的情况,但此时样本量(1000)相对于类别数来说不算极大,每个类别的样本数波动会影响经验分布的阶梯形状,导致p值波动;
  2. 随机样本的固有方差:即使是完全均匀分布的随机样本,每次抽样得到的p值本身就会有波动,尤其是当样本量不足以完全抹平随机波动时,这种情况会更明显。如果将样本量增大到10k,p值的波动会显著减小。

修正建议

如果一定要用KS检验,建议针对离散均匀分布做对比,而非连续均匀分布。不过scipy的kstest没有直接支持离散分布的选项,更推荐优先用卡方检验处理离散样本场景。


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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 20:39:15