强化学习算法-1-多臂老虎机

写在前面的话

想要在赌场中发家致富,要么有超能力,要么靠技术加持。

多臂老虎机也常常在游戏厅中见到,它是强化学习入门的必要问题,也是概率论中的经典。每一台老虎机的结果都服从一个概率分布,如高斯分布。如果想要从n个老虎机中实现财富自由,搞清楚每台老虎机的期望奖励,才能最大化自己的收益.

多臂老虎机英译为K-armed bandit。bandit:uk /ˈbæn.dɪt/   us /ˈbæn.dɪt/   土匪强盗暴徒。多臂老虎机问题也警戒我们,小赌不怡情,大赌很伤身。言归正传,面对多台老虎机,我们怎么去探求每一台老虎机的奖励分布呢?

 K-armed bandit

本算法会使用到贪婪的思想,即ϵ−greedy算法

在大多数情况下做出贪婪的选择,但是以一定的概率\epsilon做出随机的选择,能够保证每一个行动都能得到一定的探索,即便状态发生改变。

明确变量

输入:

  • k:老虎机的数量
  • num_learning_step:尝试次数

输出:

  • model.q:第k个老虎机的价值估计
  • model.n:选择第k个老虎机的次数

过程变量:

  • model:老虎机群的规模
  • reward:奖励函数
  • action:选择第action个老虎机进行一次行动
import random


# 本模型中老虎机的奖励是恒定的,即不随时间的变化而变化
class Bandit:
    def __init__(self, k):
        # 对k个老虎机初始化,确定每一个老虎机的奖励分布函数
        self.levers = [None] * k
        for i in range(k):
            minimum = random.random()
            maximum = minimum + abs(random.random() - minimum)
            lever = (minimum, maximum)
            self.levers[i] = lever

    def pull_lever(self, lever_index):
        lever = self.levers[lever_index]
        minimum, maximum = lever
        return minimum + random.random() * (maximum - minimum)


def create_k_bandit(k):
    return Bandit(k)


class Model:
    def __init__(self, bandit):
        k = len(bandit.levers)
        self.q = [0] * k
        self.n = [0] * k


def learn(bandit, num_learning_step):
    model = Model(bandit)

    Q = lambda action: model.q[action]

    for learning_step_number in range(num_learning_step):
        actions = tuple(range(len(bandit.levers)))
        epsilon = 0.1   # 贪婪程度,便于模型进行探索,值越大探索程度越大
        # TODO 修改学习率来查看不同的效果
        if random.random() <= epsilon:
            # 以epsilon的概率随机选择一个老虎机进行行动
            action = random.choice(actions)
        else:
            # 以(1-epsilon)的概率在k个老虎机中选择当前收益最大的老虎机进行行动
            action = argmax(actions, Q)
        reward = bandit.pull_lever(action)
        model.n[action] += 1
        model.q[action] += 1.0 / model.n[action] * (reward - model.q[action])

    return model


def argmax(values, predicate):
    # 返回奖励最大的老虎机的id
    return max(values, key=predicate)
    # 传入命名参数key,其为一个函数,用来指定取最大值的方法

if __name__ == '__main__':
    bandit = create_k_bandit(10)
    model = learn(bandit, 1000)
    print('bandit:', bandit)
    print('model:', model)
    print(model.q)
    print(model.n)
    print('')

在很多行业中,多臂老虎机问题有着广泛的应用。比如说广告展示,例如购物网站的推荐上,当然现在他们的算法应该更先进了.

你可能感兴趣的:(强化学习,python,python,机器学习)