我正在尝试使用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
阶段不需要计算方差。只需要平方和,总和和计数之和。
答案 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)无论如何计算一次通过的方差,它所做的就是对各个聚合求和,这对于方差的单程计算也是必需的。因此,它不会增加任何算术开销。因此,与集中计算相比,它不应该添加任何错误。