机器学习概论 强化学习实现(实验五)

一、实验目的
1、熟练使用numpy模块;
2、熟练使用matplotlib模块;
3、掌握ε-贪心算法的代码实现;
4、掌握softmax算法的代码实现。
二、实验设备
计算机:CPU四核i7 6700处理器;内存8G; SATA硬盘2TB硬盘; Intel芯片主板;集成声卡、千兆网卡、显卡; 20寸液晶显示器。
编译环境:python解释器、Pycharm编辑器
三、实验内容
1、新建项目和文件,并导入numpy和matplotlib
(1)打开Pycharm,新建项目,并在该项目下新建文件kmeans_clustering.py。
(2)导入一些编程中需要的包。

import numpy as np
import matplotlib.pyplot as plt

2、构造一个类KArmedBandits
(1)该类实现K摇臂赌博机游戏,即每个摇臂对应一个概率分布,每次使用该摇臂,可以根据它对应的概率分布产生一个正整数。初始化该类时,需要将摇臂的个数k作为参数。
(2)定义一个类方法play,需要参数k,即使用的摇臂的编号,该函数根据当前摇臂对应的概率分布,返回一个正整数。

class KArmedBandits:
    def __init__(self,k):#初始化类
        self.k = k#将摇臂的个数k作为参数
    def start(self):
        a=np.random.randint(1,100,[self.k,5])
        return a
    def R(self,p):
        index = np.random.choice([8, 6, 4, 2, 0], p = p.ravel())
        return index           #返回当次预测的奖赏
    def play(self,b,c):
        k = c[b] / np.sum(c[b])   #b是选择的摇臂,c是start方法生成的矩阵   此时的k是5个小数,并且相加等于1,符合做概率的条件
        k = np.sort(k)  #概率从小到大排列
        return k

3、编写一个类EpsilonGreedy
(1)构造一个类EpsilonGreedy,并定义构造函数,该类用于实现ε-贪心算法。
(2)定义类方法learn,实现实现ε-贪心算法,并返回游戏次数和游戏次数对应的平均reward。
(3)定义类方法use,该方法用于在learn结束之后,实现贪心算法,并返回游戏次数和游戏次数对应的平均reward。

 # 编写一个类EpsilonGreedy
class EpsilonGreedy: # ε-贪心算法
        def __init__(self, maxitem, c, item):
            self.t = maxitem
            self.us = item
            self.k = [0, 1, 2, 3, 4]
            self.c = c
            self.avg = np.zeros(5)

        def learn(self, e):
            r = 0;
            count = np.zeros(5)
            avgsum1 = np.zeros(self.t)
            for i in range(self.t):
                if np.random.random() < e:  # 随机生成一个大于0小于1的小数,判断是否小于e,如果小于,探索,否则,利用
                    k = np.random.choice(self.k)
                    print("探索")
                else:
                    k = np.argmax(self.avg)
                    print("利用")
                print("选择的臂", k)  # 选择的臂
                q = KArmedBandits.play(self, k, self.c)  # q是k摇臂对应的重置的概率
                v = KArmedBandits.R(self, q)
                print("奖赏值", v)
                r = r + v
                avgsum1[i] = r / (i + 1)
                self.avg[k] = ((self.avg[k] * count[k]) + v) / (count[k] + 1)  # 计算每个摇臂对应的平均奖赏函数,
                count[k] += 1
            return avgsum1

        def use(self, e):
            r = 0
            count = np.zeros(5)
            avgsum2 = np.zeros(self.us)
            for i in range(self.us):
                k = np.argmax(self.avg)
                print("选择的臂", k)
                q = KArmedBandits.play(self, k, self.c)
                v = KArmedBandits.R(self, q)
                print("奖赏值", v)
                r = r + v
                avgsum2[i] = r / (i + 1)
                print("平均奖赏值:", avgsum2[i])
                self.avg[k] = ((self.avg[k] * count[k]) + v) / (count[k] + 1)
                count[k] += 1
            return avgsum2, self.avg

4、编写一个类Softmax
(1)构造一个类Softmax,并定义构造函数,该类用于实现Softmax算法。
(2)定义类方法learn,实现实现Softmax算法,并返回游戏次数和游戏次数对应的平均reward。
(3)定义类方法use,该方法用于在learn结束之后,实现贪心算法,并返回游戏次数和游戏次数对应的平均reward。

