蒙特卡洛法求积分

article/2025/8/21 18:13:49

问题一:我们如何用蒙特卡洛方法求积分?问题二:如何近似求一个随机变量的数学期望?问题三:估计的误差是多少?问题四:如何从理论上对蒙特卡洛估计做分析?结论

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('whitegrid')

问题一:我们如何用蒙特卡洛方法求积分?

你眼中的蒙特卡洛方法求积分,可能是这样子的:

Image Name

最最经典的例子就是求   的近似值了,生成若干个均匀的点,然后统计在圆内的点的个数的比例,这个比例就是   的近似了!
但是这种方法的计算量非常大,而且随着维数的增长需要的计算量也会成倍上升,收敛速度也并不快。

但是我要讲的蒙特卡洛求积跟这个些许不一样。

假如我想求    ,我们来用概率的语言表达一下它。
设随机变量    ,即   上的均匀分布,   具有密度函数    。
那么就有:   ,这个公式是下面推导中非常重要的一环。
事实上,借助这个公式,我们将求积分转化为求某个随机变量的数学期望

接下来我们就可以用统计学的手段来处理了。

问题二:如何近似求一个随机变量的数学期望?

通常情况下,    都是一个比较复杂的函数。我们想要近似求期望,只能用统计学的手段。

设随机变量    ,一个常用的办法是,如果我们找到     个随机变量     的样本   
那么   就是   一个好的近似!

容易知道,上式中的     服从    上的均匀分布。

所以我们的做法可以总结如下:

  1. 生成   个   上均匀分布的随机数   。

  2. 计算函数值   

  3. 积分    具有近似值   

接下来看一个例子来验证我们的结果:

   , 用蒙特卡洛方法近似计算    ,我们知道真实值是   ,介于2.6到2.7之间
取   

N = 1000
x = 2 * np.random.random(size=N)  # [0, 2] 上的均匀分布
ans = 2 / N * np.sum(x ** 2)
print(ans)
2.6431046604313226

目前看来效果还算不错,但是问题就这样结束了么?

问题三:估计的误差是多少?

凡估计必有误差

每一次采样都可以得到一个估计值,我们多次采样,得到多个估计值,画出多个估计值的分布图,从图上就可以近似看出估计的误差了。

record = []  # 记录多次采样的估计值
N = 1000  # 每次采样取1000个点
for _ in range(1000):x = 2 * np.random.random(size=N)ans = 2 / N * np.sum(x ** 2)record.append(ans)
plt.title('N=1000')
sns.distplot(record); plt.show()

惊讶的观察到:

  • 虽然我们真实值是2.67左右,但是估计出2.5、2.9这种偏离程度大的值还是有可能的。

  • 多次采样的结果分布像是正态分布。(这是巧合吗?)

把单次采样点增加到2000个,直觉告诉我们,误差会减小!

record = []  # 记录多次采样的估计值
N = 2000  # 每次采样取2000个点
for _ in range(1000):x = 2 * np.random.random(size=N)ans = 2 / N * np.sum(x ** 2)record.append(ans)
plt.title('N=2000')
sns.distplot(record); plt.show()

明显看到分布更加紧凑了一些。

问题四:如何从理论上对蒙特卡洛估计做分析?

在统计学上,我们评价一个估计好不好的标准有哪些呢?
统计量有三大基本性质:

  • 无偏性、有效性、相合性(一致性)

无偏性表示这个估计有没有 bias;有效性指这个估计的方差够不够小;相合性或者说一致性,说的是当样本容量非常大的时候,估计值是否趋近于真实值。

接下来我们从理论上来讨论这三点:
设     是     的一个估计量,则:

  1.    是无偏的,这点很好理解,对于样本   ,    。

  2.    是相合估计量,根据大数定律,估计量   几乎绝对收敛与   。

  3. 有效性没法说明,但是我们可以知道   的方差为   (样本之间独立)
    通过中心极限定理,还可以知道,当样本容量很大的时候,   渐进服从以   为均值,   为方差的正态分布。

最后,我想展示一下,本文所述的转化为估计随机变量期望的蒙特卡洛方法 与 传统的往正方形内投点计算落在圆内的点个数来估计     值的方法的不同。

Image Name
plt.figure(figsize=(12, 4))
record = []
for _ in range(1000):x = np.random.random(size=(2, 200))ans = 4 * np.mean(np.linalg.norm(x, axis=0) < 1)  # 是否落在圆内record.append(ans)
plt.subplot(121)
sns.distplot(record, kde=False)record = []
for _ in range(1000):x = np.random.random(size=200)ans = 4 * np.mean(np.sqrt(1 - x ** 2))  # y = sqrt(1 - x ^ 2)record.append(ans)
plt.subplot(122)
sns.distplot(record, kde=False); plt.show()

