如何根据“关联性”指标对值进行分组?

如何根据“关联性”指标对值进行分组?

有一个包含三列的文件。第 1 列和第 2 列包含从同一组中抽取的数字。该文件通常为该组的每一对成员包含一行;所以,如果有n会员,应该有n×(n−1)/2 行。

第 3 列显示第 1 列和第 2 列中的数字之间的关联程度。

我想将源集划分为连续值组(即范围),其连通性大于或等于 0.2。例如,在这个小数据集中:

输入:

1   2       0.222
1   3       0.213
1   4       0.014
1   5       0.001
1   6       0.555
1   7       0.509
2   3       0.213
2   4       0.014
2   5       0.001
2   6       0.555
2   7       0.709
2   8       0.509
3   4       0.995
3   5       0.323
3   6       0.555
3   7       0.225
3   8       0.001
4   5       0.095
4   6       0.058
4   7       0.335
4   8       0.005
5   6       0.995
5   7       0.658
5   8       0.650
6   7       0.431
6   8       0.333
7   8       0.754

输出应该是这样的:

输出:

   G1: 1 2 3    G2: 4   G3 :5 6 7 8

1 与 2 和 3 之间的连通性大于 0.2,因此 1、2 和 3 应放在第一组中。事实上,一组中的任何一对数字都必须具有足够的连通性。尽管 1/2/3 和 6 之间有很高的相关性 (0.555 > 0.2),但 6 不应该放在第一组中,因为之前的数字(4 和 5)与 1 的相关性较低。所以我们不能跳过 4 和 5并将第一组中的数字与 6 连接起来。

4 号与 5 的关联度不高,因此 4 号应该单独属于第二组。不管 4 与 7 的关联度很高,因为之前的数字(5 和 6)与 4 的关联度较低,我们不能跳过中间的数字将 4 与 7 连接起来。

5 与 6、7 和 8 具有很高的连通性。此外,任何一对数字(如 6/7、6/8、7/8)在一起也具有很高的连通性。因此,他们应该被放在第三组中。这就是为什么所有这些数字都可以放在一组中。

请注意,实际数据并非从数字 1 开始,并且有超过 100,000 行。所以它是巨大的。

这是我的真实数据的一部分:
输入:

    49997 49998 0.082
    49997 49999 0.953
    49997 50000 0.060
    49998 49999 0.288
    49998 50000 0.288
    49999 50000 0.265

输出应该是:

  G1:49997   G3: 49998 49999 50000

答案1

循环输入。当第一个数字相同且连通性超过阈值时,将数字添加到同一组。一旦连通性太低,就不要执行任何操作,直到遇到第一列中的第二个数字。

#!/usr/bin/perl
use warnings;
use strict;

my $THRESHOLD = 0.2;

my $next;
my @groups;
while (<>) {
    my ($n1, $n2, $connectedness) = split;
    @groups = ([ $next = $n1 ]) unless defined $next;
    if ($next == $n1) {
        if ($connectedness > $THRESHOLD) {
            push @{ $groups[-1] }, $n1 unless @{ $groups[-1] };
            push @{ $groups[-1] }, $n2;

        } else {
            $next = $n2;
            push @groups, [$n2];
        }
    }
}

for my $i (1 .. @groups) {
    print "Group $i: @{ $groups[ $i - 1 ] }\n";
}

相关内容