使用Z-Score筛选异常值时,均匀分布样本落在±1区间的占比未达预期的问题咨询
Z-Score筛选异常值时,均匀分布样本落在±1区间的占比未达预期的问题咨询
嗨,我太懂你这种疑惑了——本来想着±1个Z-score区间应该包含大约68%的样本,结果跑出来只有57%左右,换谁都会挠头!咱们来一步步捋清楚问题出在哪:
首先,你记的「±1个标准差(Z-score)包含68%样本」的规律,是专门针对正态(高斯)分布的经典68-95-99.7法则,但你现在用的样本numpy.array(range(1, 1000))是个均匀分布的数据集啊!这两种分布的Z-score区间占比完全不是一回事。
咱们来手动算一遍均匀分布的情况:
- 你的样本是1到999的整数,属于均匀分布U(1,999)
- 均匀分布的均值μ=(1+999)/2=500
- 均匀分布的标准差σ=(b-a)/√12=(999-1)/√12≈288.1
- 当Z-score=1时,对应x=μ+σ≈788.1;Z-score=-1时,对应x=μ-σ≈211.9
- 那1到999里落在212到788之间的数有788-212+1=577个,577/999≈0.577,和你代码跑出来的结果完全吻合!
再说说你的代码:其实逻辑是完全没问题的,不管是用scipy.stats.zscore还是自己用numpy算均值和标准差,结果都一致,这部分你没做错。如果想验证68%的预期,你得换成正态分布的样本,比如生成足够多的正态分布数据:
import numpy from scipy import stats # 生成正态分布样本,均值500,标准差和之前的均匀分布一致 arr = numpy.random.normal(loc=500, scale=288.1, size=10000) col_z_score = stats.zscore(arr) print((abs(col_z_score) < 1).sum() / len(col_z_score))
跑这个代码,结果就会非常接近68%了。
另外给你个小建议:判断Z-score是否在±1之间,用abs(col_z_score) < 1会比两次逻辑判断简洁很多,结果是一样的~
备注:内容来源于stack exchange,提问作者mayen
相关产品推荐
相关产品推荐

