アーキテクチャをPyMC3からPyMC4へ [e334115, d07338e, 93bc07b] - pymc4のソースコード読んでみた
TL;DR
- 今までのコミットの
Model
やRandomVariable
は削除され、アーキテクチャも変更されています。削除されたコードはpymc3とほぼ同等だったので、試しに書いたコードだったようです汗。ほとんど0から読み進める感じになるので、焦らず読みやすそうな箇所から辿っていきます。
コミット
2018/06/09から2018/06/11の間のコミットです。
- tmp · pymc-devs/pymc4@e334115 · GitHub
- restructure + test point implementation · pymc-devs/pymc4@d07338e · GitHub
- fixes · pymc-devs/pymc4@93bc07b · GitHub
以下のファイルが追加・変更・削除されています。多いので少しづつ読んでいきます。
- pymc4/init.py
- pymc4/distributions/base.py
- pymc4/inference/init.py
- pymc4/inference/sampling/sample.py
- pymc4/model.py
- pymc4/random_variable.py
- pymc4/sample.py → pymc4/sampling.py
- pymc4/util/init.py
- pymc4/util/graph.py
- pymc4/util/interceptors.py
- tests/test_model.py
- test/test_nothing.py → tests/test_nothing.py
- requirements.txt
どこから読むか?
他ドキュメントやブログ記事を読んでいると、とりあず以下のように Model
クラスのインスタンスを作成することがわかっているので、 pymc4/model
パッケージ内のファイルから読み進めてみます。
model = pm4.Model([引数])
pymc4/modelパッケージ
対象パッケージ内には以下2ファイルが存在します。
- init.py
- base.py
init.py
base.py
内の Model
クラスと inline
関数をimportしているだけです。
from .base import ( Model, inline )
base.py
base.py
内では以下3つが定義されています。
- Configクラス(
__all__
に含まれていないのでexportされていない) - Modelクラス
- inline関数
まずは簡単な Config
クラスから読みます。
Config - base.py
dict
を継承したコンフィグ用のクラスを定義しているだけです。exportされていないので、 Model
クラス内でしか使用されないことがわかります。
class Config(dict): def __getattr__(self, item): try: return self.__getitem__(item) except KeyError as e: error = KeyError(item, '"{i}" is not found in configuration for the model, ' 'you probably need to pass "{i}" in model definition as ' '\n`model = pm.Model(..., {i}=value)`' '\nor' '\n' '\n@pm.inline(..., {i}=value)' '\ndef model(cfg):' '\n # your model starts here' '\n ...'.format(i=item)) raise error from e
__getattr__
が呼ばれた際に、 __get__item
を代わりに呼んでいるだけです。
- 例)
c.a
=>c['a']
また __getitem__
は KeyError
が発生する恐れがあるので、エラー情報にusageを含めています。
"{i}" is not found in configuration for the model, you probably need to pass "{i}" in model definition as `model = pm.Model(..., {i}=value)` or @pm.inline(..., {i}=value) def model(cfg): # your model starts here' ...
使い方として以下の2パターンがあることがわかります。
pm.Model
を使う場合
model = pm.Model(..., {i}=value)
@pm.inline
を使う場合
@pm.inline(..., {i}=value) def model(cfg): ...
次回はModelクラスを読んでいきます。