【问题标题】:Draw samples from KDE based on empirical data (to calculate entropy)根据经验数据从 KDE 中抽取样本(计算熵)
【发布时间】:2020-02-29 03:49:52
【问题描述】:

我正在尝试计算两个数值数组之间的熵 (scipy.stats.entropy),以量化它们基础分布的差异。

由于计算熵需要两个输入具有相同的形状,我想使用 KDE 估计较小列表的分布,以从中采样新数据。

使用 0 到 1e-02 之间的输入我无法从拟合的 KDE 中得出合理的数字?

emp_values = np.array([0.000618, 0.000425, 0.000597, 0.000528, 0.000393, 0.000721,
   0.000674, 0.000703, 0.000632, 0.000383, 0.000466, 0.000919,
   0.001419, 0.00063 , 0.000433, 0.000516, 0.001419, 0.000655,
   0.000674, 0.000676, 0.000694, 0.000396, 0.000688, 0.00061 ,
   0.000687, 0.000633, 0.000601, 0.00061 , 0.000747, 0.000356,
   0.000824, 0.000931, 0.000691, 0.000907, 0.000553, 0.000748,
   0.000828, 0.000907, 0.000457, 0.000494])
kde_emp = KernelDensity().fit(emp_values.reshape(-1, 1))

使用KDE.sample 绘制随机数会产生完全超出范围的值?

kde_emp.sample(10)
array([[-3.0811253 ],
   [ 1.24822136],
   [ 0.07815318],
   [ 0.01609681],
   [-0.59676707],
   [-0.89988083],
   [-0.59071966],
   [-0.72741754],
   [ 0.82296101],
   [ 0.08329316]])

那么从拟合的 PDF 中抽取 10.000 个随机样本的合适方法是什么?

【问题讨论】:

    标签: python scikit-learn kernel-density probability-density


    【解决方案1】:

    KDE 的bandwidth 默认为1,太大了。尝试使用类似的东西:

    kde_emp = KernelDensity(bandwidth=5e-5)
    kde_emp.fit(emp_values.reshape(-1, 1))
    

    将带宽设置为对该数据更合理的值。 wikipedia page 谈论带宽意味着什么

    我不太了解 scikit-learn,但是 there doesn't seem to be 有任何可以在其中自动估算此值的好方法。也就是说,您必须自己编写自己的估算器(大约 5 到 10 行代码)

    也就是说,如果您只是在使用高斯 KDE,那么 SciPy 可以为您估算带宽。见scipy.stats.gaussian_kde。请注意,scipy 估计器假定数据是单峰的(大多数情况下),而您的数据肯定不是,因此您需要更小的带宽值

    【讨论】:

    • 使用例如带宽1e-6 确实有帮助,并产生了预期的结果。谢谢!
    • 我想到你可能只是从值中采样(带替换)。请注意,您最好使用可以处理不同数据大小的度量。任何像这样的大小调整都会破坏方差估计
    猜你喜欢
    • 1970-01-01
    • 2013-02-08
    • 2019-11-21
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 2017-07-21
    • 2020-05-26
    相关资源
    最近更新 更多