ค้นหาวิธีการจำลองตัวเลขสุ่มสำหรับการแจกแจงนี้


20

ฉันพยายามเขียนโปรแกรมใน R ที่จำลองตัวเลขสุ่มหลอกจากการแจกจ่ายด้วยฟังก์ชันการแจกแจงสะสม:

F(x)=1exp(axbp+1xp+1),x0

โดยที่a,b>0,p(0,1)

ฉันพยายามสุ่มตัวอย่างการแปลงผกผัน แต่การผกผันดูเหมือนจะไม่สามารถแก้ไขได้ ฉันจะดีใจถ้าคุณสามารถแนะนำวิธีแก้ปัญหานี้


1
มีเวลาไม่เพียงพอสำหรับคำตอบที่สมบูรณ์ แต่คุณสามารถตรวจสอบอัลกอริทึมของการสุ่มตัวอย่างสำคัญเป็นทางเลือก
chuse

1
มันไม่ใช่แบบฝึกหัดตำราเรียนฉันเพียง แต่กำหนดข้อ จำกัด เท่านั้นเนื่องจากเป็นข้อสันนิษฐานที่สมเหตุสมผลสำหรับข้อมูลของฉัน
Sebastian

6
จากนั้นฉันประหลาดใจที่การทำให้เป็นปกติ "ปาฏิหาริย์" โดย(p+1)1ที่เปลี่ยนการกระจายให้เป็นพลังที่สมบูรณ์แบบของเอกซ์โปเนนเชียล แต่ปาฏิหาริย์จะเกิดขึ้น
ซีอาน

คำตอบ:


49

มีวิธีแก้ปัญหาที่ตรงไปตรงมา (และถ้าฉันเพิ่ม, สง่างาม) สำหรับแบบฝึกหัดนี้: ตั้งแต่1F(x)จะปรากฏขึ้นเหมือนผลิตภัณฑ์ของการแจกแจงการอยู่รอดสอง:

(1F(x))=exp{axbp+1xp+1}=exp{ax}1F1(x)exp{bp+1xp+1}1F2(x)
F
X=min{X1,X2}X1F1,X2F2
F1E(a)F21/(p+1)E(b/(p+1))

รหัส R ที่เกี่ยวข้องนั้นง่ายอย่างที่ได้รับ

x=pmin(rexp(n,a),rexp(n,b/(p+1))^(1/(p+1))) #simulating an n-sample

และเร็วกว่าการแปลง pdf และการปฏิเสธการปฏิเสธแน่นอน:

> n=1e6
> system.time(results <- Vectorize(simulate,"prob")(runif(n)))
utilisateur     système      écoulé 
    89.060       0.072      89.124 
> system.time(x <- simuF(n,1,2,3))
utilisateur     système      écoulé 
     1.080       0.020       1.103 
> system.time(x <- pmin(rexp(n,a),rexp(n,b/(p+1))^(1/(p+1))))
utilisateur     système      écoulé 
     0.160       0.000       0.163 

ด้วยขนาดที่พอดีอย่างน่าประหลาดใจ:

ป้อนคำอธิบายรูปภาพที่นี่


5
ทางออกที่ยอดเยี่ยมจริงๆ!
เซบาสเตียน

14

คุณสามารถแก้ไขการแปลงผกผันเป็นตัวเลขได้เสมอ

ด้านล่างนี้ฉันทำการค้นหาแบบแบ่งส่วนแบบง่ายมาก สำหรับความน่าจะใส่ให้ (ผมใช้ตั้งแต่คุณมีในสูตรของคุณ) ผมเริ่มต้นด้วยและ 1 แล้วฉันเป็นสองเท่าจนกว่า Q สุดท้ายผมซ้ำแบ่งครึ่งช่วงจนกว่าความยาวสั้นกว่าและจุดกลางตอบสนองQqqpxL=0xR=1xRF(xR)>q[xL,xR]ϵxMF(xM)q

ECDF เหมาะกับของคุณดีพอสำหรับการเลือกและและมันเร็วพอสมควร คุณสามารถเพิ่มความเร็วได้โดยใช้การปรับให้เหมาะสมของนิวตันแทนการค้นหาแบบแบ่งส่วนอย่างง่ายFab

