我想用 perl 计算每行数字的方差。我写了这个子程序:
################################################################
# variance
#
#
# A subroutine to compute the variance of an array
# division by n-1 i s used
#
sub var{
my ($data) = @_;
if (@$data ==1) {
return 0;
}
my $mean = mean ($data);
my $sqtotal = 0;
foreach (@$data) {
$sqtotal += ($_ - $mean) ** 2
}
my $var = $sqtotal / (scalar @$data - 1);
return $var;
}
如果我给它这个包含 58 个相同数字的元素的数组
[0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98, 0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98, 0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98,0.98]
计算结果为 1.25421964097639e-30。
我还尝试使用 Statistics::Descriptive 模块 ( http://metacpan.org/pod/Statistics::Descriptive ),它给了我 2.11916254524942e-15。
我也试过这个网站(http://www.alcula.com/calculators/statistics/variance/),结果是 2.2438191655582E-15。
为什么结果不一样...
我本可以直接使用该模块,但是对于我的文件来说,它以某种方式占用了大量内存,该文件基本上由数百万行 58 个数字组成。我不确定为什么它会占用这么多内存。
有人能告诉我为什么我的计算给出了与模块不同的数字以及如何使模块以更少的内存工作吗?内存密集型的事情只是该模块的固有缺点吗?几个帖子似乎暗示了这一点。
谢谢!
最佳答案
常数序列的方差为零,因此您的计算或多或少是正确的,并且或多或少是相同的。
您得到的结果与零略有不同,因为您使用有限精度 float 执行许多操作。让我们来看这段代码:
$z = 0;
$z += 0.98 for 1..58;
$mean = $z / 58;
printf "%.20f", $mean;
使用这段代码,我们将数字 0.98 的 58 个实例的总和除以 58。这段代码打印出 0.98000000000000000000
是有道理的,对吧?不,我实际得到的是
0.97999999999999887201
(您的结果可能会有所不同)。
规范What Every Programmer Should Know About Floating-Point Arithmetic可以向您解释血淋淋的细节。
关于perl - 如何计算perl中的方差?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22396676/