该值从类对象返回

时间:2018-10-11 06:37:02

标签: python python-3.x

我正在独自学习贝叶斯A / B测试课程。但是,在以下代码中,它在某些函数中具有类对象。对于以下代码:bandits = [Bandit(p) for p in BANDIT_PROBABILITIES]

我知道它将0.20.50.75应用于Bandit Class对象,但是该语句的输出是什么?是否从该类中的函数def pull(self)def sample(self)执行此操作,因为这两个函数都返回Bandit类中的某些值。通过了解这一点,我便可以知道b在此代码的后面循环了什么。

任何参考链接或文章也将受到赞赏。谢谢

import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import beta


NUM_TRIALS = 2000
BANDIT_PROBABILITIES=[0.2,0.5,0.75]

class Bandit(object):
  def __init__(self, p): #p=winning
    self.p = p
    self.a = 1
    self.b = 1

  def pull(self):
    return np.random.random() < self.p

  def sample(self):
    return np.random.beta(self.a, self.b)

  def update(self, x):
    self.a =self.a+ x
    self.b =self.b+ 1 - x  #x is 0 or 1


def plot(bandits, trial):
  x = np.linspace(0, 1, 200)
  for b in bandits:
    y = beta.pdf(x, b.a, b.b)
    plt.plot(x, y, label="real p: %.4f" % b.p)
  plt.title("Bandit distributions after %s trials" % trial)
  plt.legend()
  plt.show()


def experiment():
  bandits = [Bandit(p) for p in BANDIT_PROBABILITIES]

  sample_points = [5,10,20,50,100,200,500,1000,1500,1999]
  for i in range(NUM_TRIALS):

    # take a sample from each bandit
    bestb = None
    maxsample = -1
    allsamples = [] # let's collect these just to print for debugging
    for b in bandits:
      sample = b.sample()
      allsamples.append("%.4f" % sample)
      if sample > maxsample:
        maxsample = sample
        bestb = b
    if i in sample_points:
      print("current samples: %s" % allsamples)
      plot(bandits, i)

    # pull the arm for the bandit with the largest sample
    x = bestb.pull()

    # update the distribution for the bandit whose arm we just pulled
    bestb.update(x)


if __name__ == "__main__":
  experiment()

3 个答案:

答案 0 :(得分:1)

它以3个不同的p概率返回Bandit类的3个对象。

进一步浏览,sample = b.sample(),它将返回np.random.beta(self.a,self.b)的结果

答案 1 :(得分:1)

bandits = [Bandit(p) for p in BANDIT_PROBABILITIES]是列表理解。 BANDIT_PROBABILITIES是3个浮点值的列表,因此bandits是包含3个Bandit类的对象的列表,这些对象是用p属性的3个不同值创建的:

print(type(bandit[0]))
print(bandits[0].p)

输出:

<class '__main__.Bandit'>
0.2

到目前为止,只有方法__init__()被调用来初始化对象。列表bandits中的每个强盗都有属性p, a, b和方法pull(), sample(), update()

答案 2 :(得分:0)

声明

bandits = [Bandit(p) for p in BANDIT_PROBABILITIES]

被称为列表理解,它基本上是一种创建列表的方法。例如,您可以看到this作为参考(有很多资源)。

基本思想是使用类似的机制:

[ expression for item in list if conditional ]

因此,在您的情况下,BANDIT_PROBABILITIES是上面包含3个元素的列表,您的列表理解力所得出的表达式只是Bandit类的实例。换句话说,您将得到一个列表,其中包含Bandit类的3个实例,每个实例都用不同的参数初始化。

pull(self)sample(self)只是属于该类的函数,在此语句中未使用它们。如果您有来自__init__(self, p)成员函数的调用,则可以使用它们。

为简单起见,在创建类实例时,仅使用__init__。如果在后一个函数内部是对成员函数的其他调用,例如sample()等,则它们也会被调用,但是列表理解中的输出仍然是具有3个Bandit实例的列表。

也许您应该查看__init__功能的this answer(以及其他很多文献,因为有很多参考文献)。