機器學習-K-搖臂賭博機相關算法

一,介紹

學習K-搖臂賭博機的相關算法需要明白兩個概念:探索和利用。

僅探索:將所有嘗試機會平均分給每個搖臂,以各個搖臂的平均吐幣概率作爲獎賞期望。

僅利用:按下目前最優的搖臂,有多個則隨機選取一個。

算法一:ε-貪心算法

基於概率對探索和利用折中:以ε的概率進行探索,以1-ε的概率進行利用,一般如果嘗試次數非常大,可以讓ε隨着嘗試次數增加而減小。

我們用Q(k)表示平均獎賞:

                         

算法二:Softmax算法

此算法假設已知各搖臂平均獎賞,基於Boltzmann分佈選取搖臂:

                                                                        

其中Q(i)爲當前平均獎賞,τ>0稱爲“溫度”。

二,代碼

import random

# ε貪心算法
def EGreedy(e=0.9,T=1000):
    # 構造一個5臂的搖臂機
    ArmedBandit = [random.randint(0,100)/100,random.randint(0,100)/100,random.randint(0,100)/100,random.randint(0,100)/100,random.randint(0,100)/100]
    Q=[0.0,0.0,0.0,0.0,0.0];count=[0,0,0,0,0];select=0;bonus=0;v=0
    while T>0:      # 開始循環,假設中獎都是1,未中獎爲0
        rand = random.randint(0, 100) / 100  # 產生隨機數用於判斷是探索還是利用
        r = random.randint(0, 100) / 100  # 產生隨機數判斷是否中獎
        v=0
        if(rand<e):   # 探索
            select = select % 5
            count[select]+=1
            if(r<ArmedBandit[select]):
                bonus+=1
                v=1
            Q[select] +=(1/count[select]) * (v-Q[select])
            select += 1
        else:        # 利用
            index = Q.index(max(Q)) # 獲取最優的搖臂
            count[index] += 1
            if (r < ArmedBandit[index]):
                bonus += 1
                v = 1
            Q[index] +=(1/count[index]) * (v-Q[index])
        T-=1
        e-=e/(T+1)
    return bonus


if __name__=="__main__":
    bonus = EGreedy()
    print(bonus)

 

import random
import math

# Softmax算法
def Softmax(au=1,T=1000):
    # 構造一個5臂的搖臂機
    ArmedBandit = [random.randint(0, 100) / 100, random.randint(0, 100) / 100, random.randint(0, 100) / 100,
                   random.randint(0, 100) / 100, random.randint(0, 100) / 100]
    # 搖臂初始獎賞,
    Q = ArmedBandit.copy()
    count = [100, 100, 100, 100, 100];  #假設初始獎賞是各個搖臂100次計算出來的
    bonus = 0
    def Boltzmann(au, Q):   # 計算Boltzmann分佈
        P = [];sum=0.0
        for i in range(len(Q)):
            sum += math.exp(Q[i] / au)
        for i in range(len(Q)):
            P.append(math.exp(Q[i]/au)/sum)
        return P

    while T>0:
        p = Boltzmann(au,Q)
        r=random.randint(0, 10000) / 10000  #產生隨機數獲取搖桿
        rand = random.randint(0, 100) / 100  # 產生隨機數用於判斷是否中獎
        sum = 0.0;select=0;v=0
        for i in range(len(p)):   # 獲取選擇的搖桿
            sum+=p[i]
            if(r<sum):
                select = i
                break
        if(rand<ArmedBandit[select]):
            bonus += 1
            v = 1
        count[select]+=1
        Q[select] += (1 / count[select]) * (v - Q[select])
        T-=1
    return bonus

if __name__=="__main__":
    bonus = Softmax()
    print(bonus)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章