pymc.Model
文档显示此示例:
class CustomModel(Model):
# 1) override init
def __init__(self, mean=0, sigma=1, name=''):
# 2) call super's init first, passing model and name
# to it name will be prefix for all variables here if
# no name specified for model there will be no prefix
super().__init__(name, model)
# now you are in the context of instance,
# `modelcontext` will return self you can define
# variables in several ways note, that all variables
# will get model's name prefix
# 3) you can create variables with the register_rv method
self.register_rv(Normal.dist(mu=mean, sigma=sigma), 'v1', initval=1)
# this will create variable named like '{name::}v1'
# and assign attribute 'v1' to instance created
# variable can be accessed with self.v1 or self['v1']
# 4) this syntax will also work as we are in the
# context of instance itself, names are given as usual
Normal('v2', mu=mean, sigma=sigma)
# something more complex is allowed, too
half_cauchy = HalfCauchy('sigma', beta=10, initval=1.)
Normal('v3', mu=mean, sigma=half_cauchy)
# Deterministic variables can be used in usual way
Deterministic('v3_sq', self.v3 ** 2)
# Potentials too
Potential('p1', pt.constant(1))
# After defining a class CustomModel you can use it in several
# ways
# I:
# state the model within a context
with Model() as model:
CustomModel()
# arbitrary actions
# II:
# use new class as entering point in context
with CustomModel() as model:
Normal('new_normal_var', mu=1, sigma=0)
# III:
# just get model instance with all that was defined in it
model = CustomModel()
# IV:
# use many custom models within one context
with Model() as model:
CustomModel(mean=1, name='first')
CustomModel(mean=2, name='second')
# variables inside both scopes will be named like `first::*`, `second::*`
显然这不是一个工作示例,而是旨在概述定义自定义 PyMC 模型类的一些内部结构。
我确实对这个例子的一部分有疑问。当父类用
super().__init__(name, model)
初始化时,我看到传递了两个参数:name
和 model
。我认为 name
可能只是一个字符串,但我不太清楚的是 model
应该是什么。 model
也应该是一个字符串吗?还是别的?
从您链接的文档中,
model
似乎是一个模块级变量,由上下文管理器设置:
with Model() as model: # the "as model" part, here
CustomModel()
我不知道为什么要使用上下文管理器,但就像这样做:
class Bar:
def __init__(self):
self.value = model
# just to demonstrate & FYI
try:
Bar() # will raise that "model" is undefined
except NameError as ex:
print(ex)
# entering the contextmanager
model = Model() # the "as model"
model.__enter__()
try:
bar = Bar() # doesn't raise this time
except Exception as ex:
# exiting the contextmanager that errored
model.__exit__(type(err), err, err.__traceback__)
else:
# exiting the contextmanager without an error
model.__exit__(None, None, None)
assert bar.value is model # True
换句话说,在那个例子中,
model
是Model()
。
IMO 代码确实令人困惑,如果它作为显式构造函数 arg 传入,则不会那么混乱。