Najpierw set.seed()
Losowe wartości, które zmieniają się przy każdym uruchomieniu, są bezużyteczne w nauczaniu, ocenianiu, debugowaniu i nauce: jeśli twoja symulacja dziś daje 0.146, a jutro 0.153, która liczba trafi do raportu? set.seed() ustala punkt startowy generatora, dzięki czemu cały następujący po nim strumień „losowości” da się dokładnie powtórzyć:
To samo ziarno daje identyczne wartości, zawsze i na każdym komputerze. Liczby są pseudolosowe: to deterministyczny ciąg zaprojektowany tak, żeby przechodził każdy statystyczny test losowości, a ziarno wybiera, od którego miejsca ciągu zaczynasz. Sama wartość ziarna nic nie znaczy: 42, 7, 20260807, wybierz cokolwiek, byle to zapisać. Nawyk do wyrobienia: jedno set.seed() na początku każdego skryptu, który korzysta z losowości. (Pamiętaj, że każde losowanie przesuwa stan generatora, więc dla powtarzalności liczy się też kolejność wywołań).
System d/p/q/r: jedna tabela rozszyfrowuje całą bibliotekę
R nazywa każdą funkcję rozkładu według schematu przedrostek + rodzina. Gdy zobaczysz tę siatkę, przeczytasz całą bibliotekę statystyczną:
| Przedrostek | Na jakie pytanie odpowiada | Przykład dla rozkładu normalnego |
|---|---|---|
r | Daj mi losowe wartości | rnorm(5) |
d | Gęstość: jak wysoko jest krzywa w punkcie x? | dnorm(0) |
p | Prawdopodobieństwo: P(X ≤ x)? | pnorm(1.96) |
q | Kwantyl: które x leży na tym percentylu? | qnorm(0.975) |
p i q są wzajemnie odwrotne i to właśnie tę parę spotkasz w artykule o przedziałach ufności jako qt(0.975, df):
Zmień nazwę rodziny, a wszystko działa tak samo: runif/dunif/punif/qunif, rbinom/..., rpois/..., rt/..., rexp/.... Nauczysz się czterech przedrostków i masz dziesiątki rozkładów.
rnorm(): losowanie z rozkładu normalnego
rnorm(n, mean, sd) losuje z krzywej dzwonowej. To podstawowe narzędzie do symulowania danych przypominających pomiary:
Średnia i odchylenie standardowe z próby wychodzą blisko 100 i 15, ale nie dokładnie: ta różnica to właśnie szum próbkowania, który maleje wraz ze wzrostem n. Ostatnia linia to sztuczka, którą warto przejąć: mean() z wektora logicznego to odsetek wartości TRUE, a udział powyżej 130 wychodzi blisko teoretycznego 1 - pnorm(130, 100, 15) ≈ 2.3%. Wartości domyślne to mean = 0, sd = 1 (standardowy rozkład normalny). Histogram dla iq pokazuje znajomy dzwon.
runif(), rbinom(), rpois()
Trzy kolejne rodziny pokrywają większość potrzeb symulacji:
runif() rozkłada wartości równomiernie w przedziale („uniform”, a nie „run if”, każdy raz to źle przeczyta). rbinom(n, size, prob) symuluje n eksperymentów po size prób każdy i zwraca liczbę sukcesów w każdym, więc każda wartość powyżej to liczba orłów w 10 rzutach. rpois(n, lambda) generuje liczby zdarzeń, które występują niezależnie ze znaną średnią częstością: zgłoszenia do supportu na godzinę, literówki na stronę.
sample(): próbkowanie i tasowanie
Funkcje r* wymyślają wartości z rozkładu, a sample() losuje z wartości, które już masz:
Cała sprawa sprowadza się do argumentu replace: FALSE (domyślnie) to rozdawanie kart, każda wartość może pojawić się raz, a prośba o więcej, niż masz, kończy się błędem; TRUE to rzucanie kostką, każde losowanie zaczyna od nowa. Losowanie ze zwracaniem z własnych danych napędza bootstrap. Wywołana z samym wektorem, sample(x) zwraca losową permutację: to idiom do tasowania.
Losowanie wierszy ramki danych wykorzystuje sample() w indeksowaniu wierszy:
sample(nrow(mtcars), 5) wybiera 5 losowych numerów wierszy, a indeksowanie wyciąga te wiersze. To standardowy sposób na wyrywkowe sprawdzenie dużego zbioru danych albo podział na zbiór treningowy i testowy.
Mała symulacja Monte Carlo
Oto korzyść z całego zestawu narzędzi. Pytanie: proces daje pomiary o rozkładzie N(100, 15); uśredniasz 10 z nich. Jakie jest prawdopodobieństwo, że średnia przekroczy 105? Zamiast wyprowadzać odpowiedź, zasymuluj ją: przeprowadź eksperyment 10 000 razy i policz:
Symulacja trafia w kilka tysięcznych od dokładnej wartości (około 0.146). To Monte Carlo w pigułce: zapisz jedną próbę jako funkcję, powtórz ją tysiące razy przez replicate(), weź mean() z sukcesów. Tutaj dokładna odpowiedź istniała, bo układ był podręcznikowo prosty. Gdy tylko pytanie się komplikuje (dziwne rozkłady, maksimum skorelowanych wartości, gra oparta na regułach), droga analityczna się zamyka, a przepis na symulację działa bez zmian. Zwróć uwagę na 15 / sqrt(10) w sprawdzeniu: średnie wahają się mniej niż pojedyncze wartości. To to samo prawo pierwiastka, które decyduje o szerokości przedziału ufności.
Do symulacji, nie do sekretów
Jedna granica, której trzeba przestrzegać: domyślny generator R (Mersenne Twister) jest zbudowany z myślą o jakości statystycznej i szybkości, a nie o tajności. Jego wynik jest deterministyczny przy danym ziarnie, a stan wewnętrzny da się odtworzyć z obserwowanych wartości. To dyskwalifikuje go przy hasłach, tokenach i wszystkim, co dotyka bezpieczeństwa. Do symulacji, bootstrapu i nauczania sprawdza się świetnie; do kryptografii użyj specjalnej biblioteki (np. pakietu openssl), nigdy sample() ani runif().
Najważniejsze informacje
- Jedno
set.seed()na początku sprawia, że każdy „losowy” wynik jest powtarzalny: to samo ziarno, te same wartości. - Przedrostki d/p/q/r rozszyfrowują całą bibliotekę rozkładów: losowanie, gęstość, prawdopodobieństwo skumulowane, kwantyl.
rnorm(n, mean, sd),runif(n, min, max),rbinom(n, size, prob),rpois(n, lambda)pokrywają większość potrzeb symulacji.sample()losuje z twoich własnych wartości:replace = TRUEdla kostki, domyślnie dla kart, bezsizedo tasowania;df[sample(nrow(df), k), ]losuje wiersze.- Monte Carlo = funkcja jednej próby +
replicate()+mean(): przepis, który odpowiada na pytania o prawdopodobieństwo, do których matematyka nie dociera wygodnie. - Generator liczb losowych R służy do symulacji, nie do kryptografii.
Dalej: debugowanie, czyli co naprawdę znaczą komunikaty o błędach w R i jak czytać traceback.
Najczęściej zadawane pytania
Co robi set.seed() w R?
Ustala punkt startowy generatora liczb losowych R, więc kolejne „losowe” wartości wychodzą identyczne przy każdym uruchomieniu. Wywołaj ją raz na początku każdego skryptu, który korzysta z losowości, set.seed(42), a twoja symulacja stanie się powtarzalna: współpracownicy, sprawdzający i ty w przyszłości zobaczycie te same liczby.
Jak wygenerować liczby losowe w R?
Wybierz rozkład: rnorm(n, mean, sd) dla rozkładu normalnego, runif(n, min, max) dla jednostajnego, rbinom(n, size, prob) dla liczby sukcesów, rpois(n, lambda) dla liczby zdarzeń. Do losowania z istniejących wartości użyj sample(x, size).
Czym różnią się rnorm, dnorm, pnorm i qnorm?
Jeden rozkład, cztery przedrostki: r losuje wartości, d podaje wysokość krzywej gęstości, p podaje prawdopodobieństwo skumulowane P(X ≤ x), a q jest jego odwrotnością, czyli wartością dla danego percentyla. Te same cztery przedrostki działają dla każdego rozkładu znanego R: runif/dunif/punif/qunif, rbinom/dbinom/pbinom/qbinom i tak dalej.
Jak wylosować wiersze z ramki danych w R?
Zaindeksuj wiersze przez sample(): df[sample(nrow(df), 5), ] wybiera 5 wierszy bez zwracania. Dodaj replace = TRUE, żeby losować ze zwracaniem (na tym opiera się bootstrap).