Toward 阿法狗-第二期-蒙特卡洛模擬

背景

本系列上一期已經涵蓋了 97年IBM深藍打敗國際象棋大師的Minimax算法。而從上一期大家能看出,Minimax 屬於窮舉的方法,雖然有Alpga-Beta Pruning等優化,但是其本質還是屬於窮舉法之一。 而也是因為其屬於窮舉法範疇,Minimax無法擊敗圍棋大師。

而大家眾所周知的阿法狗已經成功打敗了人類圍棋大師。而阿法狗採用了 MCTS(蒙特卡洛樹搜索)和 深度機器學習。其中非常重要的一個不同點就是,解決如何面對不確定性和隨機性的問題。Minimax是使用窮舉法來面對棋局變化的隨機性,而阿法狗是通過MCTS,這其中的不同本系列將會覆蓋。

而本期將給大家介紹 蒙特卡洛模擬,Monte Carlo方法是應對隨機性的一個有效方法。而瞭解蒙特卡洛模擬也是 搞懂 MCTS(蒙特卡洛樹搜索)的前提。

本期的文章除了開頭及算法理解部分,其他均由翻譯Toward DataScience文章而來。

蒙特卡洛模擬

如果有對金融有一些瞭解的朋友,可能知道在期權Option定價的過程中有用到蒙特卡洛模擬。期權的定價就是典型的面對 不確定性和隨機性的定價。 而面對隨機性最簡單的方式就是抽樣或者實驗。

一個簡單的例子,假設我們要知道骰子搖到 6 的概率,最簡單的方式就是搖很多次骰子,然後最後統計下。 蒙特卡洛本質就這麼簡單,就是搖骰子。

換個例子,大家都玩過遊戲機,而遊戲機就是一個隨機性的。 而如果我們想知道遊戲機的平均值。 那很簡單,就是試足夠多的次數。而蒙特卡洛模擬的本質就是取足夠多的樣本來反應出隨機性背後的值。

Toward 阿法狗-第二期-蒙特卡洛模擬

下面將通過翻譯 Toward DataScience的一個關於蒙特卡洛模擬的文章及代碼來進一步解釋該問題。

蒙特卡洛模擬

假設有一個遊戲,而我們的玩家是Jack,搖一個骰子得出一個隨機數1~100。如果Jack 得出1~51,那麼賭場贏;但是如果Jack得出52~100,那麼Jack贏

Toward 阿法狗-第二期-蒙特卡洛模擬

在模擬結果之前,我們需要先計算 莊家 的贏面。而莊家的贏面代表著 賭場的平均利潤。

假設Jack下注一元在此遊戲:

Jack贏的概率=49/100

賭場贏的概率=51/100

Jack的期望利潤= 1* ( 49/100) - 1 * (51/100) = -0.02 = - 2%

因此,賭場的期望收益率是2%

現在,用Python來模擬不同的場景下,可視化玩家一直下注的結果

  • 引入相關的Python Lib
#Import libraries
import random
import matplotlib.pyplot as plt
  • 我們需要一個骰子,骰子隨機產生1~100的平均概率分佈。並且如果玩家獲勝,骰子 return “True”;如果賭場獲勝,return “False”
#Create function for simulating die roll 
#The die can take values from 1 to 100. If the number is between 1 #and 51, the house wins.
#If the number is between 52 and 100, the player wins.
def rolldice():


dice = random.randint(1,100)

if dice <=51:
return False
elif dice >51 & dice <=100:
return True
  • 創建一個公式來模擬下注的過程。我們需要提供三個變量:
  1. 總資金金額:玩家初始的資金數(¥10000)
  2. 下注金額:每局的下注金額(Y100)
  3. 總局數:玩家參與的總局數
#Define a function for the play which takes 3 arguments :
#1. total_funds = total money in hand the player is starting with
#2. wager_amount = the betting amount each time the player plays
#3. total_plays = the number of times the player bets on this game
def play(total_funds, wager_amount, total_plays):

#Create empty lists for :
# 1.Play_number and
# 2.Funds available
# 3.Final Fund
Play_num = []
Funds = []
#Start with play number 1
play = 1
#If number of plays is less than the max number of plays we have set
while play < total_plays:
#If we win
if rolldice():
#Add the money to our funds
total_funds = total_funds + wager_amount
#Append the play number
Play_num.append(play)
#Append the new fund amount

Funds.append(total_funds)
#If the house wins
else:
#Add the money to our funds
total_funds = total_funds - wager_amount
#Append the play number
Play_num.append(play)
#Append the new fund amount
Funds.append(total_funds)

#Increase the play number by 1
play = play + 1

#Line plot of funds over time
plt.plot(Play_num,Funds)
Final_funds.append(Funds[-1])
return(Final_funds)
  • 最後,循環上述代碼,模擬不同局數下的結果
#Call the function to simulate the plays and calculate the remaining #funds of the player after all the bets
#Intialize the scenario number to 1
x=1
#Create a list for calculating final funds
Final_funds= []
while x<=100:
ending_fund = play(10000,100,5)
x=x+1
#Plot the line plot of "Account Value" vs "The number of plays"
plt.ylabel('Player Money in $')
plt.xlabel('Number of bets')
plt.show()
#Print the money the player ends with
print("The player starts the game with $10,000 and ends with $" + str(sum(ending_fund)/len(ending_fund)))
  • 最終我們將對不同的場景的結果,進行可視化。

X軸:Jack下注的局數

Y軸:Jack的資金餘額

場景 1 -> 局數 : 5

Toward 阿法狗-第二期-蒙特卡洛模擬

場景 2 -> 局數 : 10

Toward 阿法狗-第二期-蒙特卡洛模擬

場景 3 -> 局數 : 50

Toward 阿法狗-第二期-蒙特卡洛模擬

場景 4 -> 局數 : 100

Toward 阿法狗-第二期-蒙特卡洛模擬

場景 5 -> 局數 : 500

Toward 阿法狗-第二期-蒙特卡洛模擬

場景 6 -> 局數 : 1000

Toward 阿法狗-第二期-蒙特卡洛模擬

場景 7 -> 局數 : 10000

Toward 阿法狗-第二期-蒙特卡洛模擬

從上述的模擬中可以看出,該遊戲局數較少時,玩家可能還有贏面。

總結

本期涵蓋來蒙特卡洛模擬,當面本期的例子非常簡單,因為只有一個變量。

不過其意義在於瞭解蒙特卡洛模擬的概念。其思路也很簡單,就是通過實驗模擬來達到衡量不確定性和隨機性的問題。通俗的說,就是通過實驗發現 “骰子變量”背後的概率分佈。

再回到圍棋,與minimax不同的是,由於圍棋的可能性太多無法窮舉,其演變成來一個概率的問題。而Monte Carlo 也是應對圍棋概率的算法一部分。


分享到:


相關文章: