de Michelle Jones

Cum să vă controlați randomizatorul în R.

Ce se întâmplă când aveți nevoie de un anumit tip de randomizare?

Cum sa va controlati randomizatorul in R
200 de numere aleatorii folosind distribuția normală.

Prezentare generală a generării de numere aleatorii în R.

R are cel puțin 20 de funcții de generare de numere aleatorii. Fiecare folosește o distribuție de probabilitate specifică pentru a crea numerele. Toate necesită să specificați numărul de numere aleatorii pe care le doriți (imaginea de mai sus arată 200). Toate sunt disponibile în baza R – nu sunt necesare pachete.

Distribuțiile comune ale generatorului de numere aleatorii sunt:

  • normal (rnorm): media implicită de 0 și abaterea standard de 1
  • binom (rbinom): nu există valori implicite, specificați numărul de încercări și probabilitatea de succes în fiecare proces
  • uniformă (runif): valoarea minimă implicită 0 și valoarea maximă 1

Dintre cele trei de mai sus, numai generatorul de numere aleatoare binomiale creează numere întregi.

De ce să creezi numere aleatorii?

Problemele care implică numere aleatorii sunt foarte frecvente – există în jur 50.000 de întrebări legate de numere aleatorii pe Stack Exchange.

Dar de ce să le folosești?

Numerele aleatorii au multe aplicații practice. Sunt folosite în Simulări Monte Carlo. Sunt folosite în criptografie. Au fost folosite pentru a produce Conținut CAPTCHA. Sunt folosite în păcănele. Ele au fost, de asemenea, utilizate pentru sarcini mai banale, cum ar fi crearea unei ordini de sortare aleatorii pentru o serie de date ordonate.

Probleme cu numerele aleatorii

Întrebările frecvente includ „numerele mele aleatoare sunt de fapt aleatorii?” și „cum pot genera numere aleatorii nerepetate?”

Notă: acesta din urmă scade aleatorietatea, deoarece populația de numere aleatorii posibile este redusă cu unul de fiecare dată când se extrage un număr aleatoriu. Metoda este adecvată în situații precum loterii sau bingo, în care fiecare bilet sau minge poate fi extras o singură dată.

Această problemă aduce o altă problemă! Eșantionarea generată aleatoriu fără numere de înlocuire trebuie să fie întregi. Nimeni nu are biletul 5.6932 sau mingea de bingo 0.18967.

Un exemplu practic de probleme ale numărului aleatoriu

Să luăm exemplul că am 20 de elevi de aceeași vârstă. Am patru metode de predare pe care vreau să le încerc. Vreau să încerc doar o metodă de predare pentru fiecare student. Matematică ușoară – Am nevoie de cinci elevi în fiecare grup.

Dar cum fac asta pentru ca fiecare student să fie repartizat aleatoriu?

Și cum mă asigur că am produse numai numere întregi?

Și cum pot face toate acestea folosind numere generate aleatoriu fără înlocuire? Nu vreau, de exemplu, șase elevi într-un grup și patru elevi în altul.

În primul rând, trebuie să creez niște date fictive, în R. Să creăm acea listă de băieți elevi.

FemaleStudents <- data.frame(Names=c("Alice", "Betty", "Carol", "Denise", "Erica", "Frances", "Gina", "Helen", "Iris", "Julie", "Katherine",                           "Lisa", "Michelle", "Ngaire", "Olivia", "Penelope", "Rachel", "Sarah", "Trudy", "Uma"))

Acum avem un set de date unidimensional al celor 20 de studenți.

Știm că runif() funcția nu creează numere întregi. De ce nu rotunjim numerele aleatorii astfel încât să obținem numai numere întregi și să folosim această funcție? Putem înfășura numărul aleatoriu într-o funcție de rotunjire.

Intrebarea 1: de ce folosesc distribuția uniformă aleatorie și nu alta, cum ar fi distribuția normală aleatorie?

Există cinci tipuri de funcții de rotunjire în R. Vom folosi round().

