是Boost Library的加权中位数被打破了吗?

时间:2011-02-24 22:25:47

标签: c++ boost statistics

我承认我不是C ++专家。

我正在寻找一种计算加权中位数的快速方法,Boost似乎有这种方法。 但似乎我无法使其发挥作用。

#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/median.hpp>
#include <boost/accumulators/statistics/weighted_median.hpp>
using namespace boost::accumulators;    

int main()
{
  // Define an accumulator set
  accumulator_set<double, stats<tag::median > > acc1;
  accumulator_set<double, stats<tag::median >, float> acc2;

  // push in some data ...
  acc1(0.1);
  acc1(0.2);
  acc1(0.3);
  acc1(0.4);
  acc1(0.5);
  acc1(0.6);

  acc2(0.1, weight=0.);
  acc2(0.2, weight=0.);
  acc2(0.3, weight=0.);
  acc2(0.4, weight=1.);
  acc2(0.5, weight=1.);
  acc2(0.6, weight=1.);

  // Display the results ...
  std::cout << "         Median: " << median(acc1) << std::endl;
  std::cout << "Weighted Median: " << median(acc2) << std::endl;

  return 0;
}

产生以下输出,这显然是错误的。

         Median: 0.3
Weighted Median: 0.3

我做错了吗? 任何帮助将不胜感激。

*但是,加权和可以正常工作*

@glowcoder:加权和的效果非常好。

#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/sum.hpp>
#include <boost/accumulators/statistics/weighted_sum.hpp>
using namespace boost::accumulators;

int main()
{
  // Define an accumulator set
  accumulator_set<double, stats<tag::sum > > acc1;
  accumulator_set<double, stats<tag::sum >, float> acc2;
  // accumulator_set<double, stats<tag::median >, float> acc2;

  // push in some data ...
  acc1(0.1);
  acc1(0.2);
  acc1(0.3);
  acc1(0.4);
  acc1(0.5);
  acc1(0.6);

  acc2(0.1, weight=0.);
  acc2(0.2, weight=0.);
  acc2(0.3, weight=0.);
  acc2(0.4, weight=1.);
  acc2(0.5, weight=1.);
  acc2(0.6, weight=1.);

  // Display the results ...
  std::cout << "         Median: " << sum(acc1) << std::endl;
  std::cout << "Weighted Median: " << sum(acc2) << std::endl;

  return 0;
}

,结果是

         Sum: 2.1
Weighted Sum: 1.5

5 个答案:

答案 0 :(得分:5)

升压功能没有被破坏。

问题是您没有为P ^ 2估算工作提供足够的数据。如果您在数据输入周围放置一个循环,例如

for(int i=0;i<100000;i++){
  acc2(0.1, weight=0.);
  acc2(0.2, weight=0.);
  acc2(0.3, weight=0.);
  acc2(0.4, weight=1.);
  acc2(0.5, weight=1.);
  acc2(0.6, weight=1.);
}

你得到正确的结果

Median: 0.3
Weighted Median: 0.5

或者,您可以指定

 accumulator_set<double, 
    stats<tag::weighted_median(with_p_square_cumulative_distribution) >, 
    double> acc2 ( p_square_cumulative_distribution_num_cells = 5 );

即使你的问题中只添加了6分,也可以Weighted Median: 0.55作为答案。

答案 1 :(得分:3)

加权中位数应该是什么意思?中位数仅考虑项目的顺序,而不考虑内容。权重不会改变顺序(它可以改变平均值或总和)。如果您使用出现次数(自然整数)而不是浮点数,则可以扩展中位数的定义,但我不认为这是您在此尝试做的。

答案 2 :(得分:2)

怎么样:

accumulator_set<double, stats<tag::weighted_median(with_weighted_density) >, float> acc2;

答案 3 :(得分:1)

看起来你要打两次中位数。也许你打算第二次打电话给weighted_median?

答案 4 :(得分:1)

根据文档,它说它使用P ^ 2估计器来计算中位数。我做了谷歌搜索,找到了Jain&amp; Chlamtac“用于动态计算分位数和直方图的P ^ 2算法,无需存储观测值”。令我惊讶的是,在我看来,Boost Accumulator的中位数只是一个估计而不是确切的值。它应该被称为median_est而不是中位数。

看起来好像加权中位数被打破了;它没有考虑重量。