Python 如何理解PyMC模型中“收益率”的用法?

Python 如何理解PyMC模型中“收益率”的用法?,python,generator,yield,pymc,Python,Generator,Yield,Pymc,我自己不是PyMC的用户,但最近我偶然发现了一个PyMC模型的片段: def线性回归(x): 比例=产量tfd。半柯西(0,1) coefs=屈服tfd.法线(tf.零点(x.形状[1]),1,) 预测=产量tfd.Normal(tf.linalg.matvec(x,coefs),比例) 回归预测 作者建议用户 会对bar=yield foo感到不舒服 我确实感到不舒服。我试图弄明白这台发电机的意义,但看不出它是如何使用的 这是我的思考过程。如果我执行foo=linear\u regressi

我自己不是PyMC的用户,但最近我偶然发现了一个PyMC模型的片段:

def线性回归(x):
比例=产量tfd。半柯西(0,1)
coefs=屈服tfd.法线(tf.零点(x.形状[1]),1,)
预测=产量tfd.Normal(tf.linalg.matvec(x,coefs),比例)
回归预测
作者建议用户

会对
bar=yield foo感到不舒服

我确实感到不舒服。我试图弄明白这台发电机的意义,但看不出它是如何使用的

这是我的思考过程。如果我执行
foo=linear\u regression(bar)
并执行
foo
(例如
next(foo)
),它将向我返回
scale
的值。但是,这也会将局部变量
scale
变为
None
。类似地,如果再次执行
foo
,我可以获得
coefs
的值,但是本地
coefs
将变为
None
。由于本地
量表
coefs
均为
None
,如何评估
预测

或者有没有一种方法可以评估
foo
,而不触发
scale
coefs
上的
yield
,并直接在
预测上产生收益


这里的黑魔法是什么?需要帮助。

披露:我是这本书的作者

我认为您的主要误解是:Python生成器不仅可以为您生成值,还可以使用
generator.send()
将值发送回生成器。因此,
bar=yield foo
将向您提供
foo
;生成器将等待您向其发送另一个值(可以是
None
,如果您只需调用
next(generator)
!),将该值分配给
bar
,然后继续运行生成器

下面是一个简单的例子:

>>>定义添加一个生成器():
...     x=0
...     尽管如此:
...         x=收益率x+1
...
>>>gen=添加一个发电机()
>>>y=gen.send(None)#要启动发电机,第一个发送值必须为None
>>>打印(y)
1.
>>>z=发电机发送(2)
>>>打印(z)
3.
请注意,当I
send(2)
时,生成器将发送的值分配给
x
,然后继续执行。在这种情况下,这仅仅意味着
再次产生x+1
,这就是为什么产生的
z
3

有关此模式的更多信息以及它可能有用的原因,请参阅

下面是一些伪代码,它使我们更接近(可能)PyMC4中的工作方式:

>>定义线性回归(x):
...     比例=产量tfd。半柯西(0,1)
...     coefs=屈服tfd.法线(tf.零点(x.形状[1]),1,)
...     预测=产量tfd.Normal(tf.linalg.matvec(x,coefs),比例)
...     回归预测
>>>模型=线性回归(数据)
>>>下一个分布=model.send(无)
>>>规模=pymc_do_things(下一个分布)
>>>coefs=pymc_do_things(model.send(scale))
>>>预测=pymc_do_things(model.send(coefs))

很惊讶文章作者回答了我的问题。谢谢你的解释。我想PyMC4以这种方式构造API的原因是用户可以按照自己的意愿注入
scale
coefs
,对吧?几乎是这样:它允许PyMC4推理引擎按照自己的意愿注入
scale
coefs
。用户指定的模型生成器向PyMC4生成分布,PyMC4将与这些分布交互,并将分布重新注入模型生成器。