Pentru a obține aceleași rezultate, voi seta o sămânță pentru generarea de numere aleatorii. De fiecare dată când generăm numere aleatorii, vom folosi aceeași sămânță. Am decis 5 ca sămânță. Dacă nu setați o sămânță sau dacă setați o sămânță diferită de 5, rezultatele dvs. vor fi diferite de ale mele.

set.seed(5)FemaleStudents$Group <- round(runif(20, 1, 5))

Ei bine, asta părea să funcționeze. Fiecare elev este alocat unui grup numerotat între 1 și 5.

Să verificăm alocarea noastră.

table(FemaleStudents$Group)
1 2 3 4 5 2 6 5 4 3

Darn. Numai unul dintre cele cinci grupuri are numărul corect de studenți (Grupa 4). De ce s-a întâmplat asta?

Putem verifica numerele efectiv emise de runif() fără rotunjire și lăsând ieșirea să se imprime pe consolă. Aici, ieșirea se imprimă deoarece nu am atribuit funcția unui obiect (de exemplu, unei variabile data.frame).

set.seed(5)runif(20,1,5)
[1] 1.800858 3.740874 4.667503 2.137598 1.418601 3.804230 3.111840 4.231741 4.826001 1.441812 2.093140 2.962053 2.273616 3.236691 2.050373[16] 1.807501 2.550103 4.551479 3.219690 4.368718

După cum putem vedea, rotunjirea ne-a cauzat problema. Dar dacă nu ne-am fi rotunjit, fiecare elev ar fi fost alocat unui alt grup.

Ce facem?

probă()

sample() este acum una dintre funcțiile mele preferate din R. Să vedem cum funcționează.

Alocați aleatoriu grupurilor de dimensiuni egale (contează importanța)

Cum o putem folosi pentru a repartiza aleatoriu cei 20 de studenți noștri în patru grupuri de dimensiuni egale?

Ce se întâmplă dacă încercăm sample() în mod normal?

set.seed(5)FemaleStudents$Sample <- sample(1:5, nrow(FemaleStudents), replace=TRUE)

Intrebarea 2: ce rezultat ai obținut când ai folosit table(FemaleStudents$Sample)?

Putem rezolva această problemă creând un vector de numere de grup și apoi folosind eșantionare fără înlocuire din acest vector. rep comanda este utilizată pentru a crea o gamă de valori repetate. Îl puteți folosi pentru a repeta fiecare număr din serie, așa cum am folosit aici. Numărul 1 se repetă de patru ori, apoi numărul 2 se repetă de patru ori și așa mai departe. De asemenea, îl puteți utiliza pentru a repeta o secvență de numere, dacă utilizați în schimb acest cod: rep(1:5,4)

OurGroups <- rep(1:5, each=4)set.seed(5)FemaleStudents$Sample <- sample(OurGroups, nrow(FemaleStudents), replace=FALSE)

Ne-am folosit vectorul de numere (OurGroups) să ne alocăm studenții în grupuri. Am folosit eșantionarea fără înlocuire (replace=FALSE) din OurGroups pentru că trebuie să folosim fiecare valoare din acel vector. Trebuie să eliminăm fiecare valoare pe măsură ce o folosim.

Și obținem rezultatul dorit!

table(FemaleStudents$Sample)
1 2 3 4 5 4 4 4 4 4

Întrebarea 3: de ce am pus încă o sămânță?

Un alt avantaj al sample() este că nu-i pasă de tip. Putem repeta alocarea folosind un vector de șiruri. Acest lucru poate fi util dacă nu doriți să vă referiți în continuare la ceea ce înseamnă „1”.

OurNamedGroups <- rep(c("Up", "Down", "Charmed", "Strange", "Top"), each=4)set.seed(5)FemaleStudents$Sample2 <- sample(OurNamedGroups, nrow(FemaleStudents), replace=FALSE)table(FemaleStudents$Sample2)
Charmed    Down Strange     Top      Up       4       4       4       4       4

Deoarece am folosit aceeași semință, putem vedea că s-a efectuat aceeași alocare a elevilor, indiferent dacă am folosit date numerice sau de caractere pentru atribuire.

table(FemaleStudents$Sample,FemaleStudents$Sample2)       Charmed Down Strange Top Up  1       0    0       0   0  4  2       0    4       0   0  0  3       4    0       0   0  0  4       0    0       4   0  0  5       0    0       0   4  0