同样是取了2000个点(做200次计算),统计1000次结果。左图为传统方法,右图为本文所述转化为求期望的方法。

明显右边的效果更好!

结论

本文简要介绍了蒙特卡洛方法求积分的思路,以及相应的理论推导。蒙特卡洛求积分的本质是利用随机模拟估计一个随机变量的期望。理解好蒙特卡洛求积的思想有助于进一步学习MCMC方法。

进一步还可以思考:

  • 如何用蒙特卡洛估计重积分?这种方法会随着维数的增大而出现计算困难吗?(即:是多项式级别的更困难还是指数级别的更困难)

  • 说到用随机模拟估计一个随机变量的期望,如果我们能够获取到一定数量的某随机变量的样本,但是这个随机变量的分布非常畸形(考虑中国10亿劳动人口有6亿月收入不到1千,福布斯中国排行榜上前100的富豪能对中国人均收入产生巨大的影响),如何改进我们模拟的方法?


http://chatgpt.dhexx.cn/article/iQHIQBf8.shtml

相关文章

蒙特卡洛方法求定积分

用蒙特卡洛方法计算定积分 1.原理 计算定积分 利用蒙特卡洛计算方法,核心步骤是求取随机的 g(X1),………,g(Xn),n∈[a,b],由数学期望和大数定理可以近似计算定积分,公式为 2.测试用例 原函数: 导函数:

python 二重积分_python中求二维积分的方法

python中一般求解微积分可以使符号积分求出解析解&#xff0c;使用数值积分求出数值解。在计算机的处理当中&#xff0c;数值解往往更有意义。本文介绍python中利用数值积分例程和微分方程求解器scipy.integration中的dblquad方法求取二维积分的介绍。 1、引入scipy.integratio…

R语言:蒙特卡洛方法求积分

蒙特卡洛方法&#xff08;MC&#xff09; 一、蒙特卡洛方法简介二、利用蒙特卡罗方法计算圆周率三、利用蒙特卡洛方法求定积分例1例2例3 总结: 一、蒙特卡洛方法简介 蒙特卡洛方法得名于摩纳哥的蒙特卡洛赌场&#xff0c;是大数定律的经典应用&#xff0c;即用大样本数据计算出…

计算方法(一)——计算机求积分方法,机械求积法

机械求积法 转载请注明出处! 一、引言 随着人工智能的兴起,在计算机领域又一次掀起了数学热,不管是传统的机器学习,还是现在的深度学习,都离不开积分的支撑,那计算机在底层到底是怎样求积分的呢?小编同大家一起探讨。 二、理论推导 我们知道,在我们所学的微积分中我们是…

C++实现龙贝格求积分算法

1. 算法原理简介 T(0)(b-a)(f(a)f(b))/2&#xff1b; H(0)(b-a)f( (ab)/2 )&#xff1b; T(i)(T(i-1)H(i-1))/2。 T(i) 的语义是将积分区间做 2i 等分时复化梯形求积分公式算出的近似值。 H(i) 的语义是将积分区间做 2i 等分时&#xff0c;将每个小区间的长度乘该小区间中点处…

c#求定积分

步骤&#xff1a; 1 安装和使用NuGet插件 教程链接&#xff1a;https://blog.csdn.net/qq_36456952/article/details/55252913 2 安装 C# 科学计算库 Math.NET Numerics 教程链接: https://blog.csdn.net/heray1990/article/details/72467304 注意&#xff1a;在安装 C#…

人工智能数学基础---不定积分4:有理函数求积分的方法

一、引言 在《人工智能数学基础–不定积分2&#xff1a;利用换元法求不定积分》、《人工智能数学基础—不定积分3&#xff1a;分部积分法》分别介绍了换元积分法和分步积分法。但有些函数表达式很复杂&#xff0c;如果直接用换元积分法和分步积分法不好计算积分&#xff0c;这…

求积分方法及积分知识点-----专升本

求积分 一般&#xff08;常见&#xff09;求不定积分方法 一般&#xff08;常见&#xff09;定积分方法 带三角函数的求积分 凑微分法&#xff0c;拆开&#xff0c;三角代换&#xff0c;分部积分&#xff0c;整体法&#xff0c; 倒三角变正三角&#xff0c;奇拆偶降 几分之一圆…

二维数组、指针详解

