Кластеризация по интервалу через хэш массива в Perl - PullRequest
0 голосов
/ 08 ноября 2010

У меня есть данные, которые выглядят так:

#Status value
TP       5.000
TP       3.000
TP       3.000
TN       10.000
TP       2.000
TP       9.000
TN       1.000
TP       9.000
TN       1.000

Что мы хотим сделать, это кластеризовать статус на основе заданного интервала в value.Пусть этот интервал будет 1-3, 4-6, 7-9, 10-12, etc .. (т. Е. Размер корзины 3).

Мы надеемся получить хеш массива, подобный следующему:

my %hoa = (
'1-3' => [TP,TP,TP,TN,TN],
'4-6' => [TP],
'7-9' => [TP,TP],
'10-12' => [TN]);

Как это можно сделать?

Обновление : исправлено HoA для 7-9, благодаря Ysth.

Ответы [ 2 ]

2 голосов
/ 08 ноября 2010

ysth ответ был первым, что пришло мне в голову, и я думаю, что у него правильный подход.

Я просто хотел бы оставить предложение: вы можете использовать алгоритм кластеризации, чтобы сделать это для вас способом, ориентированным на будущее (скажем, когда ваши данные станут многомерными). K-означает , например, будет работать нормально, даже для данных 1D, таких как ваши.

Например:

use strict; use warnings;
use Algorithm::KMeans;

my $datafile = $ARGV[0] or die;
my $K        = $ARGV[1] or 0;
my $mask     = 'N1';

my $clusterer = Algorithm::KMeans->new(
    datafile => $datafile,
    mask     => $mask,
    K        => $K,
    terminal_output => 0,
);

$clusterer->read_data_from_file();

my ($clusters, $cluster_centers) = $clusterer->kmeans();

my %clusters;

while (@$clusters) {

    my $cluster = shift @$clusters;
    my $center  = shift @$cluster_centers;

    $clusters{"@$center"} = $cluster;
}

use YAML; print Dump \%clusters;
2 голосов
/ 08 ноября 2010

Абстрагирование кода для определения интервала:

sub interval {
    my ($val) = @_;
    my $i = int( ( $val + 2 ) / 3 );
    my $interval = sprintf( '%d-%d', $i * 3 -2, $i * 3 );
    return $interval;
}

my %hoa;
while ( my $line = <> ) {
    next if $line =~ /^#/;
    my ($status, $value) = split ' ', $line;
    push @{ $hoa{ interval($value) } }, $status;
}

use Data::Dumper;
print Dumper \%hoa;

(который получает два TP за 7-9, а не один, как вы показываете).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...