为概率分布的数据表示寻求建议
Seeking suggestions for data representation of a probability distribution
我正在寻找一种优雅高效的方法来表示和存储由显式采样构建的任意概率分布。
该分布预计具有以下属性:
- 样本是浮点值,但原则上可以认为其分辨率低至.001
- 样本取自区间
[-4000; 4000]
- 然而,对于任意两个样本
a
、b
、|a - b| < 40
- 90%的时间,它会有一个尖锐的峰值或几个尖锐的峰值相互靠近
- 在10%的时间内,它将具有宽度为0.5至5的不均匀平台的峰值
通常的表示——直方图阵列——是不可取的,主要是因为量化/分辨率和空间之间的权衡。我想一定有一种表示方法,可以根据局部"复杂性"自适应地改变bin大小。
空间是令人担忧的,因为更高级别的网格状数据结构将包含数千个单元,每个单元至少包含一个这样的概率表示。磁盘或网络传输的简单串行化是可取的,但效率不是首要任务。
如有任何帮助,我们将不胜感激。
有趣的问题。这里有一个建议,根据你的数学倾向,它可能很难实现。
请注意,我用空间换取速度,因为我的建议可能在计算上相当繁重(但这要根据实际数据进行测试)。
首先,使用功能方法。概率分布是一种概率度量:
struct Distribution
{
virtual ~Distribution() {};
virtual double integrate(std::function<double(double)>) = 0;
};
这样,你就可以从你生产的样本中提取出来,因为你不想存储它们。说服自己,你可以用"集成"方法做任何事情。
当然,对于显式样本,您可以执行类似的操作
struct SampledDistribution
{
double integrate(std::function<double(double)> f)
{
double acc = 0;
for (double x: samples) acc += f(samples);
return acc / samples.size();
}
std::deque<double> samples;
};
现在,存储部分:
通常的表示——直方图数组——主要是不可取的因为量化/分辨率和空间之间的权衡。我想象一下,必须有一种自适应的表示方法根据当地的"复杂性"改变垃圾箱的大小。
传统的方法是小波。通过调用integrate
生成系数,可以对其进行序列化。如果系数产生的积分估计器的方差很高,则丢弃系数。
然后,为了反序列化,您生成一个Distribution
对象,其integrate
方法对小波执行积分。积分可以使用您喜欢的求积方法进行。我在这里故意含糊其辞,因为实际实现取决于您选择的小波族(平滑、紧凑支持、正交与否等)。无论如何,你都需要深入垃圾堆中了解细节。
这里的重点是,你通常只需要很少的小波来表示一个具有很少特征的光滑函数(比如说几个峰值,以及其他规则形状),而不是更"规则"的有限元(直方图是一种特殊的有限元表示)。小波表示使自己适应变换体的特征,无论它们的位置或大小如何。此外,您还可以决定保留多少系数,从而控制压缩比。
此外,0.001的数字是一个相当高的数字:我怀疑你只需要几个系数
权衡在于使用哪种小波类:非常平滑的分布可能会用平滑的小波很好地表示,但紧凑支持的小波可能更容易集成,等等。实验。请注意,这里不需要"小波变换"包:只需要小波函数的显式表示和求积例程(尝试高斯XXX程序进行重建,或其他高阶程序)。
我更喜欢在傅立叶域中定义的小波(如Lemarie小波),因为它们在傅立叶空间中的值和零导数是已知的,这允许你对分布施加约束:概率测度必须积分为1,你可能碰巧事先知道期望值或方差。
此外,您可能希望更改变量以仅处理函数,例如[0,1]。关于区间上的小波,有大量的文献记载。
我强烈建议查看SciPy中可用的所有分发模型。他们最重视这个问题,我提出的任何试图解决分辨率粒度问题的规范算法都将是他们至少间接考虑过的。
不过,正如这里所提到的,用于乘法确定数据的八叉树似乎是您想要的数据结构的正确表示。您的目标是将扰动以不同的固定粒度存储在数据集中,而不是使用包含受死记硬背箱约束的数据的平面直方图。这与用于JPEG压缩的算法最为相似,只是希望以某种粒度和复杂性从分布中提取样本。
为了创建分类算法或二分器来填充数据结构,我强烈建议查看JPEG 2000等分解算法,以确定数据中扰动的形状和复杂性。其他方法(例如ID3和C4.5)也可能是合适的,但我觉得简单的矢量化分解可能适用于您的目的。
而且,值得一提的是,如果你在这个空间里找到一个更适用的算法,我会非常感兴趣。我直接与对数据中的多尺度关系感兴趣的研究人员合作,所以如果你偶然发现了更有效的东西,请告诉我们!
这个怎么样:
我假设我们从相当于直方图的数据开始,即与之相关的样本数量的区间列表
现在,让我们从一个包含所有样本的桶的琐碎直方图开始,为它构建一个近似值。
对于近似中的所有桶,请考虑将其在中间拆分为两个桶,但只有实际拆分桶才能在近似中产生最佳改进。
重复直到达到期望的近似值或获得可接受桶的最大值。
因此,您需要的是一种方法来确定要拆分的最佳存储桶。我想说,与原始铲斗的一半相比,新铲斗的最大偏差可能会起作用。
你还需要一些准则何时停止。
我认为这实际上与1D中的八叉树非常相似。您可能会在那里寻找高效的实现。
为了实际存储近似值,只需存储一个具有bucket边界的数组和另一个具有每个bucket内容的数组。或者一个大小为其两倍的数组,其中桶边界和内容值交替。
存储n个分位数。它们将自适应地聚集在模式周围。
设n是2的幂,则密度(和累积概率)查找可以通过递归地将分位数存储为中值和"子中值"的二叉树来限制为O(log(n))。
- C++射线示踪剂ppm表示没有足够的数据来显示图像
- 如何解析表示树状数据结构的字符串
- C++ 表示 NIC 收到数据时没有收到任何内容
- 当接收到不明确的规范时,表示图的邻接列表的数据结构
- pybind11:用可选数据表示并集
- c++在循环中定义一组概率分布
- 在C++中将数据结构表示为字符串的首选方法是什么?
- 表示命令数据包格式的数据结构
- 定义概率分布的成本是否很高
- 模拟退火,如何规范化概率分布
- 如何有效地处理不同的概率分布函数
- C++ - 临界值概率分布
- 为概率分布的数据表示寻求建议
- 多个向量的数据表示
- 将c_string转换为字符串再转换回c_string时数据表示形式丢失
- 如何用给定的数据计算概率
- C++中具有概率分布的向量的随机生成器
- 将概率分布拟合到观测数据c++
- 使用boost c++为一组数据生成指数分布
- C语言中的Gomoku数据表示