1.2 K摇摆赌博机
首先我们考虑强化学习最简单的情形:仅考虑一步操作,即在状态x下只需执行一次动作a便能观察到奖赏结果。易知:欲最大化单步奖赏,我们需要知道每个动作带来的期望奖赏值,这样便能选择奖赏值最大的动作来执行。若每个动作的奖赏值为确定值,则只需要将每个动作尝试一遍即可,但大多数情形下,一个动作的奖赏值来源于一个概率分布,因此需要进行多次的尝试。
单步强化学习实质上是K-摇臂赌博机(K-armed bandit)的原型,一般我们尝试动作的次数是有限的,那如何利用有限的次数进行有效地探索呢?这里有两种基本的想法:
- 仅探索法:将尝试的机会平均分给每一个动作,即轮流执行,最终将每个动作的平均奖赏作为期望奖赏的近似值。
- 仅利用法:将尝试的机会分给当前平均奖赏值最大的动作,隐含着让一部分人先富起来的思想。
可以看出:上述两种方法是相互矛盾的,仅探索法能较好地估算每个动作的期望奖赏,但是没能根据当前的反馈结果调整尝试策略;仅利用法在每次尝试之后都更新尝试策略,符合强化学习的思(tao)维(lu),但容易找不到最优动作。因此需要在这两者之间进行折中。
1.2.1 ε-贪心
ε-贪心法基于概率来对探索和利用进行折中,具体而言:在每次尝试时,以ε的概率进行探索,即以均匀概率随机选择一个动作;以1-ε的概率进行利用,即选择当前最优的动作。ε-贪心法只需记录每个动作的当前平均奖赏值与被选中的次数,便可以增量式更新。ε是基于概率进行探索,ε作为随机选择一个摇臂的概率,那么1-ε的概率用于从平均奖赏最大的摇臂里面选择。
贪心与动规的关键区别:
看是否用到之前的最优解,如果用到就是动态规划,否则就是贪心,贪心无法解决动态规划的问题,但是动态规划能解决贪心的问题。
ε-贪心法python代码模拟仿真:
from numpy import random
K = [1,2,3,4,5] # 总共的摇臂数有5个
R = {1:2,2:3,3:5,4:1,5:9} # 各个摇臂对应的奖赏
prob = {1:0.6,2:0.5,3:0.2,4:0.7,5:0.05} #各个摇臂对应的概率吐币的概率
T = 10000
eplison = 0.1 #ε探索概率
count = dict(zip(list(range(1,6)),[0]*5)) # 计算每个摇臂的摇到的次数
#zip函数:接受任意多个(包括0个和1个)序列作为参数,返回一个tuple列表
#使用zip函数, 把key和value的list组合在一起, 再转成字典(dict).
r = 0
for i in range(T):
Q = dict(zip(list(range(1,6)),[0]*5)) #
if random.random() < eplison: #
k = random.choice(K) #
else:
k = max(Q,key=Q.get) #
v = random.choice([R[k],0],p=[prob[k],1-prob[k]]) #
r += v
Q[k] = (Q[k]*count[k]+v)/(count[k]+1) ## Q(i) 表示第i个摇臂的平均奖赏# ε-贪心法只需记录每个动作的当前平均奖赏值与