Alocați aleatoriu atunci când dimensiunea grupului nu este restricționată

Uneori vrem să alocăm aleatoriu grupurilor, dar nu avem un vector de grupuri. Încă alocăm fiecare unitate (persoană, oaie, bloc de brânză) unui singur grup și folosim alocarea complet aleatorie.

Să spunem că școala noastră are o nouă cameră de bibliotecă specială. A fost construit pentru a fi izolat fonic pentru a oferi elevilor un mediu de studiu mai bun. Bibliotecarul șef ar dori să știe despre experiențele studenților din acea cameră. Singura problemă este că camera are dimensiuni limitate. Bibliotecarul șef consideră că aproximativ patru studenți este un grup suficient de mare pentru a oferi feedback-ul inițial.

Din nou, putem folosi sample() să ne alegem grupurile de studenți. În acest caz, avem „studenți care vor testa camera” și „studenți care nu vor testa camera”. O să le numesc „Test” și „Not test”. Aceste etichete au fost alese pentru a fi 1. scurte și 2. ușor de distins.

Deoarece am efectuat eșantionarea fără înlocuire mai devreme, nu am specificat probabilitățile de atribuire către grupuri – pur și simplu am scos o atribuire dintr-un vector. Acum vom folosi eșantionarea cu înlocuire. Prin înlocuire se referă la grup, nu la studenți.

Trebuie să prelevăm probe cu înlocuire, deoarece avem doar două grupuri („Test”, „Nu test”) și 20 de studenți. Dacă am încerca să prelevăm eșantioane fără înlocuire, codul nostru ar erora.

Codul nostru este foarte similar:

set.seed(5)FemaleStudents$Library <- sample(c("Test", "Not test"), nrow(FemaleStudents), replace=TRUE, prob=c(4/20,16/20))table(FemaleStudents$Library)
Not test     Test       15        5

După cum puteți vedea, am alocat cinci studenți pentru a testa sala, nu patru. Acest tip de rezultat este de așteptat atunci când se tratează probe mici. Cu toate acestea, alocarea noastră de studenți este complet aleatorie. Fiecare elev avea exact aceeași probabilitate de a fi repartizat pentru a testa camera. Indiferent dacă studenții anteriori au fost sau nu testatori nu a avut niciun impact asupra alocării următorului student.

Să trecem prin unele dintre acel cod.

Am construit o nouă variabilă în data.frame pentru a colecta alocarea (Library).

În loc să mă ocup de numere pentru numele grupurilor, am folosit șirurile pe care le-am menționat mai devreme. Pentru că am folosit corzi, c() trebuie să împacheteze numele grupului (“Test”, “Not test”) și fiecare nume de grup este separat printr-o virgulă.

Înlocuirea a fost setată la TRUE.

Probabilitatea de alocare oricărui grup trebuie să fie furnizată. Acesta este prob=c(4/20,16/20) parte a sample() funcţie. Din nou, rețineți cum c() este folosit pentru a conține probabilitățile. De asemenea, este interesant faptul că probabilitățile pot fi exprimate ca fracții, mai degrabă decât zecimale.

Ura pentru eșantion ()

eu folosesc sample() tot timpul pentru munca pe care o fac. Abilitatea de a utiliza șiruri, precum și de a restricționa ieșirea numerică la numere întregi (și de a defini intervalul întreg dorit), îmi oferă mai mult control decât încercarea de a utiliza una dintre funcțiile de număr aleatoriu.

Răspunsuri

raspunsul 1: Am folosit o distribuție uniformă aleatorie pentru că am vrut ca fiecare valoare să fie la fel de probabilă.

Răspunsul 2: Am obținut această ieșire:

1 2 3 4 5 2 7 4 2 5

Răspunsul 3: Dacă nu stabilim o valoare inițială sau folosim una diferită, alocarea anumitor studenți va fi diferită. De exemplu, atunci când semința este 5, Alice este alocată grupului 2. Dacă semința este 7, Alice este alocată grupului 5. Replicarea este importantă atunci când codul trebuie relansat (de exemplu, în testare).