Monte Carlo Simulation을 사용한 대략적인


35

최근에 Monte Carlo 시뮬레이션을 살펴보고 (사각형 내부의 원, 비례 영역) 와 같은 상수를 근사화하는 데 사용했습니다 .π

그러나 Monte Carlo 통합을 사용하여 [Euler 's number]의 값을 근사하는 해당 방법을 생각할 수 없습니다 .e

이 작업을 수행하는 방법에 대한 조언이 있습니까?


7
이를 수행하는 방법은 여러 가지가 있습니다. 이것은 R명령 2 + mean(exp(-lgamma(ceiling(1/runif(1e5))-1)))이 수행 하는 것을 고려함으로써 분명해질 수 있습니다 . (로그 감마 함수를 사용하면 문제가 2 + mean(1/factorial(ceiling(1/runif(1e5))-2))발생하는 경우 덧셈, 곱하기, 나누기 및 잘림 만 사용하고 오버플로 경고를 무시하는로 대체하십시오 .) 더 중요한 관심사는 효율적인 시뮬레이션입니다. 를 주어진 정확도 로 추정하는 데 필요한 계산 단계 ? e
whuber

4
유쾌한 질문입니다! 다른 사람의 답변을 기다리겠습니다. whuber가 제안한 것처럼 이 질문에 실제로 관심을 끌 수있는 한 가지 방법은 아마도 다른 여섯 가지 답변 중 하나 인 질문을 수정하고 효율적인 답변을 요청하는 입니다. CV 사용자를위한 catnip과 같습니다.
복원 Monica Monica

1
@EngrStudent 대한 기하학적 아날로그가 있는지 확실하지 않습니다 . 와 같이 자연적으로 (pun 의도 된) 기하학적 양이 아닙니다 . πeπ
Aksakal

6
@ Aksakal 는 매우 기하학적 인 수량입니다. 가장 기본적인 수준에서는 쌍곡선과 관련된 영역의 표현에 자연스럽게 나타납니다. 약간 더 고급 수준에서는 기하학적 내용이 분명한 삼각 함수를 포함하여 모든 주기적 함수와 밀접하게 연결되어 있습니다. 여기서 진짜 도전은 와 관련된 값을 시뮬레이션 하는 것이 너무 쉽다 는 것입니다 ! ee
whuber

2
@StatsStudent : 자체는 흥미롭지 않습니다. 그러나 이것이 와 같은 양의 편견 추정량을 초래하는 경우 MCMC 알고리즘에 가장 유용 할 수 있습니다. exp { x 0 f ( y ) d G ( y ) }e
exp{0xf(y)dG(y)}
시안

답변:


34

Monte Carlo가 를 추정하는 간단하고 우아한 방법 은 이 백서에 설명되어 있습니다. 이 논문은 실제로 를 가르치는 것에 관한 것 입니다. 따라서 접근 방식이 목표에 완벽하게 적합한 것으로 보입니다. 이 아이디어 는 Gnedenko의 확률 이론에 대한 인기있는 러시아 교과서 의 연습을 기반으로합니다 . p.183의 22 번 참조ee

너무 일어나는 , 다음과 같이 정의 된 랜덤 변수이다. 의 최소 ​​개수입니다ξE[ξ]=eξ 되도록 Σ N = 1 개 R I > (1) r에 제가 균일 한 분포로부터 무작위 숫자 [ 0 , 1 ] . 아름답 지 않습니까?!ni=1nri>1ri[0,1]

연습 문제이므로 여기에 해결책을 게시하는 것이 멋진 지 잘 모르겠습니다. 올바른 방향으로.

직접 구현하려면 더 이상 읽지 마십시오!

이것은 Monte Carlo 시뮬레이션을위한 간단한 알고리즘입니다. 합계가 1을 초과 할 때까지 균일 한 무작위를 그린 다음 다른 하나를 그립니다. 당신이 가지고 있다고 가정 해 봅시다 :

 0.0180
 0.4596
 0.7920

그런 다음 첫 번째 평가판은 3을 렌더링했습니다. 이러한 평가판을 계속 수행하면 평균적으로 됩니다.e

MATLAB 코드, 시뮬레이션 결과 및 히스토그램이 이어집니다.

N = 10000000;
n = N;
s = 0;
i = 0;
maxl = 0;
f = 0;
while n > 0
    s = s + rand;
    i = i + 1;
    if s > 1
        if i > maxl
            f(i) = 1;
            maxl = i;
        else
            f(i) = f(i) + 1;
        end
        i = 0;
        s = 0;
        n = n - 1;
    end
end

disp ((1:maxl)*f'/sum(f))
bar(f/sum(f))
grid on

f/sum(f)

결과 및 히스토그램 :

2.7183


ans =

  Columns 1 through 8

         0    0.5000    0.3332    0.1250    0.0334    0.0070    0.0012    0.0002

  Columns 9 through 11

    0.0000    0.0000    0.0000

여기에 이미지 설명을 입력하십시오

업데이트 : 시험 결과 배열을 제거하여 RAM을 사용하지 않도록 코드를 업데이트했습니다. 또한 PMF 추정치를 인쇄했습니다.

업데이트 2 : 여기 내 Excel 솔루션이 있습니다. Excel에 버튼을 넣고 다음 VBA 매크로에 연결하십시오.

Private Sub CommandButton1_Click()
n = Cells(1, 4).Value
Range("A:B").Value = ""
n = n
s = 0
i = 0
maxl = 0
Cells(1, 2).Value = "Frequency"
Cells(1, 1).Value = "n"
Cells(1, 3).Value = "# of trials"
Cells(2, 3).Value = "simulated e"
While n > 0
    s = s + Rnd()
    i = i + 1
    If s > 1 Then
        If i > maxl Then
            Cells(i, 1).Value = i
            Cells(i, 2).Value = 1
            maxl = i
        Else
            Cells(i, 1).Value = i
            Cells(i, 2).Value = Cells(i, 2).Value + 1
        End If
        i = 0
        s = 0
        n = n - 1
    End If
Wend


s = 0
For i = 2 To maxl
    s = s + Cells(i, 1) * Cells(i, 2)
Next


Cells(2, 4).Value = s / Cells(1, 4).Value

Rem bar (f / Sum(f))
Rem grid on

Rem f/sum(f)

End Sub

셀 D1에 시행 횟수 (예 : 1000)를 입력하고 버튼을 클릭하십시오. 다음은 첫 실행 후 화면이 어떻게 표시되는지 보여줍니다.

여기에 이미지 설명을 입력하십시오

업데이트 3 : Silverfish는 첫 번째만큼 우아하지는 않지만 여전히 멋진 다른 방법으로 영감을 얻었습니다. Sobol 시퀀스를 사용하여 n-simplex의 부피를 계산했습니다 .

s = 2;
for i=2:10
    p=sobolset(i);
    N = 10000;
    X=net(p,N)';
    s = s + (sum(sum(X)<1)/N);
end
disp(s)

2.712800000000001

우연히 그는 고등학교에서 읽은 Monte Carlo 방법에 관한 첫 번째 을 썼습니다 . 내 의견으로는 방법에 대한 가장 좋은 소개입니다.

업데이트 4 :

주석에서 Silverfish는 간단한 Excel 수식 구현을 제안했습니다. 이것은 약 백만 개의 임의의 숫자와 185K의 시도 후에 그의 접근 방식으로 얻는 종류의 결과입니다.

여기에 이미지 설명을 입력하십시오

분명히 이것은 Excel VBA 구현보다 훨씬 느립니다. 특히 루프 내 셀 값을 업데이트하지 않도록 VBA 코드를 수정하고 모든 통계가 수집 된 후에 만 ​​수행하는 경우.

업데이트 5

Xi'an의 솔루션 # 3은 밀접하게 관련되어 있습니다 (또는 스레드에서 jwg의 의견에 따라 어떤 의미에서도 동일합니다). 누가 먼저 Forsythe 또는 Gnedenko 아이디어를 생각해 냈는지 말하기는 어렵습니다. 러시아어로 작성된 Gnedenko의 1950 년판에는 챕터에 문제 섹션이 없습니다. 따라서이 문제가 이후 버전에있는 경우 한눈에 찾을 수 없었습니다. 나중에 추가되거나 텍스트에 묻 혔을 수 있습니다.

Xi'an의 답변에서 언급했듯이 Forsythe의 접근법은 또 다른 흥미로운 영역과 관련이 있습니다. 임의 (IID) 시퀀스에서 피크 (극단) 사이의 거리 분포. 평균 거리는 3입니다. Forsythe의 접근 방식의 다운 시퀀스는 바닥으로 끝나므로 샘플링을 계속하면 어떤 지점에서 또 다른 바닥을 얻을 수 있습니다. 그런 다음 다른 지점을 얻을 수 있습니다. 이들 사이의 거리를 추적하고 분포를 구축 할 수 있습니다.


우와 짱이다! 왜 이것이 효과가 있는지 설명하는 단락을 추가 할 수 있습니까?
복원 Monica Monica

7
(+1) 훌륭합니다! 답변은 균일 한 시뮬레이션에만 의존하기 때문에 가장 높은 점수를받을 가치가 있습니다. 그리고 Monte Carlo로 인한 근사값을 사용하지 않습니다. 그것이 Gnedenko와 다시 연결된다는 것은 또 다른 특권입니다.
시안

2
Mean[Table[ Length[NestWhileList[(Random[]+#) &, Random[], #<1&]], {10^6}]]

4
@wolfies RXi'an의 답변에 게시 한 솔루션을 다음과 같이 직접 번역하면 20 배 더 빠릅니다.n=10^6; 1. / Mean[UnitStep[Differences[Sort[RandomReal[{0, n}, n + 1]]] - 1]]
whuber

1
e

19

Aksakal의 답변을지지하는 것이 좋습니다. 그것은 편향되지 않고 단위 유니폼 편차를 생성하는 방법에만 의존합니다.

e

loge

추정e

nni1n1np=(11n)n.

exp(1)=limn(11n)n

exp(1)p^=i=1mIiBjm

pmBji

np^

eπ

결과

다양한 부트 스트랩 복제에 대해 여러 시뮬레이션을 수행했습니다. 표준 오차는 정규 간격을 사용하여 추정됩니다.

nppnnen=103p1e

mp^pep^여기에 이미지 설명을 입력하십시오

나는 이것을 위해 매우 긴 R 스크립트를 썼다. 개선 제안은 $ 20 청구서 뒷면에 제출할 수 있습니다.

library(boot)
library(plotrix)
n <- 1e3

## if p_hat is estimated with 0 variance (in the limit of infinite bootstraps), then the best estimate we can come up with is biased by exactly this much:
approx <- 1/((1-1/n)^n)

dat <- c("A", rep("B", n-1))
indicator <- function(x, ndx)   xor("A"%in%x[ndx], TRUE) ## Because we want to count when "A" is *not* in the bootstrap sample

p_hat <- function(dat, m=1e3){
    foo <- boot(data=dat, statistic=indicator, R=m) 
    1/mean(foo$t)
} 

reps <- replicate(100, p_hat(dat))

boxplot(reps)
abline(h=exp(1),col="red")

p_mean <- NULL
p_var <- NULL
for(i in 1:10){
    reps <- replicate(2^i, p_hat(dat))
    p_mean[i] <- mean(reps)
    p_var[i] <- sd(reps)
}
plotCI(2^(1:10), p_mean, uiw=qnorm(0.975)*p_var/sqrt(2^(1:10)),xlab="m", log="x", ylab=expression(hat(p)), main=expression(paste("Monte Carlo Estimates of ", tilde(e))))
abline(h=approx, col='red')

4
+1 많은 의미가 있습니다. 코드를 작성한 경우 코드를 공유 할 수 있습니까?
Antoni Parellada 2016

2
ee

1
확실한. 다른 호출 내부에서 한 번의 복제 호출로 끝날 수 있습니다. 이는 현재와 동일합니다.
복원 Monica Monica

1
ee

1
@jwg 개념적으로 중요 할뿐만 아니라 근사치에 근사값을 구현하려면 두 근사값 각각이 얼마나 정확한지 추적해야하기 때문에 실제로 중요합니다. 그러나 두 근사치 모두 수용 가능할 때 전체 접근 방식이 실제로 양호하다는 데 동의해야합니다.
whuber

14

해결책 1 :

P(λ)

P(X=k)=λkk!eλ
XP(1)
P(X=0)=P(X=1)=e1
e1

U(i:n)U(i1:n)B(1,n)

P(n{U(i:n)U(i1:n)}1)=(11n)n
e1n

해결책 2 :

e

X1,X2iidN(0,1)
(X12+X22)χ12
E(1/2)
P(X12+X222)=1{1exp(2/2)}=e1
e(X1,X2)X12+X222πX12+X22<1

해결책 3 :

u1,u2,...un+1>unNeNe1expG(x)ee1

1/n!n

Forsythe 방법의 빠른 R 구현은 더 큰 블록을 선호하는 균일 한 시퀀스를 정확하게 따르지 않고 병렬 처리가 가능합니다.

use=runif(n)
band=max(diff((1:(n-1))[diff(use)>0]))+1
bends=apply(apply((apply(matrix(use[1:((n%/%band)*band)],nrow=band),
2,diff)<0),2,cumprod),2,sum)

12
e

5
eE(1)loge1P(1)

5
logexpn <- 1e5; 1/mean(n*diff(sort(runif(n+1))) > 1)

3
xnnxixn1n1xi1nxi1n1xi

3
n+1n

7

해결책이 아닙니다 ... 댓글 상자에 너무 긴 빠른 메모입니다.

악사 칼

Aksakal은 합이 1을 초과하도록 가져와야 할 표준 균일 도면의 예상 수를 계산하는 솔루션을 게시했습니다. Mathematica 에서 첫 번째 공식은 다음과 같습니다.

mrM := NestWhileList[(Random[] + #) &, Random[], #<1 &]

Mean[Table[Length[mrM], {10^6}]] 

편집 : 이것으로 빨리 놀았으며 다음 코드 (Mma에서 동일한 코드-다른 코드)는 약 10 배 빠릅니다.

Mean[Table[Module[{u=Random[], t=1},  While[u<1, u=Random[]+u; t++]; t] , {10^6}]]

시안 / 우버

Whuber는 Xian의 솔루션 1을 시뮬레이트하기위한 빠른 멋진 코드를 제안했습니다.

R 버전 : n <- 1e5; 1/mean(n*diff(sort(runif(n+1))) > 1)

MMA 버전 : n=10^6; 1. / Mean[UnitStep[Differences[Sort[RandomReal[{0, n}, n + 1]]] - 1]]

그는 첫 번째 코드보다 20 배 빠르며 (또는 위의 새 코드보다 약 2 배 빠릅니다).

재미로, 두 가지 접근 방식이 모두 통계적 측면에서 효율적인지 확인하는 것이 흥미로울 것이라고 생각했습니다. 이를 위해 다음을 사용하여 e의 2000 추정치를 생성했습니다.

  • 악사 칼의 방법 : dataA
  • whuber 코드를 사용하는 Xian의 방법 1 : dataB

... Mathematica 에서 둘 다 . 다음 다이어그램은 결과 데이터 A 및 데이터 B 데이터 세트의 비모수 커널 밀도 추정치를 대조합니다.

여기에 이미지 설명을 입력하십시오

따라서 whuber의 코드 (빨간색 곡선)는 약 두 배 빠르지 만이 방법은 '신뢰할 수있는 것처럼 보이지 않습니다.


실제 값의 위치에 세로선이 있으면이 이미지가 크게 향상됩니다.
복원 Monica Monica

1
매우 흥미로운 관찰입니다. 감사합니다. 절반 너비는 시뮬레이션의 크기에 따라 2 차적으로 확장되며 Xi'an 방법의 절반 너비는 Aksakal보다 약 2 배이므로 4 배 많은 반복을 실행하면 동일하게 정확하게됩니다. 각 반복에 얼마나 많은 노력이 필요한지에 대한 의문이 남아 있습니다. Xi'an의 방법을 한 번의 반복으로 4 분의 1 미만의 노력으로도이 방법은 여전히 ​​더 효율적입니다.
whuber

1
n

1
running four times as many iterations will make them equally accurate106106

1
코드를 잘 처리하면 많은 부분을 개선하기가 어려울 것입니다.
whuber

2

불신 한 양의 샘플이 필요한 방법

f(x)=exx¯12n˙N(0,1)e

N(0,1)ex

N(0,1)ϕ^(x)ϕ((2))=(2π)1/2e1e=ϕ^(2)2π

완전히 견디고 싶다면 추정 할 수도 있습니다.22π

샘플이 거의 필요하지 않지만 불필요하게 많은 양의 숫자 오류가 발생하는 방법

내가 작성한 의견을 바탕으로 완전히 어리석지 만 매우 효율적인 답변 :

Xuniform(1,1)Yn=|(x¯)n|e^=(1Yn)1/Yn

이것은 매우 빠르게 수렴 되지만 극단적 인 수치 오류가 발생합니다.

Yn1/YnnYnYn=0e


2
e

1
@ whuber : 필자가 필자의 책에서 지수로 직접 변환해야하기 때문에 Box-Muller를 사용하지 않았습니다. 나는 cos와 sin을 반사적으로 허용했을 것입니다 . 그러나 그것은 단지 복잡한 분석에 대해 잠시 잊어 버렸기 때문입니다.
Cliff AB

1
n1n2ϕ(2)n1n2en2n1

2

속도가 느리지 만 여기에 또 다른 방법이 있습니다. 나는 효율성을 주장하지는 않지만 완전성의 정신으로이 대안을 제시한다.

nU1,,UnIID U(0,1)e

E(I(Ui1/e)Ui)=1/e1duu=1.

eu(1)u(n)

Sn(k)1ni=1k1u(i)for all k=1,..,n.

mmin{k|S(k)1}1/ee

e^2u(m)+u(m+1).

1/eee

R에서의 구현 : 이 방법은 균일 한 값을 생성하기 위해 R사용하여 구현 될 수있다 runif. 코드는 다음과 같습니다.

EST_EULER <- function(n) { U <- sort(runif(n), decreasing = TRUE);
                           S <- cumsum(1/U)/n;
                           m <- min(which(S >= 1));
                           2/(U[m-1]+U[m]); }

e

set.seed(1234);

EST_EULER(10^3);
[1] 2.715426

EST_EULER(10^4);
[1] 2.678373

EST_EULER(10^5);
[1] 2.722868

EST_EULER(10^6); 
[1] 2.722207

EST_EULER(10^7);
[1] 2.718775

EST_EULER(10^8);
[1] 2.718434

> exp(1)
[1] 2.718282

e

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.