蒙特卡罗积分是一种基于随机抽样的统计方法。打个比方,要想知道抛出硬币得到正面的概率,随机投1000次,得到500次左右,推测出概率应该为 1 2 \frac{1}{2} 21。差不多是这意思,比较著名的例子是W.S.戈塞特使用随机抽样来研究现在被称为“学生t”统计数据的分布。随着计算机的出现及发展,该方法也得到发展。
概述 ∫ a b g ( x ) d x \int_a^b g(x)dx ∫abg(x)dx
理论基础:如果X是一个随机变量,其密度函数为 f ( x ) f(x) f(x),那么随机变量 Y = g ( X ) Y=g(X) Y=g(X)的数学期望为 E [ g ( X ) ] = ∫ − ∞ ∞ g ( x ) f ( x ) d x E[g(X)]=\int_{-\infty}^{\infty} g(x)f(x)dx E[g(X)]=∫−∞∞g(x)f(x)dx
那么获得服从随机变量X分布的随机数,那么所求的 E [ g ( x ) ] E[g(x)] E[g(x)] 就是该样本均值的无偏估计。
计算(积分上下界为0-1) θ = ∫ 0 1 g ( x ) d x \theta=\int_0^1 g(x)dx θ=∫01g(x)dx, 求 θ \theta θ。
这么想: ∫ 0 1 g ( x ) d x = ∫ 0 1 g ( x ) × 1 d x \int_0^1g(x)dx=\int_0^1g(x) \times 1dx ∫01g(x)dx=∫01g(x)×1dx套上面的意思,假定X服从均匀分布 U(0,1),那么 f ( x ) = 1 f(x)=1 f(x)=1, 那么生成该均匀分布的随机数,代入 g ( x ) g(x) g(x)式子中,则
θ = g ( x ) ‾ = 1 N ∑ 0 N g ( x i ) \theta = \overline{g(x)}=\frac{1}{N}\sum_0^Ng(x_i) θ=g(x)=N10∑Ng(xi)
计算(积分上下界为a-b) ∫ a b g ( t ) d t \int_a^bg(t)dt ∫abg(t)dt为了让积分上下限变为0和1,做一个变量变换:
y = t − a b − a d y = 1 b − a d t y =\frac{t-a}{b-a}\\ dy=\frac{1}{b-a}dt y=b−at−ady=b−a1dt
像不像均匀分布分布函数表达式,对应地, ∫ a b g ( t ) d t = ∫ 0 1 1 b − a × ( y × ( b − a ) + a ) d t = ( b − a ) ∫ a b g ( t ) × 1 b − a d t \int_a^bg(t)dt=\int_0^1\frac{1}{b-a}\times(y\times(b-a)+a)dt\\ =(b-a)\int_a^bg(t)\times\frac{1}{b-a}dt ∫abg(t)dt=∫01b−a1×(y×(b−a)+a)dt=(b−a)∫abg(t)×b−a1dt
就可以看成要求随机变量g(Y)的均值,Y服从均匀分布U(a,b),积分结果就等于该均值再乘以(b-a)。
具体步骤图上写得很清楚,公式也太难敲了吧,手速有限。
计算(积分上下限存在无界情况咋办呢)
举个例子,
计算标准正态分布函数 ϕ ( x ) = ∫ − ∞ x 1 2 π e − t 2 2 d t \phi(x)=\int^x_{-\infty}\frac{1}{\sqrt{2\pi}}e^{-\frac{t^2}{2}}dt ϕ(x)=∫−∞x2π1e−2t2dt
这么想哈,求解可以分成两种情况(x>0 or x<0):
代码:
x <- seq(.1, 2.5, length = 10) #取十个x做做,算出十个值
m <- 10000
u <- runif(m)
cdf <- numeric(length(x))
for (i in 1:length(x)) {
g <- x[i] * exp(-(u * x[i])^2 / 2)
cdf[i] <- mean(g) / sqrt(2 * pi) + 0.5
}
#利用内置函数求精确解
Phi <- pnorm(x)
print(round(rbind(x, cdf, Phi), 3)) #对比分析一下,估计得蛮准
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
x 0.10 0.367 0.633 0.900 1.167 1.433 1.700 1.967 2.233 2.500
cdf 0.54 0.643 0.737 0.816 0.879 0.925 0.957 0.978 0.990 0.997
Phi 0.54 0.643 0.737 0.816 0.878 0.924 0.955 0.975 0.987 0.994
m <- 10000
x <- runif(m)
theta.hat <- mean(exp(-x))
print(theta.hat)
print(1 - exp(-1))
[1] 0.6355289 #估计值
[1] 0.6321206 #解析解
m <- 10000
x <- runif(m, min=2, max=4)
theta.hat <- mean(exp(-x)) * 2
print(theta.hat)
print(exp(-2) - exp(-4))
[1] 0.1172158
[1] 0.1170196
# 自己写的
N = 5000
x = runif(N)
y = runif(N)
count = 0
for(i in 1:N){
z = x[i]**2+y[i]**2
count[z<=1]=count+1
}
Pi = 4*count/N
Pi
[1] 3.1328
#老师写的,还画出来图
N = 10000
x = matrix(runif(N*2),N,2)
plot(x)
L = x[,1]^2+x[,2]^2<=1
points(x[L,], col="red")
n = sum(L)
p = 4*n/N
p
x = runif(3000,0,pi/3)
fx = sin(x)
Fx2 = -(cos(pi/3)-cos(0))
Fx = (pi/3)*mean(fx)
> Fx2 #解析解
[1] 0.5
> Fx #估计解
[1] 0.496512