二维数组、指针详解&#xff1a; 目录 二维数组、指针详解&#xff1a; 1.研究二维数组的表示。 2.现在研究关于二维数组和指针的关系 1.研究二维数组的表示。 首先&#xff0c;用代码运行进行测试&#xff0c;验证的相关结果&#xff0c; // C.cpp : 定义控制台应用程序…

二维数组与指针

转载自&#xff1a;https://www.cnblogs.com/chenyangyao/p/5222696.html 声明&#xff1a;本文为原创博文&#xff0c;如有转载&#xff0c;请注明出处。若本文有编辑错误、概念错误或者逻辑错误&#xff0c;请予以指正&#xff0c;谢谢。 指针与数组是C/C编程中非常重要的元…

二维数组指针,指针数组与数组指针的区别,一看就懂

目录 一.二维数组基本概念 二.指针数组和数组指针的区别 1.数组指针 2.指针数组 3.总结 三.二维数组的首地址和数组名 四.二维数组如何运用指针&#xff1f; 五.代码分析,加深了解。 一.二维数组基本概念 二维数组在概念上是二维的&#xff0c;有行和列&#xff0c;但在…

二维数组与数组指针详解

二维数组 深入理解二维数组 首先定义一个二维数组 int a[2][3]{{1,2,3},{4,5,6}}; #or int a[2][2]{1,2,3,4};新的理解&#xff1a;我们可以这样认为&#xff0c;a可以看作是一个一维数组&#xff0c;包含2个元素&#xff0c;每个元素恰好是包含3个整型的元素&#xff0c;a这个…

c语言——二维指针数组

1 一维度数组与指针 1.1一维数组元素在内存分布 #include<stdio.h> #include<stdlib.h> #include<string.h>#define ARRAY_SIZE 8void main() {int data[ARRAY_SIZE]{0,1,2,3,4,5,6,7};int i;printf("data address:0x%-8x\r\n",data);for(i0; i&l…

c++二维数组指针

&#xff11;.定义指针指向二维数组 为了方便根据用户输入动态定义二维数组的行和列&#xff0c;引入变量rowsNum(行)&#xff0c;colsNum(列&#xff09;。 以定义&#xff15;行&#xff14;列的二维数组为例&#xff0c; int rowsNum 4;int colsNum 5;float** a new fl…

二维数组名是指针的指针吗?

我们知道一维数组名是常量指针&#xff0c;我们可以将一维数组名赋给一个指针类型再对一维数组进行相关的操作&#xff0c;那二维数组名又是什么&#xff1f; 我们这样初始化一个二维数组int A[3][3]{1,2,3,4,5,6,7,8}或者为int A[3][3]{ {1,2,3},{4,5,6}&#xff0c;{7,8,9}}…

c++二维数组中指针详解

二维数组 a[2][3]{{1,2,3},{4,5,6}};指针p有如下几种表达形式&#xff1a; 1 方式一&#xff1a;int (*p)[3]a (或&a[0]&#xff09;; 一定要加上括号&#xff0c;因为[]的优先级高于*&#xff1b;意思是定义一个指向3个int类型变量的指针。p代表二维数组中第一个…

C语言 二维数组和指针

二维数组可以看成是元素为一维数组的数组&#xff0c;假设有一个三行四列的二维数组a&#xff0c;它定义为&#xff1a; int a[3][4] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; a 是二维数组名。a 数组包含 3 行&#xff0c;即 3 个行元素&#xff1a;a[0]&#xff0c;a[1]…

C/C++指向二维数组的指针

1. 二维数组 设有整型二维数组a[3][4]如下&#xff1a;     0 1 2 3     4 5 6 7     8 9 10 11   它的定义为&#xff1a;       int a[3][4]{{0,1,2,3},{4,5,6,7},{8,9,10,11}}  设数组a的首地址为1000&#xff0c;各下标变量的首地址及其值如图所…

二维数组与二级指针

关于二维数组与二级指针那些你必须知道的事 首先,来看一个例子一个error嗯,我是解析指针数组与数组指针 首先,来看一个例子 #include <iostream>using namespace std;int main(void) {int **p;pnew int*[5];for(int i0;i<5;i){p[i]new int[5];}return 0; }不严格地说…

C语言二维数组指针用法

目录 题目 背景概念梳理 一维线性 数组指针 指针步长 数组名与指向其的指针变量名等价 数组的初始化与取元素 数组指针转换关系 解题过程 选项A&#xff1a;* (( * prt1)[2]) 选项B&#xff1a;* ( * (p5)) 选项C&#xff1a;( * prt1)2 选项D&#xff1a; * ( * (…