将连续变量下采样到均匀分布

问题描述

给定一个分布,比如说,一个高斯分布:

import pandas as pd
import numpy as np

gaussian_distribution = np.random.normal(0,1,10_000)

此示例如下所示:

enter image description here

我想要做的是重新采样这个分布以某种方式得到一个均匀的分布,所以:

Pr(X) = Pr(X+W)

我不担心以n < 10_000结尾,我只是想去除分布峰值。

我读了一些关于在这个分布上插值的内容,但我不知道这是如何工作的。

解决方法

我不确定您为什么要这样做,或者为什么保留原始样本而不是重新采样具有与直方图相对应的边界的均匀分布很重要。但这里有一种方法,正如您所要求的:获取足够粒度的直方图,并与 bin 高度成反比地重新采样落入每个 bin 中的点。您最终会从每个 bin 间隔中获取相同数量(大致)的点。

x = np.random.randn(10_000)
counts,bins = np.histogram(x,bins=10)
subsampled = []
for i in range(len(bins)-1):
  if i == len(bins)-2:
    # last bin is inclusive on both sides
    section = x[(x>=bins[i]) & (x<=bins[i+1])]
  else:
    section = x[(x>=bins[i]) & (x<bins[i+1])]
  sub_section = np.random.choice(section,np.amin(counts),replace=False)
  subsampled.extend(sub_section)

这种快速而肮脏的解决方案的局限性在于,最小的 bin 可以决定最终均匀分布的高度。因此,直方图中较少的 bin 不会使二次采样点变得均匀,但可以让您保留更多的点。你也可以剪掉尾巴来解决这个问题。

原文: histogram of x

子采样: histogram of subsampled

,

有一个函数叫做 np.random.uniform

import matplotlib.pyplot as plt
mu,sigma = 0,0.1 # mean and standard deviation
s = np.random.uniform(mu,sigma,1000)
count,bins,ignored = plt.hist(s,30,density=True)
plt.plot(bins,1/(sigma * np.sqrt(2 * np.pi)) *
np.exp( - (bins - mu)**2 / (2 * sigma**2) ),linewidth=2,color='r')
plt.show()

enter image description here