Python 中的蒙特卡洛

今天我们看一下 Python 中一种非常著名的方法,称为蒙特卡罗,它可以用来解决任何具有概率解释的问题。让我们从一些有趣的历史开始吧。

蒙特卡罗的一点历史

它用于解决复杂的数值问题,例如布冯针问题(https://en.wikipedia.org/wiki/Buffon’s_needle_problem):

假设我们有一个由平行木条制成的地板,每条木条的宽度相同,然后我们将一根针扔到地板上。针穿过两条带之间的线的概率是多少?

自 20 世纪 40 年代以来一直被用于:

  • 在洛斯阿拉莫斯国家实验室研究核武器项目的中子扩散,其中 ENIAC 用于执行 MC 模拟。
  • 在氢弹的研制过程中也被使用
  • 在流体力学中,求解复杂的微分方程(非线性抛物线偏微分方程)
  • 用于估计粒子传输能量
  • 高级信号处理和贝叶斯推理
  • 关于遗传类型突变选择学习机(当今生物信息学领域的早期介绍)等。

在 Python 中实现蒙特卡洛

蒙特卡洛允许我们模拟看似随机的事件,并评估风险(当然还有其他结果)。它已用于评估给定交易策略的风险。

在本教程中,我们将模拟赌场(因为我们无法模拟核武器测试😀)

一般来说,问题越复杂,需要的伪随机数值变量就越多。

打开您的Google Colaboratory并连接到运行时。

1. 创建赌场轮盘的基本滚动

让我们导入numpypandas包:

import numpy as np
import pandas as pd
  • 然后,我们将“掷骰子”定义为 1 到 100 之间的数字,并将其设置为客户获胜的几率为49-51 。
  • 这意味着对于 1-50 和正好 100 的掷骰,庄家(/赌场)获胜。
  • 对于 51-99 的掷骰,玩家获胜。

这似乎是一个公平的获胜机会,大多数玩家很可能会抓住它。

让我们用 Python 来模拟一下:

def casino_roll():
    roll = np.random.randint(1,100)
 
    if roll <= 50 or roll == 100:
        print('rolled %d. you lose. House wins! Play again?!'%roll)
    elif 50 < roll < 100:
        print('you win! On a roll !')
        return True

所以,现在我们可以调用casino_roll(),你就可以看到你得到了什么。我尝试了四次,失败了三次。

2. 做经销商

接下来,让我们投入一些钱来打赌。因此,我们将创建接受投注的庄家,并且:

  • 如果获胜,他会奖励玩家。
  • 如果有损失,他就把钱装进自己的口袋。
def deal_bet(funds,initial_bet,bet_count):
    bet = 0
    funds_total = 0
    while bet < bet_count:
        if casino_roll():
            funds += initial_bet
        else:
            funds -= initial_bet
 
        bet += 1
        print('Funds : %d'%funds)
        funds_total += funds
    print('average win/loss : %f'%(10000-funds_total/bet_count))

请注意,我找到了总资金,然后找到了平均盈利/亏损。如果是积极的,那就是胜利。如果是负数,那就是损失。

3. 投注100卢比。100

因此,运行 100 个投注,每次投注相同金额的 100 卢比,我们得到:

deal_bet(10000,100,100)
蒙特卡洛赌场投注资金

在得到这个负值之前,我必须运行该程序 5 次,但观察有多少个值远远超过 10000,但玩家总体上还是赔钱的。

这只是为了表明我们认为有利可图的交易可能并不总是如此。

4. 培养更多玩家

我们可以让 100 名玩家进行与上述相同的投注:

x=0
while x<100:
  deal_bet(10000,100,100)
  x+=1

注释掉deal_bet ()中的打印(资金)语句

所以,现在我们可以看到每个玩家产生的所有利润和损失:

蒙特卡洛平均胜负

5. 使用 Matplotlib 绘制平均值

让我们在这里使用 matplotlib 绘制数据

return (10000-funds_total/bet_count)

将以上行添加到deal_bet () 函数的末尾。

然后我们修改:

x=0
avg_list=[]
while x<100:
  avg_list.append(deal_bet(10000,100,100))
  x+=1

最后,我们可以绘制它:

import matplotlib.pyplot as plt
 
avg_list = np.array(avg_list).astype(int)
plt.figure(figsize=(20,20))
plt.plot(avg_list)
plt.axhline(np.array(avg_list).mean(), color='k', linestyle='dashed', linewidth=1)
平均输赢图蒙特卡洛

结论

大家今天的活动就到此为止。我希望这个例子能够帮助您很好地理解Python中的蒙特卡罗模拟。

您现在可以对激进的玩家执行此操作。或许,他每次获胜,都会下双倍的钱。想各种场景,自己修改下注函数。

如果您在我的 github 上错过了某些内容,您会发现更多场景以及完整代码:

https://github.com/arkaprabha-majumdar/monte-carlo

直到下一次 !!