Nếu tôi hiểu chính xác về bạn, bạn muốn lấy mẫu các giá trị từ phân phối đa thức với xác suất sao cho , tuy nhiên bạn muốn phân phối bị cắt bớt nên cho tất cả .x1, Lọ , xkp1,…,pk∑ixi=nai≤xi≤bixi
Tôi thấy ba giải pháp (không thanh lịch như trong trường hợp không cắt ngắn):
- Chấp nhận từ chối. Mẫu từ đa cực không cắt, chấp nhận mẫu nếu nó phù hợp với ranh giới cắt, nếu không thì từ chối và lặp lại quy trình. Nó nhanh, nhưng có thể rất không hiệu quả.
rtrmnomReject <- function(R, n, p, a, b) {
x <- t(rmultinom(R, n, p))
x[apply(a <= x & x <= b, 1, all) & rowSums(x) == n, ]
}
- Mô phỏng trực tiếp. Mẫu trong thời trang tương tự như việc xử lý dữ-tạo, tức là đá cẩm thạch đơn mẫu từ một urn ngẫu nhiên và lặp lại quá trình này cho đến khi bạn lấy mẫu bi trong tổng số, nhưng khi bạn triển khai tổng số viên bi từ trao urn ( là đã tương đương với ) sau đó dừng vẽ từ urn như vậy. Tôi đã thực hiện điều này trong một kịch bản dưới đây.nxibi
# single draw from truncated multinomial with a,b truncation points
rtrmnomDirect <- function(n, p, a, b) {
k <- length(p)
repeat {
pp <- p # reset pp
x <- numeric(k) # reset x
repeat {
if (sum(x<b) == 1) { # if only a single category is left
x[x<b] <- x[x<b] + n-sum(x) # fill this category with reminder
break
}
i <- sample.int(k, 1, prob = pp) # sample x[i]
x[i] <- x[i] + 1
if (x[i] == b[i]) pp[i] <- 0 # if x[i] is filled do
# not sample from it
if (sum(x) == n) break # if we picked n, stop
}
if (all(x >= a)) break # if all x>=a sample is valid
# otherwise reject
}
return(x)
}
- Thuật toán đô thị. Cuối cùng, cách tiếp cận thứ ba và hiệu quả nhất sẽ là sử dụng thuật toán Metropolis . Thuật toán được khởi tạo bằng cách sử dụng mô phỏng trực tiếp (nhưng có thể được khởi tạo khác nhau) để vẽ mẫu đầu tiên . Trong các bước sau lặp lại: giá trị đề xuất
được chấp nhận là với xác suất , nếu không, giá trị được lấy đó là nơi, nơi. Như một đề xuất, tôi đã sử dụng hàm lấy giá trị và chuyển ngẫu nhiên từ 0 sang số trường hợp và chuyển nó sang danh mục khác.X1y=q(Xi−1)Xif(y)/f(Xi−1)Xi−1f(x)∝∏ipxii/xi!qXi−1
step
# draw R values
# 'step' parameter defines magnitude of jumps
# for Meteropolis algorithm
# 'init' is a vector of values to start with
rtrmnomMetrop <- function(R, n, p, a, b,
step = 1,
init = rtrmnomDirect(n, p, a, b)) {
k <- length(p)
if (length(a)==1) a <- rep(a, k)
if (length(b)==1) b <- rep(b, k)
# approximate target log-density
lp <- log(p)
lf <- function(x) {
if(any(x < a) || any(x > b) || sum(x) != n)
return(-Inf)
sum(lp*x - lfactorial(x))
}
step <- max(2, step+1)
# proposal function
q <- function(x) {
idx <- sample.int(k, 2)
u <- sample.int(step, 1)-1
x[idx] <- x[idx] + c(-u, u)
x
}
tmp <- init
x <- matrix(nrow = R, ncol = k)
ar <- 0
for (i in 1:R) {
proposal <- q(tmp)
prob <- exp(lf(proposal) - lf(tmp))
if (runif(1) < prob) {
tmp <- proposal
ar <- ar + 1
}
x[i,] <- tmp
}
structure(x, acceptance.rate = ar/R, step = step-1)
}
Thuật toán bắt đầu ở và sau đó đi lang thang xung quanh các khu vực phân phối khác nhau. Nó rõ ràng là nhanh hơn những cái trước, nhưng bạn cần nhớ rằng nếu bạn sử dụng nó để lấy mẫu số lượng nhỏ các trường hợp, thì bạn có thể kết thúc với các lần rút gần nhau. Một vấn đề khác là bạn cần quyết định về kích thước, tức là thuật toán nên nhảy lớn như thế nào - quá nhỏ có thể dẫn đến di chuyển chậm, quá lớn có thể dẫn đến đưa ra quá nhiều đề xuất không hợp lệ và từ chối chúng. Bạn có thể xem ví dụ về việc sử dụng nó dưới đây. Trên các ô bạn có thể thấy: mật độ biên ở hàng đầu tiên, traceplots ở hàng thứ hai và các ô hiển thị các bước nhảy tiếp theo cho các cặp biến.X1step
n <- 500
a <- 50
b <- 125
p <- c(1,5,2,4,3)/15
k <- length(p)
x <- rtrmnomMetrop(1e4, n, p, a, b, step = 15)
cmb <- combn(1:k, 2)
par.def <- par(mfrow=c(4,5), mar = c(2,2,2,2))
for (i in 1:k)
hist(x[,i], main = paste0("X",i))
for (i in 1:k)
plot(x[,i], main = paste0("X",i), type = "l", col = "lightblue")
for (i in 1:ncol(cmb))
plot(jitter(x[,cmb[1,i]]), jitter(x[,cmb[2,i]]),
type = "l", main = paste(paste0("X", cmb[,i]), collapse = ":"),
col = "gray")
par(par.def)
Vấn đề với lấy mẫu từ phân phối này là mô tả một chiến lược lấy mẫu rất kém hiệu quả nói chung. Hãy tưởng tượng rằng và , và gần với , trong trường hợp như vậy bạn muốn lấy mẫu cho các danh mục có xác suất khác nhau, nhưng mong muốn tương tự tần số cuối cùng. Trong trường hợp cực đoan, hãy tưởng tượng phân phối hai loại trong đó và ,p1≠⋯≠pka1=⋯=akb1=…bkaibip1≫p2a1≪a2b1≪b2, trong trường hợp như vậy, bạn mong đợi một sự kiện rất hiếm xảy ra (ví dụ thực tế về phân phối như vậy sẽ là nhà nghiên cứu lặp lại việc lấy mẫu cho đến khi anh ta tìm thấy mẫu phù hợp với giả thuyết của mình, vì vậy nó có liên quan nhiều đến gian lận hơn là lấy mẫu ngẫu nhiên) .
Phân phối sẽ ít gặp vấn đề hơn nếu bạn xác định nó là Rukhin (2007, 2008) trong đó bạn lấy mẫu các trường hợp cho mỗi danh mục, tức là mẫu theo tỷ lệ với 's.npipi
Rukhin, AL (2007). Thống kê đơn hàng bình thường và tổng các biến ngẫu nhiên hình học trong các vấn đề phân bổ điều trị. Số liệu thống kê & xác suất, 77 (12), 1312-1321.
Rukhin, AL (2008). Các quy tắc dừng trong các vấn đề phân bổ cân bằng: Phân phối chính xác và tiệm cận. Phân tích tuần tự, 27 (3), 277-292.