최근에 Monte Carlo 시뮬레이션을 살펴보고 (사각형 내부의 원, 비례 영역) 와 같은 상수를 근사화하는 데 사용했습니다 .
그러나 Monte Carlo 통합을 사용하여 [Euler 's number]의 값을 근사하는 해당 방법을 생각할 수 없습니다 .
이 작업을 수행하는 방법에 대한 조언이 있습니까?
최근에 Monte Carlo 시뮬레이션을 살펴보고 (사각형 내부의 원, 비례 영역) 와 같은 상수를 근사화하는 데 사용했습니다 .
그러나 Monte Carlo 통합을 사용하여 [Euler 's number]의 값을 근사하는 해당 방법을 생각할 수 없습니다 .
이 작업을 수행하는 방법에 대한 조언이 있습니까?
답변:
Monte Carlo가 를 추정하는 간단하고 우아한 방법 은 이 백서에 설명되어 있습니다. 이 논문은 실제로 를 가르치는 것에 관한 것 입니다. 따라서 접근 방식이 목표에 완벽하게 적합한 것으로 보입니다. 이 아이디어 는 Gnedenko의 확률 이론에 대한 인기있는 러시아 교과서 의 연습을 기반으로합니다 . p.183의 22 번 참조
너무 일어나는 , 다음과 같이 정의 된 랜덤 변수이다. 의 최소 개수입니다ξ 되도록 Σ N 난 = 1 개 R I > (1) 및 r에 제가 균일 한 분포로부터 무작위 숫자 [ 0 , 1 ] . 아름답 지 않습니까?!
연습 문제이므로 여기에 해결책을 게시하는 것이 멋진 지 잘 모르겠습니다. 올바른 방향으로.
직접 구현하려면 더 이상 읽지 마십시오!
이것은 Monte Carlo 시뮬레이션을위한 간단한 알고리즘입니다. 합계가 1을 초과 할 때까지 균일 한 무작위를 그린 다음 다른 하나를 그립니다. 당신이 가지고 있다고 가정 해 봅시다 :
0.0180
0.4596
0.7920
그런 다음 첫 번째 평가판은 3을 렌더링했습니다. 이러한 평가판을 계속 수행하면 평균적으로 됩니다.
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의 접근 방식의 다운 시퀀스는 바닥으로 끝나므로 샘플링을 계속하면 어떤 지점에서 또 다른 바닥을 얻을 수 있습니다. 그런 다음 다른 지점을 얻을 수 있습니다. 이들 사이의 거리를 추적하고 분포를 구축 할 수 있습니다.
R
Xi'an의 답변에 게시 한 솔루션을 다음과 같이 직접 번역하면 20 배 더 빠릅니다.n=10^6; 1. / Mean[UnitStep[Differences[Sort[RandomReal[{0, n}, n + 1]]] - 1]]
Aksakal의 답변을지지하는 것이 좋습니다. 그것은 편향되지 않고 단위 유니폼 편차를 생성하는 방법에만 의존합니다.
다양한 부트 스트랩 복제에 대해 여러 시뮬레이션을 수행했습니다. 표준 오차는 정규 간격을 사용하여 추정됩니다.
나는 이것을 위해 매우 긴 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')
해결책 1 :
해결책 2 :
해결책 3 :
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)
해결책이 아닙니다 ... 댓글 상자에 너무 긴 빠른 메모입니다.
악사 칼
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 추정치를 생성했습니다.
... Mathematica 에서 둘 다 . 다음 다이어그램은 결과 데이터 A 및 데이터 B 데이터 세트의 비모수 커널 밀도 추정치를 대조합니다.
따라서 whuber의 코드 (빨간색 곡선)는 약 두 배 빠르지 만이 방법은 '신뢰할 수있는 것처럼 보이지 않습니다.
불신 한 양의 샘플이 필요한 방법
완전히 견디고 싶다면 추정 할 수도 있습니다.
샘플이 거의 필요하지 않지만 불필요하게 많은 양의 숫자 오류가 발생하는 방법
내가 작성한 의견을 바탕으로 완전히 어리석지 만 매우 효율적인 답변 :
이것은 매우 빠르게 수렴 되지만 극단적 인 수치 오류가 발생합니다.
속도가 느리지 만 여기에 또 다른 방법이 있습니다. 나는 효율성을 주장하지는 않지만 완전성의 정신으로이 대안을 제시한다.
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]); }
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
R
명령2 + mean(exp(-lgamma(ceiling(1/runif(1e5))-1)))
이 수행 하는 것을 고려함으로써 분명해질 수 있습니다 . (로그 감마 함수를 사용하면 문제가2 + mean(1/factorial(ceiling(1/runif(1e5))-2))
발생하는 경우 덧셈, 곱하기, 나누기 및 잘림 만 사용하고 오버플로 경고를 무시하는로 대체하십시오 .) 더 중요한 관심사는 효율적인 시뮬레이션입니다. 를 주어진 정확도 로 추정하는 데 필요한 계산 단계 ?