2010-02-17 16 views
5

Załóżmy, że mam dwuwymiarowy dyskretny rozkład, tj. Tabelę wartości prawdopodobieństwa P (X = i, Y = j), dla i = 1, ... n i j = 1 ,. ..m. Jak wygenerować losową próbkę (X_k, Y_k), k = 1, ... N z takiej dystrybucji? Może istnieje gotowa funkcja R, taka jak:Losowa próbka z danego dwuwymiarowego dyskretnego rozkładu

sample(100,prob=biprob) 

gdzie biprob jest dwuwymiarową matrycą?

Jeden intuicyjny sposób próbkowania jest następujący. Załóżmy, że mamy data.frame

dt=data.frame(X=x,Y=y,P=pij) 

gdzie x i y pochodzą z

expand.grid(x=1:n,y=1:m) 

są pij i P (X = I, Y = J).

Wtedy dostajemy naszą próbkę (Xs, Ys) o rozmiarze N, w następujący sposób:

set.seed(1000) 
Xs <- sample(dt$X,size=N,prob=dt$P) 
set.seed(1000) 
Ys <- sample(dt$Y,size=N,prob=dt$P) 

używam set.seed(), aby symulować "bivariateness". Intuicyjnie powinienem dostać coś podobnego do tego, czego potrzebuję. Nie jestem pewien, czy to prawda. Stąd pytanie :)

Innym sposobem jest użycie próbkowania Gibbs, dystrybucje marginalne są łatwe do obliczenia.

Próbowałem googling, ale nic naprawdę istotne nie podszedł.

Odpowiedz

7

Już prawie jesteś. Zakładając, że masz ramkę danych dt z wartościami x, y i pij, po prostu próbkuj wiersze!

dt <- expand.grid(X=1:3, Y=1:2) 
dt$p <- runif(6) 
dt$p <- dt$p/sum(dt$p) # get fake probabilities 
idx <- sample(1:nrow(dt), size=8, replace=TRUE, prob=dt$p) 
sampled.x <- dt$X[idx] 
sampled.y <- dt$Y[idx] 
+0

przeczytaniu tego ponownie starannie, jest to ta sama rozwiązanie jak to, co sugeruję. Próbkowanie rzędów jest prawdopodobnie czystsze niż łączenie rmultinom i które. Kluczem jest uświadomienie sobie, że wiersze i kolumny są po prostu notacją. – Tristan

+0

Tak, zapis jest kluczem. Dwuwymiarowa dyskretna dystrybucja jest taka sama jak jednokierunkowa dyskretna dystrybucja z notacją zmienioną. Wybieram odpowiedź Aniki jako prawidłową, ale tylko dlatego, że kod jest prostszy :) Tristan daje lepsze wyjaśnienie teoretyczne. – mpiktas

+0

+1 za ładny przykład – andi

7

Nie jest dla mnie jasne, dlaczego warto zadbać o to, aby był dwucyfrowy. Prawdopodobieństwa sumują się do jednego, a wyniki są dyskretne, więc po prostu próbujesz z categorical distribution. Jedyną różnicą jest to, że indeksujesz obserwacje za pomocą wierszy i kolumn zamiast jednej pozycji. To jest po prostu notacja.

W R można w prosty sposób pobierać próbki z dystrybucji, przekształcając dane i próbkowanie z dystrybucji kategorycznej. Próbkowanie z kategorii można wykonać przy użyciu rmultinom i używając which, aby wybrać indeks, lub, jak sugeruje Aniko, używając sample do wypróbowania wierszy przekształconych danych. Niektóre księgi rachunkowe mogą zająć się twoją dokładną sprawą.

Oto rozwiązanie:

library(reshape) 

# Reshape data to long format. 
data <- matrix(data = c(.25,.5,.1,.4), nrow=2, ncol=2) 
pmatrix <- melt(data) 

# Sample categorical n times. 
rcat <- function(n, pmatrix) { 
    rows <- which(rmultinom(n,1,pmatrix$value)==1, arr.ind=TRUE)[,'row'] 
    indices <- pmatrix[rows, c('X1','X2')] 
    colnames(indices) <- c('i','j') 
    rownames(indices) <- seq(1,nrow(indices)) 
    return(indices) 
} 

rcat(3,pmatrix) 

ta zwraca 3 random czerpie ze swojej matrycy, zgłoszenie i i j z wierszy i kolumn:

i j 
1 1 1 
2 2 2 
3 2 2