Tạo số ngẫu nhiên sau phân phối trong một khoảng


17

Tôi cần tạo các số ngẫu nhiên theo phân phối chuẩn trong khoảng . (Tôi đang làm việc tại R.)(a,b)

Tôi biết hàm rnorm(n,mean,sd)sẽ tạo các số ngẫu nhiên theo phân phối bình thường, nhưng làm thế nào để đặt giới hạn khoảng trong đó? Có bất kỳ chức năng R cụ thể có sẵn cho điều đó?


tại sao bạn muốn làm việc này? Nếu nó bị ràng buộc thì nó không thể thực sự bình thường. Bạn đang cố gắng để đạt được điều gì?
gung - Phục hồi Monica

x <- rnorm(n, mean, sd); x <- x[x > lower.limit & x < upper.limit]
Hugh

3
@Hugh thật tuyệt ... miễn là bạn không quan tâm bạn nhận được bao nhiêu giá trị ngẫu nhiên.
Glen_b -Reinstate Monica

Câu trả lời:


31

Có vẻ như bạn muốn mô phỏng từ một bản phân phối bị cắt cụt , và trong ví dụ cụ thể của bạn, một bình thường bị cắt cụt .

Có nhiều phương pháp để làm như vậy, một số đơn giản, một số tương đối hiệu quả.

Tôi sẽ minh họa một số cách tiếp cận trên ví dụ bình thường của bạn.

  1. Đây là một phương pháp rất đơn giản để tạo từng cái một (trong một số loại mã giả):

    repeat tạo từ N (trung bình, sd) thấp hơn trênxiuntilxi

    nhập mô tả hình ảnh ở đây

    Nếu hầu hết phân phối nằm trong giới hạn, điều này khá hợp lý nhưng nó có thể trở nên khá chậm nếu bạn gần như luôn tạo ra ngoài giới hạn.

    Trong R, bạn có thể tránh vòng lặp một lần bằng cách tính diện tích trong giới hạn và tạo đủ giá trị mà bạn có thể gần như chắc chắn rằng sau khi loại bỏ các giá trị bên ngoài giới hạn bạn vẫn có nhiều giá trị cần thiết.

  2. Bạn có thể sử dụng chấp nhận từ chối với một số chức năng chính phù hợp trong khoảng thời gian (trong một số trường hợp, đồng phục sẽ đủ tốt). Nếu các giới hạn được thu hẹp một cách hợp lý so với sd nhưng bạn không đi sâu vào đuôi, ví dụ, một chuyên ngành thống nhất sẽ hoạt động tốt với bình thường.

    nhập mô tả hình ảnh ở đây

  3. Nếu bạn có một cdf và cdf nghịch đảo hiệu quả hợp lý (chẳng hạn như pnormqnormđối với phân phối bình thường trong R), bạn có thể sử dụng phương pháp nghịch đảo cdf được mô tả trong đoạn đầu tiên của phần mô phỏng của trang Wikipedia trên bình thường bị cắt cụt . [Trong thực tế, điều này giống như lấy một bộ đồng phục bị cắt cụt (bị cắt ở các lượng tử yêu cầu, thực sự không yêu cầu từ chối, vì đó chỉ là một đồng phục khác) và áp dụng cdf bình thường ngược cho điều đó. Lưu ý rằng điều này có thể thất bại nếu bạn ở xa đuôi]

    nhập mô tả hình ảnh ở đây

  4. Có những cách tiếp cận khác; cùng một trang Wikipedia đề cập đến việc điều chỉnh phương pháp ziggurat , sẽ hoạt động cho nhiều bản phân phối khác nhau.

Các liên kết cùng Wikipedia đề cập đến hai gói cụ thể (cả trên cran) với các chức năng để tạo ra normals cắt ngắn:

Các MSMgói vào R có một chức năng, rtnorm, tính toán rút ra từ một bình thường cắt ngắn. Các truncnormgói vào R cũng có chức năng để vẽ từ một cắt ngắn bình thường.


Nhìn xung quanh, rất nhiều câu hỏi được đề cập trong các câu trả lời cho các câu hỏi khác (nhưng không trùng lặp chính xác vì câu hỏi này chung chung hơn là chỉ cắt ngắn bình thường) ... xem thêm thảo luận trong

a. Câu trả lời này

b. Câu trả lời của Xi'an ở đây , có liên kết đến bài viết arXiv của anh ấy (cùng với một số câu trả lời đáng giá khác).


2

Cách tiếp cận nhanh và bẩn là sử dụng quy tắc 68-95-99.7 .

