2015-12-04 1 views
1

Je dois créer une permutation aléatoire d'un ensemble de données comportant plus de 3 millions de lignes.Permutation aléatoire des lignes d'un grand ensemble de données

J'ai essayé d'utiliser PROC PLAN, basé sur cet exemple: http://support.sas.com/kb/23/977.html Selon cet article, ayant n = (nombre de lignes)! permet la sélection aléatoire d'une permutation. Malheureusement pour un ensemble de cette taille, c'est 4,3 * 10^19668676 permutations. Évidemment, je rencontre un peu un problème de mémoire ici.

J'ai également trouvé un exemple utilisant PROC IML, mais il semble que mon entreprise ne dispose pas du logiciel de licence/logiciel nécessaire pour l'utiliser.

Quelqu'un peut-il me fournir un bon moyen de mélanger cet ensemble de données?

+0

Si vous avez un moyen de donner à chaque ligne de données un index unique, vous pouvez utiliser le [shuffle Fisher-Yates] (https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) pour générer indexes aux données. Je suppose que vous ne voulez qu'une petite quantité de permutations plutôt que toutes. –

+1

Vous dites permutation aléatoire? Pouvez-vous fournir plus d'informations? Une partie de moi veut dire PROC SURVEYSELECT avec SRS, mais pas certain à coup sûr. – Reeza

+0

Droit - en quoi la 'permutation aléatoire' est-elle différente de 'échantillon aléatoire [sans remplacement]'? – Joe

Répondre

2

Il semble que vous vouliez prendre les lignes et les placer dans un ordre aléatoire. Dans ce cas, la méthode la plus courante consiste à créer une valeur aléatoire pour chaque ligne et puis trier par les valeurs aléatoires:

DATA augmented ; 
    SET original ; 
    sortval = RAND('UNIFORM') ; 
RUN ; 

PROC SORT DATA=augmented OUT=permuted(DROP=sortval) ; 
    BY sortval ; 
RUN ; 

Vous pouvez utiliser l'appel STREAMINIT (seedval) appeler la routine si vous voulez être en mesure de précision reproduire la séquence aléatoire plus tard.

Vous pouvez également faire sans doute cela avec PROC SQL [code non testé]:

PROC SQL ; 
    CREATE TABLE permuted(DROP=sortval) AS 
    SELECT a.*, RAND('UNIFORM') AS sortval 
     FROM original a 
     ORDER BY sortval 
    ; 
QUIT ; 
+0

Le seul problème que je vois ici est que RAND ('UNIFORM') répète 1,000+ fois ce nombre de lignes. Des suggestions sur la façon de corriger cela? –

+0

Il répète un par rangée, ce qui semble être souhaité. Il n'y a rien de randomisé - il suffit de placer un seul numéro pseudo-aléatoire sur chaque ligne (une ligne par appel). – Joe

+0

@ Joe, Désolé, je n'étais pas clair. Les valeurs créées par RAND ('UNIFORM') ne sont pas uniques. Il y a plus de 1000 valeurs qui se produisent plus d'une fois. –

1

Cela va créer un remaniement aléatoire des données et conserver les graines de nombres aléatoires à la fois en tant que colonne dans les données et en tant que méta Les données. Vous pouvez omettre un ou les deux mais j'aime laisser SAS générer la graine et me laisser la sauvegarder pour que je puisse reproduire l'échantillon/shuffle. Utilisez une VUE pour que les observations soient redirigées directement vers PROC SORT.

data shuffle/view=shuffle; 
    obs = _n_; 
    set sashelp.cars; 
    if _n_ eq 1 then call streaminit(0); 
    r = rand('uniform'); 
    retain seed; 
    if _n_ eq 1 then seed=symgetn('sysrandom'); 
    run; 


proc sort data=shuffle out=shuffle01; 
    by r; 
    run; 
%put NOTE: &=sysrandom; 

proc datasets nolist; 
    modify shuffle01(label="SEED=&sysrandom"); 
    run; 
    quit; 
proc contents; 
    run; 
proc print; 
    run; 
2

similaires à ce que Ludwig61 dit, je ferais ce qui suit

DATA augmented ; 
    SET original ; 
    call streaminit(12072015)*optional, if you want to set a seed; 
    sortval1 = RAND('UNIFORM') ; 
    sortval2 = RAND('UNIFORM') ; 
    sortval3 = RAND('UNIFORM') ; 
RUN ; 

PROC SORT DATA=augmented OUT=permuted(DROP=sortval1 sortval2 sortval3) ; 
    BY sortval1 sortval2 sortval3; 
RUN ; 

Puisque vous courriez dans des collisions en utilisant simplement un nombre aléatoire, vous pouvez simplement ajouter des numéros aléatoires jusqu'à ce que vous sentez à l'aise de savoir que vous n'obtiendrez aucune valeur de répétition, puis trier par ces nombres aléatoires. Étant donné que la fonction Rand ('Uniform') a une période de 2^19937-1, vous devriez utiliser 3 - votre seul ennemi dans ce cas est la troncature de SAS après 53 bits.