方差的并行计算

时间:2014-09-28 21:17:04

标签: javascript mapreduce variance

我正在尝试使用MapReduce在JavaScript中实现variance的并行计算。我相信可以使用这个Parallel algorithm,但我想知道如何将它应用于任意数量的数据集。到目前为止,我得出的结论是,解决问题的最佳方法是根据平方和进行减少,而不是根据方差进行减少。一个天真的实现看起来像这样:

// partials is an array of [count, sum, sumsquare] arrays
function variance(partials) {
  var count = 0;
  var sum = 0;
  var sumsquare = 0;
  for (var i = 0; i < partials.length; ++i) {
    count += partials[i][0];
    sum += partials[i][1];
    sumsquare += partials[i][2];
  }
  return (sumsquare / count) - Math.pow(sum / count, 2);
}

// variance([[3, 6, 14], [3, 15, 77], [3, 24, 194]]) should return 6.666666666666668

不是统计学家,我很难搞清楚这种并行算法是否会引入太多的复合错误。但如果可以接受,值得注意的是,在map阶段不需要计算方差。只需要平方和,总和和计数之和。

2 个答案:

答案 0 :(得分:1)

我不确定我是否清楚地理解你的意思 reduce函数将为映射到a的整个数据集的每个子集获得一个四元组数组,如{variance,sumsquare,sum,count}一组工人。尽管如此,基于您的代码剪切,我会使用类似的东西:

Array.sums = function (arr, addarr) {
   var newarr = [0,0,0];
   if (addarr.length === arr.length) {
      arr.forEach( function (v,i) {
        newarr[i] = v + addarr[i];
      });
   }
   return newarr;
}
    
function variance(arr) {
  var summations = arr[0].map(function () {return 0;});
  arr.forEach(function (v){
   summations = Array.sums(v, summations);
  });
  summations.unshift( (summations[2] / summations[0]) -
                      Math.pow(summations[1] / summations[0], 2) );
  // summations is now a quadruplet containing [variance, count, sum, sumsquare]
  return summations;
}

alert( variance([[3, 6, 14], [3, 15, 77], [3, 24, 194]])[0] );

答案 1 :(得分:0)

据我所知,原始问题中添加的“天真”解决方案就像它获得的一样好,因为它依赖于需要的三个聚合(count,sum和sumsquare)无论如何计算一次通过的方差,它所做的就是对各个聚合求和,这对于方差的单程计算也是必需的。因此,它不会增加任何算术开销。因此,与集中计算相比,它不应该添加任何错误。