生成随机数以测试核密度估计

dee*_*ing 3 python math statistics machine-learning scipy

我有一个一维数据集,使用 statsmodels 和 scipy,在 python 中计算了核密度估计。

我想生成一组随机数,看看它们是否给我相同的分布。

到目前为止我能找到的解决方案是这样的:

绘制 0 到 1 之间的数字 x 并返回 cdf^{-1}(x),其中 cdf^{-1} 是 'f' 的逆累积分布函数。

问题是,使用 statsmodel 我能够找到逆累积分布,但以矩阵的形式。因此,将数字 x 与矩阵相乘并不能从计算的 KDE 分布中获得随机样本。

如何从给定的 KDE 函数或分布生成随机数?

编辑:这是一个代码示例:

def calcKDE(data):
    #Calculating KDE
    kde = sm.nonparametric.KDEUnivariate(data)
    kde.fit(kernel='gau', bw='silverman')
    return kde
def generateData(data, kde):
    inverse_cdf = kde.icdf // this is a method which takes no parameters, and so is kde.cdf
    randomSet = np.random.random(1) * inverse_cdf // inverse_cdf is taken as a matrix, will also add a loop here to return 1000 random values
    return randomSet
Run Code Online (Sandbox Code Playgroud)

sas*_*cha 5

逆变换采样方法如下所示:

from scipy.optimize import brentq
import statsmodels.api as sm
import numpy as np

# fit
kde = sm.nonparametric.KDEMultivariate()  # ... you already did this

# sample
u = np.random.random()

# 1-d root-finding
def func(x):
    return kde.cdf([x]) - u
sample_x = brentq(func, -99999999, 99999999)  # read brentq-docs about these constants
                                              # constants need to be sign-changing for the function
Run Code Online (Sandbox Code Playgroud)

我建议使用定制的示例函数来实现这个基于类的,以便更好地使用。

这种方法也非常通用,并且使用有关正在使用的内核的附加信息(无逆变换采样)有更快的方法。您应该通过谷歌搜索找到一些示例。

另一条评论:

我对 kde 工具从最好到最差的排序(我的意见):

  • statsmodels(不错的功能,如因变量;基于优化的 CV)
  • scikit-learn(易于使用;样本函数;基于网格和随机搜索的 CV)
  • scipy(不太喜欢它,但是基于 fft 的方法用于某些用途 -> 快速)