3gipnet 发表于 2015-12-27 10:33:18

perl聚类


[*]@12@vip.com#20120307/1
[*]BCDBCDBD
[*]+
[*]AAAAAAAA
[*]@18@vip.com#20120307/1
[*]BBDACCDA
[*]+
[*]AAAAAAAA
[*]@13@vip.com#20120307/1
[*]BCDBCDAA
[*]+
[*]AAAAAAAA
[*]@14@vip.com#20120307/1
[*]BCDAAABC
[*]+
[*]AAAAAAAA
[*]@15@vip.com#20120307/1
[*]BCDCCABC
[*]+
[*]AAAAAAAA
[*]@16@vip.com#20120307/1
[*]BCDBBABC
[*]+
[*]AAAAAAAA
[*]@12@vip.com#20120307/1
[*]BBDABBDA
[*]+
[*]AAAAAAAA
[*]...

我想对上面的数据进行一个聚类,每四行是一段,假设每段第二行前三个字符相同,且后五个字符差异度(对应位置不同,比如BC和BB差异度为1,BC和AB差异度为2)相近的归为一段、类,(计算出所有的差异度,选取差异度最大的那段为第一凝聚点,再在第一凝聚点距离D(D=2d)之外寻找第二凝聚点,依此类推,直到遍历所有为止)  每类之间空行隔开,生成下面这样的结果:



[*]BBD BBD BBDACCDA BBDABBDA
[*]

[*]BCD BCD BCDBCDBD BCDBCDAA
[*]

[*]BCD BCD BCDAAABC BCDBBABC
[*]BCD BCD BCDAAABC BCDCCABC
  ————————————————————————————————————————————
    比如:
1、BCDAAABC 2、BCDBBABC 3、BCDCCABC 4、BCDBCDBD 5、BCDBCDAA
五个字符串,1和2的差异度是2;1和3的差异度是2;1和4的差异度是4;1和5的差异度是5;2和3的差异度是2;2和4的差异度是3;2和5的差异度是4;3和4的差异度是3;3和5的差异度是4;4和5的差异度是2;
那么:
   1 2 3 4 5
1 0 2 2 4 5
2    0 2 3 4
3       0 3 4
4          0 2
5             0
那么2的频率是最多的,所有差异度为2的归为一类,所以1、2;1、3;4、5;归为一类;所有的都有归类了,就结束。如果还没有结束,再选下一个,也就是4,所有差异度为4的归为一类。。直到所有的归为一类。。。


—————————————————————————————————————————————————






1 #!/usr/bin/perl
2 my ( $A, $B ) = ( 3, 5 );
3 my ( @A, %G );
4
5 while (<>) {
6   chomp( my $L = <> );
7   push @A, $L; <>, <>;
8 }
9
10 for my $i ( 0 .. $#A - 1 ) {
11   for my $j ( $i + 1 .. $#A ) {
12         next if substr( $A[$i], 0, $A ) ne substr( $A[$j], 0, $A );
13         my $dif;
14         substr( $A[$i], $_, 1 ) ne substr( $A[$j], $_, 1 ) and $dif++
15         for $A .. $A + $B - 1;
16         push @{ $G{$dif} }, [ $i, $j ];
17   }
18 }
19
20 for my $v ( sort { @$b <=> @$a } values %G ) {
21   for my $ij (@$v) {
22         my @H = map substr( $A[$_], 0, $A ), @$ij;
23         print join( "\t", @H, @A[@$ij] ), $/;
24   }
25   print $/;
26 }
  
页: [1]
查看完整版本: perl聚类