如何将数据转换为均匀分布(均匀百分位数)?

信息处理 统计数据
2022-02-14 17:01:07

给定数据点列表(在 [0,1] 范围内标准化),我绘制值的直方图并计算百分位数(显示为 x 刻度)。

数据的价值分布

如何找到数据值的转换,使直方图大致一致。反过来,这会使百分位值也均匀分布。

2个回答

您好:您可以计算数据的经验累积分布。我的意思是,给定样本中的一些观察值,通过计算小于 x_{i} 的观察值的比例(即百分位数)来计算 ( X然后,对所有的累积分布xiP(X<xi)xixixi

然后,是一致的P(X<x)x

实际上,您似乎已经这样做了,但是百分位值应该在垂直轴上,数据的值应该在 x 轴上。

请注意,此 PDF 的第 14 页比我更清楚地解释了这个概念。


示例实现

下面是一个快速而肮脏的尝试来说明这个答案。下图显示了高斯的原始直方图,该数据的经验累积分布函数,然后是转换数据的直方图。

示例实现图

下面的R代码

par(mfrow=c(3,1))
# First, generate some Gaussian numbers.
gaussian <- rnorm(1000,0.0,0.05)
gh <- hist(gaussian, breaks=1000)

empirical_cumulative_distribution <- cumsum(gh$counts)/1000

plot(gh$mids, empirical_cumulative_distribution)


uniformize <- function(x) {
  ans_x <- x
  for (idx in seq(1,length(x))){
    max_idx <- max(which(gh$mids < x[idx]))
    ans_x[idx] <- empirical_cumulative_distribution[max_idx]
  }
  return(ans_x)
}

uniform2 <- uniformize(gaussian )
hist(uniform2, breaks=100)
par(mfrow=c(1,1))

蟒蛇版本:

将 matplotlib.pyplot 导入为 plt
将 numpy 导入为 np
定义统一(x,nbins=1000):
    其中 = lambda lst:list(np.where(lst)[0])

    gh = np.histogram(x,bins=nbins)
    
    经验累积分布 = np.cumsum(gh[0])/nbins
    
    ans_x = x
    对于范围内的 idx(len(x)):
        max_idx = max(其中(gh[1]<x[idx])+[0])
        ans_x[idx] = 经验累积分布[max_idx]
    
    返回 ans_x

如果 __name__ == '__main__':
    #要使用的垃圾箱数
    麻木 = 1000
    
    # 要转换的分布
    dist_transform = np.random.normal(3,5,numb)
    
    # 绘制原始分布和 CDF
    无花果,(ax1,ax2,x3)= plt.subplots(3,1)
    n,bins,patches = ax1.hist(dist_transform,bins=numb)
    ax2.plot(bins[1:],np.cumsum(n)/numb)

    uniform_dist = 均匀化(dist_transform)   
    x3.hist(uniform_dist,bins = 100,alpha=0.5)