aa <- 2
bb <- 1
pp <- 0.1

cdf <- function(x) 1-exp(-aa*x-bb*x^(pp+1)/(pp+1))

simulate <- function(prob,epsilon=1e-5) {
    left <- 0
    right <- 1
    while ( cdf(right) < prob ) right <- 2*right

    while ( right-left>epsilon ) {
        middle <- mean(c(left,right))
        value_middle <- cdf(middle)
        if ( value_middle < prob ) left <- middle else right <- middle
    }

    mean(c(left,right))
}

set.seed(1)
results <- Vectorize(simulate,"prob")(runif(10000))
hist(results)

xx <- seq(0,max(results),by=.01)
plot(ecdf(results))
lines(xx,cdf(xx),col="red")

ECDF


10

มีความซับซ้อนค่อนข้างถ้าการแก้ปัญหาโดยตรงโดยการยอมรับ - ปฏิเสธ ก่อนอื่นความแตกต่างอย่างง่ายแสดงให้เห็นว่าไฟล์ pdf ของการแจกแจงคือ วินาทีตั้งแต่ เรามีขอบเขตบน ประการที่สามพิจารณาเทอมที่สองในใช้การเปลี่ยนแปลงของตัวแปรคือ1)} จากนั้น คือ Jacobian แห่งการเปลี่ยนแปลงของตัวแปร ถ้า

f(x)=(a+bxp)exp{axbp+1xp+1}
f(x)=aeaxebxp+1/(p+1)1+bxpebxp+1/(p+1)eax1
f(x)g(x)=aeax+bxpebxp+1/(p+1)
gξ=xp+1x=ξ1/(p+1)
dxdξ=1p+1ξ1p+11=1p+1ξpp+1
Xมีความหนาแน่นของรูปแบบโดยที่คือค่าคงที่ normalizing จากนั้นมีความหนาแน่น ซึ่งหมายความว่า (i)คือ กระจายเป็นเลขชี้กำลังแปรปรวนและ (ii) ค่าคงที่เท่ากับหนึ่ง ดังนั้นสิ้นสุดลงเท่ากับการกระจายน้ำหนักอย่างเท่าเทียมกันของเลขชี้กำลังและ -th อำนาจของเลขชี้กำลังκbxpebxp+1/(p+1)κΞ=X1/(p+1)
κbξpp+1ebξ/(p+1)1p+1ξpp+1=κbp+1ebξ/(p+1)
ΞE(b/(p+1))κg(x)E(a)1/(p+1)E(b/(p+1))การแจกแจงโมดูโลค่าคงที่การคูณที่ขาดหายไปของเพื่ออธิบายน้ำหนัก: และตรงไปตรงมาเพื่อจำลองเป็นส่วนผสม2
f(x)g(x)=2(12aeax+12bxpebxp+1/(p+1))
g

ดังนั้นการเรนเดอร์ R ของอัลกอริทึม accept-reject จึงเป็นเช่นนั้น

simuF <- function(a,b,p){
  reepeat=TRUE
  while (reepeat){
   if (runif(1)<.5) x=rexp(1,a) else
      x=rexp(1,b/(p+1))^(1/(p+1))
   reepeat=(runif(1)>(a+b*x^p)*exp(-a*x-b*x^(p+1)/(p+1))/
      (a*exp(-a*x)+b*x^p*exp(-b*x^(p+1)/(p+1))))}
  return(x)}

และสำหรับตัวอย่าง n:

simuF <- function(n,a,b,p){
  sampl=NULL
  while (length(sampl)<n){
   x=u=sample(0:1,n,rep=TRUE)
   x[u==0]=rexp(sum(u==0),b/(p+1))^(1/(p+1))
   x[u==1]=rexp(sum(u==1),a)
   sampl=c(sampl,x[runif(n)<(a+b*x^p)*exp(-a*x-b*x^(p+1)/(p+1))/
      (a*exp(-a*x)+b*x^p*exp(-b*x^(p+1)/(p+1)))])
   }
  return(sampl[1:n])}

นี่คือภาพประกอบสำหรับ a = 1, b = 2, p = 3:

ป้อนคำอธิบายรูปภาพที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.