「関連性」指標に基づいて値をグループ化する方法は?

「関連性」指標に基づいて値をグループ化する方法は?

3つの列を持つファイルがあります。列 1 と 2 には、同じグループから取得した数字が含まれます。ファイルには通常、グループの各メンバーのペアに対して1行が含まれています。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セットのすべての数値ペアには十分な接続性が必要です。 1/2/3と6の間には高い相関関係がありますが(0.555> 0.2)、前の数字(4と5)は1と低い相関関係があるため、6を最初のグループに配置しないでください。したがって、4と5をスキップし、最初のグループの数字を6に関連付けることはできません。

4番は5番と密接な関係がないので、4番は単独で2番目のグループに属する必要があります。 4が7と関連性が高いとしても、前の数字(5と6)は4と関連性が低いため、中間数字をスキップして4と7を連結することはできません。

5は6、7、8との接続性が高い。さらに、数字のペア(6/7、6/8、7/8など)も高い接続性を持っています。したがって、それらは3番目のグループに配置する必要があります。これが、これらすべての数字を1つのグループに配置できる理由です。

実際のデータは、数字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

ループ入力。最初の数字が同じで接続性がしきい値を超える場合は、同じグループに数字を追加します。接続が低すぎる場合は、最初の列の2番目の数字が表示されるまで何もしないでください。

#!/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";
}

関連情報