ベイズ推論用ライブラリー・・PyMC3での変数の設定

##PythonのPyMC3の解説
[「Pythonで体験するベイズ推論」](https://github.com/CamDavidsonPilon/Probabilistic-Programming-and-Bayesian-Methods-for-Hackers)から、`PyMC3`での変数の設定の方法を解説する。

第２章の２．１の`PyMC2`の内容を`PyMC3`用に若干変更しています。

###変数について
`PyMC3`では、`Model`オブジェクト内で必要なすべての変数を処理します。

```python

import pymc3 as pm

with pm.Model() as model:
    parameter = pm.Exponential("poisson_param", 1.0)
    data_generator = pm.Poisson("data_generator", parameter)

with model:
    data_plus_one = data_generator + 1

with pm.Model() as model:
    theta = pm.Exponential("theta", 2.0)
    data_generator = pm.Poisson("data_generator", theta)    
    
with pm.Model() as ab_testing:
    p_A = pm.Uniform("P(A)", 0, 1)
    p_B = pm.Uniform("P(B)", 0, 1)

print("parameter.tag.test_value =", parameter.tag.test_value)
print("data_generator.tag.test_value =", data_generator.tag.test_value)
print("data_plus_one.tag.test_value =", data_plus_one.tag.test_value)

#parameter.tag.test_value = 0.6931471824645996
#data_generator.tag.test_value = 0
#data_plus_one.tag.test_value = 1

```

変数には親変数と子変数がある。
親変数は他の変数に影響を与える変数で、子変数は他の変数から影響を受ける変数である。

この場合、`parameter`は、`data_generator`の親変数である。逆に`data_generator`は`parameter`の子変数である。
すでに作成したモデルオブジェクトの名前（`model`）で「`with`」を使用することにより、同じモデル内で変数を作ることができます。
また`PyMC`変数は値を持っている。もし変数が子変数であれば親変数が変われば、子変数の値も変わる。

`PyMC3`変数には初期値（つまり、テスト値）があります。 `****.tag.test_value`で初期値が得られます。`test_value`は、開始位置が指定されていない場合のサンプリングの開始点として使用されます。

####２つの変数（確率的変数と決定的変数）
`PyMC3`は、確率的(stochhastic)および決定的(deterministic)という2つの変数があります。

確率的変数(stochhastic)は、決定的でない変数である。つまり、この変数の親変数の値を知っていても、この変数は依然としてランダムである。このカテゴリーに属するクラスには、Poisson（ポアソン分布）、DiscreteUniform（一様分布）、およびExponential（指数分布）がある。

決定的(deterministic)変数は、親変数の値がわかっていたら、その値が決まる変数である。
一瞬紛らわしいと感じるがこのように考えましょう。「変数`foo`の親変数がすべてわかった時にその`foo`の値が決まるか？」もし値が決まるなら、その`foo`は決定的変数である。

####確率的変数の初期化

確率変数またはランダム変数を初期化するための第１引数は、変数の名前を表す文字列で、第２引数以降にクラス固有の追加引数を渡すことができます。

`some_variable = pm.DiscreteUniform（ "discrete_uni_var"、0、4）`

これは、DiscreteUniform（一様分布）クラスで、`discrete_uni_var`が変数の名前で、0と4は、確率変数が取りえる上限と下限である。

引数に渡す名前は、事後分布を作時に必要になるので、できるだけわかりやすい方がよい。
また、多くの変数を使う問題の時は、`shape`引数を使います。モデル化したい多くの変数$𝛽𝑖、𝑖= 1、...、𝑁$が存在するという時に便利です。次のようにそれぞれに任意の名前と変数を作成する代わりに

```python

beta_1 = pm.Uniform（ "beta_1"、0、1）
beta_2 = pm.Uniform（ "beta_2"、0、1）
```
次のように一つの変数で作ることができる。

```python
betas = pm.Uniform（ "betas"、0、1、shape = N）
```
####確定的変数の初期化

確率変数を作成する方法と同様に、確定変数を作成できます。 `PyMC3`で`pm.Deterministic`クラスを呼び出し、必要な引数を渡すだけです。

```python
deterministic_variable = pm.Deterministic（ "deterministic variable"、some_function_of_variables）
```
これで、決定的変数を作成することができます。

```python
with pm.Model() as model:
    lambda_1 = pm.Exponential("lambda_1", 1.0)
    lambda_2 = pm.Exponential("lambda_2", 1.0)
    tau = pm.DiscreteUniform("tau", lower=0, upper=10)

new_deterministic_variable = lambda_1 + lambda_2
```

これは、[ベイズ推論の考え方（３）・・pymc3による実際の計算](https://qiita.com/motoyuki1963/items/d4d59d320dbd58a68df6)で使ったスクリプトです。

このように加減などの演算子を使った計算をしたものは暗黙的に決定的変数になります。つまり`new_deterministic_variable`は決定的変数です。

```math

\lambda = 
\begin{cases}\lambda_1  & \text{if } t \lt \tau \cr
\lambda_2 & \text{if } t \ge \tau
\end{cases}

```
####theanoとは
どうも`theano`とは、昔のディープラーニング用のライブラリーのようです。`PyMC3`のバックエンドで計算しています。でも、`PyMC4`では、`tensorflow`がバックエンドになったようなので、この勉強限りのお付き合いですので、あまり気にしないようにしましょう。

####モデルに観測を組み込む
ここまでで、変数の設定。つまり事前分布の指定が完了している。
つまりλの形とかも表すことができます。つまり、[ベイズ推論の考え方（２）・・ベイズ推定と確率分布](https://qiita.com/motoyuki1963/items/904d8c8ecb340a801ebb)でのベイズの定理の$P(A)$を決定したことになる。これに、データ（あるいは証拠、観測等）である$X$をモデルに組み込むことを行う。