2010-11-23 4 views
3

J'ai un tableau contenant de nombreuses valeurs entre 0 et 360 (comme les degrés dans un cercle), mais inégalement répartie:Comment obtenir un échantillon distribué uniformément à partir de valeurs de tableau Perl?

1,45,46,47,48,49,50,51,52,53,54 , 55,100,120,140,188, 210, 280, 355

Maintenant, je dois réduire ces valeurs pour, par exemple, 4 seulement, mais aussi uniformément que possible des valeurs distribuées.

Comment faire?

Merci, Jan

+1

Vous devez formuler votre question plus attentivement. À l'heure actuelle, cela n'a pas beaucoup de sens. – singingfish

Répondre

3

mettre les chiffres sur un cercle, comme une horloge. Maintenant, construisez une croix logique, disons à 12, 3, 6 et 9 heures. Mettez le 12 au premier numéro. Trouvez maintenant quels nombres seraient les plus proches de 3, 6 et 9 heures, et enregistrez la somme des distances de ces trois nombres à côté du premier nombre. Iterate en tournant le haut de votre croix - le point de 12 heures - dans le sens des aiguilles d'une montre jusqu'à ce qu'il s'aligne exactement avec le chiffre suivant. Encore une fois, mesurez la distance entre les nombres les plus proches de chacun de vos trois autres points de croisement et notez ce score à côté de ce nombre actuel de 12 heures.

Répétez jusqu'à ce que vous atteigniez votre 12 heures a tourné tout le chemin à l'original 3 heures, à quel point vous avez terminé. Quel que soit le nombre auquel la somme la plus basse est attribuée détermine la configuration gagnante.

Cette solution généralise à toute plage de valeurs R et tout nombre N de points finaux que vous souhaitez réduire à l'ensemble. Chaque point sur la "croix" est R/N à l'écart l'un de l'autre, et vous avez seulement besoin de tourner jusqu'à ce que le sommet de votre croix atteigne où le bras suivant était dans la position d'origine. Donc si vous voulez 6 points, vous aurez une croix à 6 pointes, espacées de 60 degrés au lieu d'une croix à 4 pointes espacées de 90 degrés. Si votre plage est différente, vous faites toujours le même type d'opération. De cette façon, vous n'avez pas besoin d'une horloge physique et d'une croix pour implémenter cet algorithme: cela fonctionne pour n'importe quel R et N.

Je me sens mal de cette réponse du point de vue de Perl, car je n'ai réussi à inclure aucun dollar signes dans la solution. :)

+1

Étape 1. Obtenez un échantillon distribué uniformément à partir des valeurs du tableau Perl. Étape 2. ???. Étape 3. ** $$$ ** –

1

Utilisez un clustering algorithm pour diviser vos données en partitions réparties uniformément. Ensuite, prenez une valeur aléatoire de chaque cluster. Ce qui suit $datafile ressemble à ceci:

1 1 
45 45 
46 46 
... 
210 210 
280 280 
355 355 

La première colonne est une étiquette, la seconde colonne est données. Exécution de ce qui suit avec $K = 4:

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->[int rand(@$cluster - 1)]; 
} 

use YAML; print Dump \%clusters; 

renvoie cette:

120: 120 
199: 188 
317.5: 355 
45.9166666666667: 46 

La première colonne est le centre du groupe, le second est la valeur sélectionnée de ce cluster. La distance entre les centres devrait être maximisée selon le Expectation Maximization algorithm.

Questions connexes