class Softmax:
    def __init__(self,maxium,avgk,item,gama):
        self.t = maxium
        self.gama = gama
        self.avgk = avgk
        self.k = [0,1,2,3,4]
        self.us = item
    def P(self):    #重置摇臂选择概率
        index = np.zeros(5)
        index[0] = np.exp(self.avgk[0]/self.gama) / np.sum(np.exp(self.avgk/self.gama))
        index[1] = np.exp(self.avgk[1]/self.gama) / np.sum(np.exp(self.avgk/self.gama))
        index[2] = np.exp(self.avgk[2]/self.gama) / np.sum(np.exp(self.avgk/self.gama))
        index[3] = np.exp(self.avgk[3]/self.gama) / np.sum(np.exp(self.avgk/self.gama))
        index[4] = np.exp(self.avgk[4]/self.gama) / np.sum(np.exp(self.avgk/self.gama))
        return index
    def learn(self,c):
        r = 0;avg = np.zeros(5);count = np.zeros(5);avgsum = np.zeros(self.t)
        for i in range(self.t):
            p = self.P()  #选择摇臂概率
            k = np.random.choice(self.k, p = p.ravel())
            q = KArmedBandits.play(self,k,c)  #c是重置的概率矩阵
            v = KArmedBandits.R(self,q)
            r = r + v
            avgsum[i] = r / (i+1)
            self.avgk[k] = ((self.avgk[k]*count[k])+v) / (count[k]+1)
            count[k] +=1
        return avgsum
    def use(self):
        r = 0;count = np.zeros(5)
        avgsum = np.zeros(self.us)
        for i in range(self.us):
            k=np.argmax(self.avgk)
            print("选择的臂",k)
            q = KArmedBandits.play(self,k,c)  #c是重置的概率矩阵
            v = KArmedBandits.R(self,q)
            print("奖赏值",v)
            r = r + v
            avgsum[i] = r / (i+1)
            self.avgk[k] = ((self.avgk[k]*count[k])+v) / (count[k]+1)
            print("平均奖赏值:",avgsum[i])
            count[k] +=1
        return avgsum

5、编写if _ name ==” main _”:
(1)构造if _ name ==” main _”:。
(2)使用不同的参数,调用EpsilonGreedy类和Softmax类
(3)使用每次调用learn和use之后返回的数据,绘制折线图
(4)比较算法。

if __name__ == "__main__":
    KArmedBanditsinit = KArmedBandits(5)
    c = KArmedBanditsinit.start()
    EpsilonGreedy = EpsilonGreedy(10000,c,1000)
    avg_1_lean = EpsilonGreedy.learn(0.3)
    avg_2_lean = EpsilonGreedy.learn(0.1)
    avg_1_use,avg_1 = EpsilonGreedy.use(0.3)
    avg_2_use,avg_2 = EpsilonGreedy.use(0.1)
    Softmax_1 = Softmax(10000,avg_1,1000,0.1)
    Softmax_2 = Softmax(10000,avg_1,1000,1)#根据e概率为0.3时返回的平均奖赏作softmax运算
    avg_1__lean = Softmax_1.learn(c)
    avg_2__lean = Softmax_2.learn(c)
    avg_1__use = Softmax_1.use()
    avg_2__use = Softmax_2.use()
    #折线图,数据可视化处理
    plt.figure()
    plt.subplot(121)
    plt.plot(avg_1_lean,"r",avg_2_lean,"b",avg_1__lean,"y",avg_2__lean,"g")
    plt.subplot(122)
    plt.plot(avg_1_use,"r",avg_2_use,"b",avg_1__use,"y",avg_2__use,"g")
    plt.show()

四、实验总结
通过本次实验,自己对机器的学习有了更深的理解,主要学习了强化学习中的K-摇臂赌博机,对比了ε-贪心算法和softmax算法实现,尝试用不同的方法来实现某一功能,比较不同算法在摇臂赌博机上的性能。

你可能感兴趣的:(机器学习概论,机器学习,python,人工智能)