C ++累加器库,能够删除旧样本

时间:2012-09-26 00:51:38

标签: c++ boost machine-learning accumulator

在Boost.Accumulator中,您可以将样本添加到累加器,然后从中提取统计量。 e.g:

acc(1.)
acc(2.)
acc(3.)
cout << mean; // 2

图书馆有许多更复杂的统计数量,例如skewnesskurtosisp_square_cumulative_distribution

我想做的是这样的事情:

acc(1.)
acc(2.)
acc(3.)
std::cout << mean(acc); // 2
acc.pop() // withdraw the first value (1.)
std::cout << mean(acc); // 2.5

pop()将以FIFO(先进先出)方式工作。我想要做的是在滑动时间窗口内以在线(增量)方式计算我的数据的统计数据。

累加器必须在内部保留所有值。

我可以自己做,但我总是想首先检查现有的库,并且可能有一些我不知道的算法,即在数据传入或传出时巧妙地计算数量。

3 个答案:

答案 0 :(得分:9)

由于您提到了“滑动时间窗口”,因此一个选项是使用滚动平均值(还有滚动总和和滚动计数),这是最后 N 样本的平均值。根据您的需要,您可以创建具有不同窗口大小的单独累加器。

typedef accumulator_set<double,
                stats<tag::rolling_mean>
                > my_accumulator;

my_accumulator acc(tag::rolling_window::window_size = 3);
acc(1.);
acc(2.);
acc(3.);
std::cout << rolling_mean(acc);
// Reset accumulator and use different window size
acc = my_accumulator(tag::rolling_window::window_size = 2);
acc(2.);
acc(3.);
std::cout << rolling_mean(acc);

另外,如果你看一下这些的实现,他们会使用boost/circular_buffer.hpp

答案 1 :(得分:1)

您可能需要将所有样本保存在矢量中,然后从矢量中为每次计算累积它们。这样的事情:https://stackoverflow.com/a/7616783/219136

答案 2 :(得分:1)

您可能希望将数据存储在std::deque而不是矢量中,因此插入和删除都可能具有不变的复杂性。如果使用向量,则不可避免地会是线性的。

除此之外,将算法应用于集合是一件非常简单的事情。然而,奇怪的是,我不知道已经编写和测试过的这类算法的集合,尽管看起来像一组相当明显的算法可供使用。

对于它的价值,构建适配器以将数据从集合提供到累加器以计算您可以使用的统计数据是相当简单的。在少数情况下,累加器可能需要做一些额外的工作来逐步计算结果,但我认为很少会失去足够的效率来关心。