オーストラリアで勉強してきたMLデザイナーの口語自由詩

主に、データ分析・機械学習・ベイズ・統計について自由に書く。

pymc4のソースコード読んでみた - “RandomVariable”, Initial Model Class, sampling and random variable [aafa32d]

f:id:yukinagae:20171122095115p:plain

コミット

2018/05/30のコミットです。

Initial Model Class, sampling and random variable · pymc-devs/pymc4@aafa32d · GitHub

主に、pymc4の根幹となる ModelRandomVariable クラスが作成されています。

以下ファイルが追加されています。

  • .vscode/settings.json
  • pymc4/init.json
  • pymc4/model.py
  • pymc4/random_variable.py
  • pymc4/sample.py
  • test.ipynb

一つ一つを細かくみたいので、今回は random_variable.pyRandomVariable クラスだけを見てみます。

random_variable.py

以下の4つが記述されています。

  • future系のimport
  • edward2のimport
  • PyMC4自身のModelクラスのimport
  • edward2の RandomVariable クラスを継承したクラスを作成
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function


from tensorflow_probability import edward2 as ed
from pymc4 import Model

class RandomVariable(ed.RandomVariable):
    
    def __init__(
                self,
                distribution,
                sample_shape=(),
                value=None,
                name="RV"
                ):
        self.model = Model.get_context()
        self.name = name

        super(RandomVariable, self).__init__(
                                                distribution,
                                                sample_shape,
                                                value,
                                                )
        
        self.model.add_random_variable(self)

future系のimport

python2とpython3で挙動が異なる処理の差異を吸収してくれるパッケージのようです。多くのpythonライブラリでimportされていると記憶しています。

future is the missing compatibility layer between Python 2 and Python 3. It allows you to use a single, clean Python 3.x-compatible codebase to support both Python 2 and Python 3 with minimal overhead.

see: Overview: Easy, clean, reliable Python 2/3 compatibility — Python-Future documentation

例えば2系と3系では、文字列とバイト列の処理で差異がありますが、futureを使うことで以下のような問題も吸収してくれるみたいです(Bytes, strings and Unicode: Common migration problems — Supporting Python 3: An in-depth guide

# Backported Py3 bytes object
b = bytes(b'ABCD')
assert list(b) == [65, 66, 67, 68]
assert repr(b) == "b'ABCD'"
# These raise TypeErrors:
# b + u'EFGH'
# bytes(b',').join([u'Fred', u'Bill'])

edward2のimport

PyMC4のバックエンドに採用された edward2 がimportされています。この edward2 はもともと blei-lab/edward でしたが、最近tensorflowの確率系のライブラリとして吸収されました。ちなみに、edwardの作者のDustin Tranは今年の2月にgoogleに入社したみたいです(Dustin's Blog: I joined Google | Dustin Tran

see: GitHub - tensorflow/probability: Probabilistic reasoning and statistical analysis in TensorFlow

PyMC4自身のModelクラスのimport

次回ソースコードリーディングします。

edward2の RandomVariable クラスを継承したクラスを作成

単に edward2RandomVariable クラスを継承しているだけです。

異なる点は、name を設定している点と、PyMC4の ModelModel.get_context で取得している点です。self.model.add_random_variable(self) あたりのコードは、Model クラスのコードを読めばわかると思います。

self.model = Model.get_context()
self.name = name
(中略)
self.model.add_random_variable(self)

see: probability/random_variable.py at master · tensorflow/probability · GitHub

class RandomVariable(ed.RandomVariable):
    
    def __init__(
                self,
                distribution,
                sample_shape=(),
                value=None,
                name="RV"
                ):
        self.model = Model.get_context()
        self.name = name

        super(RandomVariable, self).__init__(
                                                distribution,
                                                sample_shape,
                                                value,
                                                )
        
        self.model.add_random_variable(self)

参考資料