今天我们看一下 Python 中一种非常著名的方法,称为蒙特卡罗,它可以用来解决任何具有概率解释的问题。让我们从一些有趣的历史开始吧。
蒙特卡罗的一点历史
它用于解决复杂的数值问题,例如布冯针问题(https://en.wikipedia.org/wiki/Buffon’s_needle_problem):
假设我们有一个由平行木条制成的地板,每条木条的宽度相同,然后我们将一根针扔到地板上。针穿过两条带之间的线的概率是多少?
自 20 世纪 40 年代以来一直被用于:
- 在洛斯阿拉莫斯国家实验室研究核武器项目的中子扩散,其中 ENIAC 用于执行 MC 模拟。
- 在氢弹的研制过程中也被使用
- 在流体力学中,求解复杂的微分方程(非线性抛物线偏微分方程)
- 用于估计粒子传输能量
- 高级信号处理和贝叶斯推理
- 关于遗传类型突变选择学习机(当今生物信息学领域的早期介绍)等。
在 Python 中实现蒙特卡洛
蒙特卡洛允许我们模拟看似随机的事件,并评估风险(当然还有其他结果)。它已用于评估给定交易策略的风险。
在本教程中,我们将模拟赌场(因为我们无法模拟核武器测试😀)
一般来说,问题越复杂,需要的伪随机数值变量就越多。
打开您的Google Colaboratory并连接到运行时。
1. 创建赌场轮盘的基本滚动
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
直到下一次 !!