我正在独自学习贝叶斯A / B测试课程。但是,在以下代码中,它在某些函数中具有类对象。对于以下代码:bandits = [Bandit(p) for p in BANDIT_PROBABILITIES]
。
我知道它将0.2
,0.5
和0.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()
答案 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(以及其他很多文献,因为有很多参考文献)。