小样本大概率事件的正确处理方式 - 1. 概率的含义和误差产生的原因

博客探讨了在游戏中处理小样本概率事件的问题,指出小样本统计可能会与期望概率相差较大。提出通过限制触发次数为概率乘以样本数,并加入波动值进行‘可控随机化’的解决方案,以改善概率分布并使其更接近期望值。文章还强调了此方法适用于概率性事件的概率约束,但实际应用需谨慎。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

在很多时候——特别是在游戏中——我们经常需要对某一事件进行随机触发处理,例如:攻击有几率触发暴击,怪物有几率掉出装备,武器有几率强化失败。通常我们的做法就是,从0~1中取随机数,然后判断是否大于给出的几率(实际上大多数时候为了计算效率会用0~100的随机整数)。

当我们从整个游戏世界上去统计这个随机事件时,无论这个概率是小概率还是大概率,得到的结果与我们的期望都不会有很大的差别。但是从单一玩家的角度,或者是某一短时间段的角度去统计这个事件时,对于结果的直观感受会有很大的波动性——换句话说,得到的实际概率往往并不是我们所想要的概率。

实际上从概率论的角度能给出非常合理的解释,期望方差标准差啥的一套公式概念拿出来,似乎就“原来如此”了。但是我们要的是直观的解释和合理的算法,而不是一堆晦涩难懂的公式概念。

问题分析

举个栗子:
玩家在攻击时有30%的几率触发暴击。从游戏世界中统计一个大样本,得到的触发概率基本不会与预期有很大的差别。但是对于一个玩家十次攻击的结果来说呢?
这里写图片描述
从上图模拟能很明显看到,对于一个小样本模拟,其概率与我们的期望相差甚远。你完全能够脑补出玩家在心中反复念叨的“我擦,这人品”。事实上,0/10或者10/10这样的样本,在独立随机事件中是完全合乎逻辑的。初中课本上就出现过的概念:对于独立随机事件,任何一次事件都不会影响到另一次事件的发生。

煎蛋一菊花的解释就是:概率值的本质上是对一个样本中某个特定事件的统计计算结果,而并非对某一事件是否发生的约束条件。样本和事件是前提,概率才是结果,反过来从某一统计概率上去预测样本事件的发生情况,并不能得到我们所想要的结果(所以彩票预测和股票周四会涨啥的完全就是扯淡)。

从心理感官方面,如果是一个概率非常小的事件,我们并不会从小样本上去分析,千分之一的概率在一百次中出现一次以上的概率太小,而在一千次中没有一次出现,或者出现了两次,看起来都并没有什么奇怪。所以我们需要解决的,是“小样本大概率事件”在程序中的逻辑优化。

解决方案

首先,我们有一个随机概率P,要让其在样本数量S中体现出来,我们必须将事件触发的次数限制为P*S。也就是说,我们需要将S次样本大小为1的发生概率为P的独立重复随机事件,变成一次样本大小为S的,触发次数为P*S的事件,从而把该样本的统计概率约束在P

但是,作为一个合理的随机事件,“随机”是必须存在一定概率波动的,只是独立重复随机事件的“随机”并不可控,所以我们无法将波动控制在我们的可接受范围内。而对固定次数的事件做优化,给定一个波动值D,将触发次数变成P*S ±D中的随机数,那么就能够对该事件进行“可控随机化”了。

需求分析

初始化参数

  1. 样本数量quantity;
  2. 期望次数expectation;
  3. 波动大小deviation;

公共接口

  1. bool GetNext():下次事件是否触发;
  2. void Reset():重新计算随机事件;
  3. void Reset(int deviation):以给定的波动值重新计算随机事件;

逻辑流程

  1. 以expectation和deviation得出一个随机数作为样本中触发事件数量count;
  2. 从0到quantity中取count个随机数保存到selection[];
  3. 每次用GetNext()取结果时,样本编号加一(如果超过样本数量,则重新计算),判断该样本编号是否存在于selection[]中,存在则返回true;

代码编写(可略过不看)

逻辑优化:对于判断当前样本是否为触发点,即样本编号是否在selection中,可以对selection进行排序后进行判断;

