Perl:编程大量数据的相关系数时的编程效率

时间:2009-03-23 20:04:05

标签: perl memory performance dataset

编辑:链接现在应该工作,对不起麻烦

我有一个看起来像这样的文本文件:

Name, Test 1, Test 2, Test 3, Test 4, Test 5
Bob, 86, 83, 86, 80, 23
Alice, 38, 90, 100, 53, 32
Jill, 49, 53, 63, 43, 23.

我正在编写一个给出这个文本文件的程序,它将生成一个Pearson的相关系数表,看起来像这样,其中条目(x,y)是人x和人y之间的相关性:

Name,Bob,Alice,Jill
Bob, 1, 0.567088412588577, 0.899798494392584
Alice, 0.567088412588577, 1, 0.812425393004088
Jill, 0.899798494392584, 0.812425393004088, 1

我的程序有效,除了我提供的数据集有82列,更重要的是54000行。当我现在运行我的程序时,它非常慢,我得到一个内存不足错误。有没有办法,我可以首先删除任何内存不足错误的可能性,并可能使程序运行更高效?代码在这里:code

感谢您的帮助,
千斤顶

编辑:如果其他人正在尝试进行大规模计算,请将数据转换为hdf5格式。这就是我最终要解决的问题。

7 个答案:

答案 0 :(得分:4)

您将不得不进行至少54000 ^ 2 * 82次计算和比较。当然,这需要花费很多时间。你把一切都记在了记忆中吗?这也会非常大。它会更慢,但是如果你可以将用户保留在数据库中并且计算一个用户对抗所有其他用户,那么它可能会使用更少的内存,然后继续执行下一个用户而不是一个大型数组或散列。

答案 1 :(得分:4)

请查看Tie::File以处理将输入和输出文件存储在内存中的高内存使用情况。

答案 2 :(得分:4)

您搜索过CPAN吗?我自己的搜索产生了另一种方法gsl_stats_correlation用于计算Pearsons相关性。这个是Math::GSL::Statisics。该模块与GNU Scientific Library绑定。

  

gsl_stats_correlation($ data1,$ stride1,$ data2,$ stride2,$ n) - 此函数有效地计算数组引用$ data1和$ data2之间的Pearson相关系数,它们必须具有相同的长度$ n。 r = cov(x,y)/(\ Hat \ sigma_x \ Hat \ sigma_y)= {1 /(n-1)\ sum(x_i - \ Hat x)(y_i - \ Hat y)\ over \ sqrt {1 /(n-1)\ sum(x_i - \ Hat x)^ 2} \ sqrt {1 /(n-1)\ sum(y_i - \ Hat y)^ 2}}

答案 3 :(得分:3)

您可能需要查看PDL

  

PDL(“Perl数据语言”)给出   标准Perl具有紧凑的能力   存储并迅速操纵   大的N维数据阵列   是科学的面包和黄油   计算

答案 4 :(得分:2)

基本上保罗·汤姆林给了你答案:这是很多计算所以需要很长时间。这是很多数据,因此需要大量内存。

但是,可能有一个问题:如果你使用perl 5.10.0,那么每个方法开头的列表赋值可能是该版本perl中一个微妙的性能错误的受害者(参见perlmonks thread

一些小问题:

打印输出实际上可能会在某种程度上减慢程序的速度。

无需为每一行重新打开输出文件!做这样的事情:

open FILE, ">", "file.txt" or die $!;
print FILE "Name, ", join(", ", 0..$#{$correlations[0]}+1), "\n";
my $rowno = 1;
foreach my $row (@correlations) {
  print FILE "$rowno, " . join(", ", @$row) . "\n";
  $rowno++;
}
close FILE;

最后,虽然我尽可能地使用Perl,但是使用您描述的程序和数据集,这可能是简单地使用C ++及其iostream(这使得解析足够容易)来执行此任务的最简单方法。 / p>

请注意,所有这些只是次要优化。没有算法收益。

答案 5 :(得分:1)

我不太了解你要做什么来提供有关实施的好建议,但你可能会看Statistics::LSNoHistory,它声称有一个方法pearson_r可以返回Pearson的相关性系数。

答案 6 :(得分:0)

除了上面关于PDL的评论之外,以下是如何非常有效地计算非常大的数据集的相关表的代码:

use PDL::Stats; # this useful module can be downloaded from CPAN
my $data = random(82, 5400); # your data should replace this
my $table = $data->corr_table(); # that's all, really

您可能需要在脚本的标题中设置$PDL::BIGPDL = 1;,并确保在具有大量内存的计算机上运行此项。计算本身相当快,82 x 5400表在我的笔记本电脑上只用了几秒钟。