【发布时间】:2011-10-14 11:06:21
【问题描述】:
我正在努力实现直方图,其中一个关键点是直方图箱的快速合并。因为我对直方图逼近的数据集没有先验知识,所以我需要想出一种方法,在超过最大 bin 数后快速合并相邻的 bin。
因此,举个例子,如果您使用五个直方图 bin 来近似数据流 23、19、10、16、36、2、9、32、30、45,您将读取前五个元素,获得:
(23, 1), (19,1), (10,1), (16,1), (36,1)
添加 bin (2,1) 会导致问题,因为我们已经超过了 bin 的最大数量。因此,我们添加 (2,1) 并合并两个最接近的 bin - (16,1) 和 (19,1) - 以获得替换这两个的新 bin (17.5,2)。
对直方图的其余部分重复此方法,得到最终输出:
(2,1), (9.5,2), (19.33,3), (32.67,3), (45,1)。
在不考虑复杂性问题的情况下实现这一点是微不足道的。但是,我真的很关心如何针对大型数据集进行优化,因为我的“微不足道”实现最终需要 15 秒才能在 100,000 个高斯分布值的流上运行。
我目前的想法是使用 boost::multi_index 来跟踪我的 HistogramBin 结构,其定义为:
struct HistogramBin
{
double bin;
unsigned long count;
bool isNull;
HistogramBin(double x, bool n = false)
: bin(x), count(1), isNull(n) {}
bool operator<(const HistogramBin &other) const
{ return (bin < other.bin); }
// Merges other with this histogram bin
// E.g., if you have (2.0,1) and (3.0,2), you'd merge them into (2.67,3)
void merge(const HistogramBin &other)
{
unsigned long old_count = count;
count += other.count;
bin = (bin*old_count + other.bin*other.count)/count;
}
// Gets the difference between two histogram bins
const double getDifference(const HistogramBin &other) const
{ return (double)abs(bin - other.bin); }
};
因此,multi_index 将使用 ordered_unique 对 HistogramBin::bin 进行排序。
现在,这并不能解决根据相邻 bin 之间的差异对 bin 进行排序的问题。 HistogramBin::bin 的索引为我们提供了 HistogramBin 对象的有序列表,但下一步是计算当前 bin 与下一个 bin 之间的差异,然后也对 那些 值进行排序.
有没有办法对这些值进行排序,同时保持列表的完整性,并且不引入新的容器(例如差异/迭代器键/值对的多重映射)?
维护这个列表是我目前对复杂性问题的近乎最优解决方案的想法,因为它只需要在合并时进行更改,并且只有在添加新值时才会发生合并。
任何想法或见解将不胜感激。
【问题讨论】:
-
您的垃圾箱应该具备哪些属性?我认为可以对传入的值进行排序,然后根据您的标准设置箱的限制。
-
不清楚根据相邻元素之间的差异对容器进行排序是什么意思。或许举个例子就能说明问题。
-
@n.m.我试图在问题中举个例子。通过按相邻元素之间的差异进行排序,我的意思是在排序后,“排序后的差异图”将类似于:(6, (10,1), (16,1)), (3, (16,1), (19,1)), ...,这就是你想要排序的向量——根据差异。这就是告诉我们将 (16,1) 和 (19,1) 合并到 (17.5,2) 中的原因。
-
看看这个问题的答案:stackoverflow.com/questions/3698532/online-k-means-clustering 如果我正确理解你的问题,那几乎就是你要找的,最初的
k猜测是你的第一个k值. -
@kmore 实际上是 O(n*log(m)),如果你保持你的 bin 中心有序,你可以对它进行二分搜索,最接近的值要么是之前的要么是之后的它
标签: c++ algorithm boost time-complexity