<think>我们被要求判断一个矩阵是否是从标准正态分布(均值为0,标准差为1)中随机采样生成的。 通常,我们可以通过统计检验来验证。主要步骤包括: 1. 检验矩阵的每个元素是否独立同分布(i.i.d.)于标准正态分布。 2. 使用正态性检验方法(如Shapiro-Wilk检验、Kolmogorov-Smirnov检验等)对矩阵的展平数据进行检验。 3. 检查样本的均值标准差是否接近01(由于抽样误差,允许有一定偏差,但需通过统计检验判断是否显著偏离)。 然而,由于矩阵可能很,我们通常将矩阵展平为一维数组,然后进行正态性检验。 具体方法: 方法一:使用描述性统计量 - 计算矩阵的均值标准差。如果矩阵是从标准正态分布中生成的,样本均值应接近0,样本标准差应接近1- 但注意,由于抽样误差,即使是从标准正态分布中抽取的样本,样本均值标准差也不会完全等于01,因此需要判断其偏离程度是否在可接受的范围内(例如,通过计算标准误差,或者使用置信区间)。 方法二:使用正态性检验 - 常用的正态性检验有: Shapiro-Wilk检验(适用于中小样本,如样本量小于5000) Kolmogorov-Smirnov检验(适用于样本) Anderson-Darling检验 D'Agostino's K-squared检验 - 这些检验的原假设是样本来自正态分布。如果p值于显著性水平(如0.05),则不能拒绝原假设,即认为样本来自正态分布。 方法三:可视化方法(辅助) - 绘制Q-Q图(分位数-分位数图):如果点近似落在一条直线上,则表明数据服从正态分布。 - 绘制直方图并叠加标准正态分布密度曲线,观察形状。 注意:由于我们要求的是标准正态分布(均值为0,标准差为1),因此在检验时,如果使用Kolmogorov-Smirnov检验,需要指定均值标准差为01(即检验是否服从标准正态分布)。而其他检验(如Shapiro-Wilk)通常检验的是数据是否服从正态分布(不指定参数),所以需要先标准化数据(减去样本均值,除以样本标准差)再检验?但是注意:我们是要检验它是否来自标准正态分布,而不是一般的正态分布。因此,在KS检验中,我们可以指定分布参数,而Shapiro-Wilk检验则是对复合假设(不指定参数)的检验。所以,如果我们使用Shapiro-Wilk检验,我们需要先标准化数据(因为Shapiro-Wilk检验的是数据是否来自正态分布,而不指定均值方差),然后检验标准化后的数据是否服从标准正态分布?实际上,标准化后的数据一定是均值为0,方差为1的,但分布形状不一定正态。所以,我们其实可以直接对原始数据做检验,但需要同时检验均值方差吗?或者,我们可以将问题拆分为: - 检验数据是否来自正态分布(不指定参数) - 然后检验均值标准差是否为01(通过t检验卡方检验) 然而,更直接的方法是使用KS检验,并指定均值为0,标准差为1(即标准正态分布)。 具体步骤(以Python为例): 步骤1:将矩阵展平为一维数组。 步骤2:进行正态性检验(这里以KS检验为例,因为可以指定参数): 使用scipy.stats中的kstest,设置参数cdf='norm',并且指定args=(0,1)(均值为0,标准差为1)。 注意:KS检验要求连续分布,且对样本小敏感。 步骤3:同时,我们可以计算样本均值标准差,看它们是否接近01(但注意,即使总体是标准正态分布,样本均值标准差也会有波动,因此需要结合统计检验)。 但是,KS检验的原假设是:样本来自指定的分布(这里为标准正态分布)。如果p值小于0.05,则拒绝原假设,认为不是来自标准正态分布。 另外,由于KS检验在样本下可能过于敏感(即使很小的偏离也会拒绝原假设),因此可以结合其他方法。 因此,综合方法: 1. 计算样本均值标准差,并检查它们是否在01附近(例如,均值的绝对值小于0.1,标准差在0.9到1.1之间?但这取决于样本量,样本量越,要求越严格)。 2. 进行KS检验(或Shapiro-Wilk检验,但注意Shapiro-Wilk检验不能指定参数,所以需要先标准化?不对,如果我们使用Shapiro-Wilk检验,它检验的是数据是否来自正态分布(不指定均值方差),所以如果我们想检验是否来自标准正态分布,需要两步: a. 检验数据是否来自正态分布(Shapiro-Wilk检验) b. 检验数据的均值是否为0(t检验)方差是否为1(卡方检验)? 但是,如果数据来自正态分布,那么标准化后就是标准正态分布,但这里我们要求的是原始数据就是标准正态分布,所以不能标准化。因此,我们可以: - 用Shapiro-Wilk检验正态性(不指定参数),如果拒绝,则不是标准正态。 - 然后,再检验均值标准差:用t检验检验均值是否为0(单样本t检验),用卡方检验检验方差是否为1(单样本方差检验)?但注意,这两个检验是独立的,而且需要满足正态性(第一步已经检验了)。 然而,更简单的是使用KS检验直接检验标准正态分布。 因此,我们推荐使用KS检验(如果样本量不是特别)或者Lilliefors检验(专门为正态分布设计的KS检验,但scipy中没有直接提供)?不过,KS检验在指定参数的情况下,对正态性检验也是有效的。 代码示例(Python): 假设我们有一个矩阵(或二维数组)`matrix`,我们将其展平为一维数组。 ```python import numpy as np from scipy import stats # 假设matrix是给定的矩阵 data = matrix.flatten() # 展平为一维数组 # 方法1:KS检验(检验是否服从标准正态分布) ks_statistic, p_value = stats.kstest(data, 'norm', args=(0, 1)) # 注意:args=(0,1)表示均值为0,标准差为1 # 设置显著性水平 alpha = 0.05 if p_value > alpha: print("KS检验:不能拒绝原假设,数据服从标准正态分布(均值为0,标准差为1)") else: print("KS检验:拒绝原假设,数据不服从标准正态分布(均值为0,标准差为1)") # 方法2:检查均值标准差 mean = np.mean(data) std = np.std(data, ddof=1) # 样本标准差(分母为n-1) print(f"样本均值: {mean:.6f}, 样本标准差: {std:.6f}") # 根据样本量,我们可以计算均值标准差的置信区间,或者进行假设检验(t检验方差检验) # 单样本t检验(检验均值是否为0) t_stat, p_val_mean = stats.ttest_1samp(data, 0) if p_val_mean > alpha: print("t检验:不能拒绝均值等于0的假设") else: print("t检验:拒绝均值等于0的假设") # 检验方差是否为1:使用卡方检验(注意:卡方检验要求数据正态,我们已经做了KS检验,或者这里用前面的正态性检验结果) # 卡方检验统计量:chi_square = (n-1)*s^2 / 1,服从自由度为n-1的卡方分布 n = len(data) chi_square = (n - 1) * std**2 # 计算双侧检验的p值(因为我们要检验方差是否等于1,是双侧检验) chi2_dist = stats.chi2(df=n-1) # 计算p值:取两端的尾部概率 p_val_var = 2 * min(chi2_dist.cdf(chi_square), 1 - chi2_dist.cdf(chi_square)) if p_val_var > alpha: print("方差检验:不能拒绝方差等于1的假设") else: print("方差检验:拒绝方差等于1的假设") # 综合判断:如果KS检验通过,且均值方差的检验也通过,则更有把握。 ``` 但是,注意:KS检验已经检验了分布的形状参数,所以理论上如果KS检验通过,则均值方差也应该是符合的。但是,KS检验对分布的形状敏感,而均值方差的检验是单独的。因此,我们可以单独使用KS检验,或者结合均值方差的检验。 另外,由于多重检验问题,我们可能会增加犯第一类错误的概率。因此,如果使用多个检验,需要调整显著性水平(例如Bonferroni校正)。 方法四:使用Anderson-Darling检验(可以指定正态分布,但需要自己设定参数?在scipy中,`anderson`函数不能指定均值方差,只能检验标准化的正态分布?所以需要先标准化?但标准化后,我们改变了数据,所以不适合。因此,我们使用KS检验更直接。 总结步骤: 1. 展平矩阵。 2. 使用KS检验(指定均值为0,标准差为1)检验数据是否来自标准正态分布。 3. 同时,可以检查样本均值标准差,并做假设检验(t检验卡方检验)作为辅助。 注意:如果样本量很,KS检验可能会过于敏感(即微小的偏离也会导致拒绝原假设),此时可以结合Q-Q图进行主观判断。 因此,在实际操作中,我们通常结合统计检验描述性统计量。 另外,如果矩阵是由某个随机数生成器产生的,我们也可以考虑检验随机数生成器的性质(但这超出了问题范围)。 根据搜索,我们还可以使用其他方法,但以上是主流方法。 注意:在生成随机矩阵时,我们通常使用伪随机数生成器,所以理论上,如果生成器是正确的,那么生成的矩阵应该符合要求。但这里我们是要检验一个给定的矩阵是否符合。 因此,回答用户问题: 判断给定的矩阵是否按照标准正态分布随机采样生成,可以通过以下步骤: 1. 将矩阵展平为一维数组。 2. 使用Kolmogorov-Smirnov检验(KS检验)检验数据是否服从均值为0、标准差为1的标准正态分布。 3. 计算样本均值标准差,并与01进行比较(考虑抽样误差,进行假设检验)。 4. 结合可视化方法(如Q-Q图)进行辅助判断。 注意:KS检验对样本量敏感,样本下可能过于严格。因此,当样本量很时,可以主要关注Q-Q图是否近似在一条直线上,以及样本均值标准差与01的偏离程度(例如,均值的绝对值小于0.05,标准差在0.95到1.05之间等,具体阈值取决于应用场景)。 下面给出一个完整的代码示例(包括检验绘图):</think>### 判断矩阵是否符合标准高斯分布(均值为0、标准差为1) #### 1. 描述性统计检验 计算矩阵的样本均值 ($\bar{x}$) 样本标准差 ($s$): $$\bar{x} = \frac{1}{n}\sum_{i=1}^{n} x_i, \quad s = \sqrt{\frac{1}{n-1}\sum_{i=1}^{n}(x_i - \bar{x})^2}$$ 期望值应接近01(允许抽样误差): ```python import numpy as np def check_descriptive_stats(matrix): flat_data = matrix.flatten() mean = np.mean(flat_data) std = np.std(flat_data, ddof=1) # 样本标准差 return abs(mean) < 0.1 and 0.9 < std < 1.1 # 阈值可调整 ``` #### 2. 正态性假设检验 使用统计检验验证分布形态: - **Kolmogorov-Smirnov 检验**:比较经验分布与标准正态分布 - **Shapiro-Wilk 检验**:适合中小样本量(n < 5000) ```python from scipy import stats def normality_tests(matrix): flat_data = matrix.flatten() # KS检验(指定标准正态参数) ks_stat, ks_p = stats.kstest(flat_data, 'norm', args=(0, 1)) # Shapiro-Wilk检验 sw_stat, sw_p = stats.shapiro(flat_data) return ks_p > 0.05 and sw_p > 0.05 # 不拒绝原假设(正态分布) ``` #### 3. 高阶矩分析 计算偏度 ($\gamma_1$) 峰度 ($\gamma_2$): $$\gamma_1 = \frac{\mu_3}{\sigma^3}, \quad \gamma_2 = \frac{\mu_4}{\sigma^4} - 3$$ 标准正态分布应满足 $\gamma_1 \approx 0$ $\gamma_2 \approx 0$ ```python def check_moments(matrix): flat_data = matrix.flatten() skew = stats.skew(flat_data) kurtosis = stats.kurtosis(flat_data, fisher=True) # Fisher定义(正态峰度=0) return abs(skew) < 0.2 and abs(kurtosis) < 0.5 # 阈值可调整 ``` #### 4. 可视化诊断 使用图形工具辅助判断: - **Q-Q图**:数据分位数 vs 标准正态分位数 - **直方图**:叠加标准正态密度曲线 ```python import matplotlib.pyplot as plt import seaborn as sns def plot_diagnostics(matrix): flat_data = matrix.flatten() plt.figure(figsize=(12, 5)) # Q-Q图 plt.subplot(121) stats.probplot(flat_data, dist="norm", plot=plt) plt.title("Q-Q Plot") # 直方图+KDE plt.subplot(122) sns.histplot(flat_data, kde=True, stat="density") x = np.linspace(-4, 4, 100) plt.plot(x, stats.norm.pdf(x), 'r-', lw=2) plt.title("Histogram with PDF") plt.tight_layout() plt.show() ``` #### 5. 随机性检验(可选) 验证数据独立性: - **Ljung-Box 检验**:检测自相关性 - **Runs 检验**:检测序列模式 ```python from statsmodels.stats.diagnostic import acorr_ljungbox def check_randomness(matrix): flat_data = matrix.flatten() lb_test = acorr_ljungbox(flat_data, lags=[10]) return lb_test.iloc[0].lb_pvalue > 0.05 # 不拒绝独立假设 ``` #### 综合判断流程 1. 执行描述性统计检验(均值标准差) 2. 进行至少一种正态性假设检验(KS或Shapiro-Wilk) 3. 检查高阶矩(偏度峰度) 4. 可视化验证(Q-Q图直方图) 5. (可选)添加随机性检验 当所有检验均通过时(p>0.05),可认为矩阵符合标准正态分布
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值