Trong một phân phối bình thường, 99,7% giá trị nằm trong 3 độ lệch chuẩn của giá trị trung bình. Vì vậy, nếu bạn đặt giá trị trung bình của bạn ở giữa giá trị tối thiểu và giá trị tối đa mong muốn của bạn và đặt độ lệch chuẩn của bạn thành 1/3 giá trị trung bình của bạn, bạn sẽ nhận được (hầu hết) các giá trị nằm trong khoảng mong muốn. Sau đó, bạn có thể chỉ cần làm sạch phần còn lại.

minVal <- 0
maxVal <- 100
mn <- (maxVal - minVal)/2
# Generate numbers (mostly) from min to max
x <- rnorm(count, mean = mn, sd = mn/3)
# Do something about the out-of-bounds generated values
x <- pmax(minVal, x)
x <- pmin(maxVal, x)

Gần đây tôi đã phải đối mặt với vấn đề tương tự, cố gắng tạo các lớp học sinh ngẫu nhiên cho dữ liệu kiểm tra. Trong đoạn mã trên, tôi đã sử dụng pmaxpminđể thay thế các giá trị ngoài giới hạn bằng giá trị giới hạn tối thiểu hoặc tối đa. Điều này hoạt động cho mục đích của tôi, bởi vì tôi đang tạo ra một lượng dữ liệu khá nhỏ, nhưng với số lượng lớn hơn, nó sẽ mang lại cho bạn những va chạm đáng chú ý ở các giá trị tối thiểu và tối đa. Vì vậy, tùy thuộc vào mục đích của bạn, tốt hơn là loại bỏ các giá trị đó, thay thế chúng bằng NAs hoặc "cuộn lại" chúng cho đến khi chúng bị giới hạn.


Tại sao phải làm điều này? Thật đơn giản để tạo ra các số ngẫu nhiên bình thường và loại bỏ những số cần cắt bớt mà không cần phải phức tạp về nó trừ khi việc cắt ngắn mong muốn là gần 100% diện tích của mật độ.
Carl

2
Có lẽ tôi đang hiểu sai câu hỏi ban đầu. Tôi đã gặp câu hỏi này trong khi cố gắng tìm ra cách để đạt được một nhiệm vụ lập trình không liên quan đến thống kê trong R và bây giờ tôi chỉ nhận thấy trang này là một stackexchange, không phải là stackexchange. :) Trong trường hợp của tôi, tôi muốn tạo một số lượng số nguyên ngẫu nhiên cụ thể, với các giá trị nằm trong khoảng từ 0 đến 100 và tôi muốn các giá trị được tạo rơi vào một đường cong hình chuông đẹp trong phạm vi đó. Kể từ khi viết bài này, tôi nhận ra rằng sample(x=min:max, prob=dnorm(...))có lẽ là một cách dễ dàng hơn để làm điều đó.
Aaron Wells

@Glen_b Aaron Wells đề cập sample(x=min:max, prob=dnorm(...))có vẻ ngắn hơn câu trả lời của bạn một chút.
Carl

Nhưng lưu ý rằng sample()mẹo này chỉ hữu ích nếu bạn đang cố chọn các số nguyên ngẫu nhiên hoặc một số giá trị khác được xác định trước.
Aaron Wells

1

a<b

ΦX1,...,XNμσ2a<b

Xi=μ+σΦ1(Ui)U1,...,UNIID U[Φ(aμσ),Φ(bμσ)].

Không có hàm inbuilt cho các giá trị được tạo từ phân phối bị cắt cụt, nhưng việc lập trình phương thức này bằng các hàm thông thường để tạo các biến ngẫu nhiên là chuyện nhỏ. Đây là một Rhàm đơn giản rtruncnormthực hiện phương thức này trong một vài dòng mã.

rtruncnorm <- function(N, mean = 0, sd = 1, a = -Inf, b = Inf) {
  if (a > b) stop('Error: Truncation range is empty');
  U <- runif(N, pnorm(a, mean, sd), pnorm(b, mean, sd));
  qnorm(U, mean, sd); }

Đây là một hàm vectơ sẽ tạo ra Ncác biến ngẫu nhiên IID từ phân phối chuẩn bị cắt ngắn. Sẽ dễ dàng lập trình các chức năng cho các bản phân phối bị cắt ngắn khác thông qua cùng một phương thức. Nó cũng sẽ không quá khó để lập trình các hàm mật độ và lượng tử liên quan cho phân phối bị cắt cụt.


μσ2

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.