蒙特卡洛模拟原理与python实现

蒙特卡洛方法是一种基于随机数(或更准确地说是伪随机数)来解决数学、物理和工程问题的方法。这种方法以摩纳哥的蒙特卡洛赌场命名,因为赌场中的随机性与这种方法的随机抽样特性相似。

数学原理

蒙特卡洛方法的核心原理是利用随机数(或伪随机数)来模拟或表示一个系统的随机过程,然后通过对这些随机数的统计分析来近似计算问题的解。这种方法基于大数定律,即随着试验次数的增加,样本的平均值会趋近于期望值。

公式推导

在Markdown格式下,上述数学原理和公式可以表示如下:

  1. 期望值的估计
    假设我们想要估计一个函数 ( f(x) ) 在区间 ([a, b]) 上的积分,即 ( f(x) ) 的期望值。我们可以将区间 ([a, b]) 划分为 ( N ) 个小区间,每个小区间的宽度为 ( \Delta x )。在每个小区间的随机选择 ( x_i ),计算 ( f(x_i) ),然后取平均值:

    E [ f ( x ) ] ≈ 1 N ∑ i = 1 N f ( x i ) E[f(x)] \approx \frac{1}{N} \sum_{i=1}^N f(x_i) E[f(x)]N1i=1Nf(xi)

    其中 ( x_i ) 是在 ([a, b]) 区间内均匀随机选取的。

  2. 方差的估计
    对于随机变量 ( X ) 的方差估计,可以使用以下公式:

    Var ( X ) ≈ 1 N − 1 ∑ i = 1 N ( x i − x ‾ ) 2 \text{Var}(X) \approx \frac{1}{N-1} \sum_{i=1}^N (x_i - \overline{x})^2 Var(X)N11i=1N(xix)2

    其中 ( \overline{x} ) 是样本均值。

请注意,在Markdown中,数学公式需要用两个美元符号 $$ 包围来表示一个独立的数学环境,或者对于行内数学公式,可以使用单个美元符号 $

使用场景

  1. 数值积分
    蒙特卡洛方法常用于计算多维积分,这些积分在解析方法中可能难以处理。

  2. 风险分析
    在金融领域,蒙特卡洛模拟用于评估投资组合的风险,通过模拟不同的市场情景来估计资产的未来价值。

  3. 物理和工程模拟
    在物理实验中,蒙特卡洛方法可以用来模拟粒子的随机行为,如在粒子物理和热力学中的应用。

  4. 优化问题
    在搜索复杂系统的全局最优解时,蒙特卡洛方法可以用来随机探索解空间。

  5. 机器学习
    在机器学习中,蒙特卡洛方法用于生成数据的样本,如在训练神经网络时的 Dropout 技术。

  6. 游戏理论
    在博弈论中,蒙特卡洛方法可以用来模拟玩家的随机策略,以评估不同策略的效果。

蒙特卡洛方法的优点是简单、通用,尤其适用于那些难以找到解析解的问题。然而,它的缺点是收敛速度可能较慢,且结果的准确性高度依赖于随机样本的数量和质量。因此,在使用蒙特卡洛方法时,通常需要大量的模拟来确保结果的可靠性。

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import norm
import matplotlib.pyplot as plt
import seaborn as sns

# 设置字体为 Microsoft YaHei
plt.rcParams['font.family'] = 'Microsoft YaHei'

# 设置调色板
sns.set_palette("colorblind")



# 进行蒙特卡洛模拟
n = 1000
result_lst = []
for i in range(n):
    x = 0
    for j in range(df.shape[0]):
        xj = np.random.normal(df['利润差'][j],np.sqrt((df['预期总销量'][j])**2))
        x += xj
    result_lst.append(x)

# 绘制直方图
plt.figure(figsize=(10, 6))
sns.histplot(result_lst, kde=True, color='blue', bins=30)
plt.title('总利润差直方图(模拟)', fontsize=16)
plt.xlabel('总利润差', fontsize=14)
plt.ylabel('频数', fontsize=14)
plt.show()


# 绘制累积概率密度分布曲线
plt.figure(figsize=(10, 6))
sns.kdeplot(result_lst, cumulative=True, color='blue')
plt.title('总利润差累积概率密度分布曲线', fontsize=16)
plt.xlabel('总利润差', fontsize=14)
plt.ylabel('累积概率密度', fontsize=14)
plt.show()

# 计算 95% 的概率范围
mean = np.mean(result_lst)
std = np.std(result_lst)
lower_bound = norm.ppf(0.025, mean, std)
upper_bound = norm.ppf(0.975, mean, std)
print('95% 的概率范围为:({:.2f}, {:.2f})'.format(lower_bound, upper_bound))

这段代码是一个使用Python进行蒙特卡洛模拟的示例,用于估计一个统计分布的特征。下面是对代码每一步的解释:

  1. 导入必要的库:

    • numpy:用于数值计算。
    • matplotlib.pyplot:用于绘图。
    • seaborn:基于matplotlib的高级绘图库,提供更美观的图表。
    • scipy.stats:用于统计分析。
  2. 设置字体为 Microsoft YaHei,以便图表中的中文能够正确显示。

  3. 设置 seaborn 的调色板为 "colorblind",这是一种对色盲友好的调色板。

  4. 初始化一个空列表 result_lst,用于存储模拟结果。

  5. 进行蒙特卡洛模拟:

    • 设置模拟次数 n 为1000。
    • 循环 n 次,每次模拟计算总利润差。
    • 在每次模拟中,初始化 x 为0。
    • 循环数据框 df 的每一行,对每一行进行如下操作:
      • 从正态分布中抽取一个随机数 xj,均值为该行的 利润差,标准差为 预期总销量 的平方根。
      • 将抽取的随机数累加到 x
    • 将每次模拟的总利润差 x 添加到 result_lst 列表中。
  6. 绘制直方图:

    • 设置图表大小为10x6英寸。
    • 使用 seabornhistplot 函数绘制 result_lst 的直方图,并添加核密度估计(KDE)。
    • 设置图表的标题、X轴和Y轴标签,并指定字体大小。
  7. 显示直方图。

  8. 绘制累积概率密度分布曲线:

    • 再次设置图表大小。
    • 使用 seabornkdeplot 函数绘制 result_lst 的累积概率密度分布曲线。
    • 设置图表的标题、X轴和Y轴标签,并指定字体大小。
  9. 显示累积概率密度分布曲线。

  10. 计算95%的概率范围:

    • 计算 result_lst 的均值 mean 和标准差 std
    • 使用 scipy.stats.norm.ppf 函数计算95%置信区间的下界和上界。
    • 打印出95%的概率范围。

注意:代码中有一些重复的导入语句(例如,matplotlib.pyplotseaborn 各导入了两次),这在实际编写代码时应避免。此外,代码中提到的 df 数据框没有在代码片段中定义,它应该在代码执行之前就已经存在,并且包含 利润差预期总销量 这两列数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

徐木叶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值