複数の分布を混合したモデル
$$ p(X) = \sum_{Z\in\mathcal{Z}}p(X \mid Z) p(Z) $$
有限個のガウス分布を混合したモデル
$$ p(X) = \sum_{Z=1}^{K} p(X \mid Z) p(Z) $$ where $$ \begin{align} p(X \mid Z) &= \mathcal{N}(X; \mu_{Z}, \Sigma_{Z})~(\mu_Z\in\mathbb{R}^D, \Sigma_{Z}\in\mathbb{S}_{+}^D)\\ p(Z=k) &= \pi_k~(k=1,\dots,K) \end{align} $$ ここで $\sum_{k=1}^K \pi_k = 1$ が成り立つとする。
有限個のガウス分布を混合したモデル
$$ p(X) = \sum_{k=1}^{K} \pi_k \mathcal{N}(X; \mu_{k}, \Sigma_{k}) $$
と書くことが多い。
混合ガウスモデルは $K+1$ 個の確率分布で構成される
2つの正規分布からなる GMM
確率変数 $X$ を生成する過程としても解釈できる
数式では以下のように書く
$$ \begin{align} Z &\sim \mathrm{Categorical}(\mathbf{\pi})\\ X &\sim \mathcal{N}(\pi_{Z}, \Sigma_{Z}) \end{align} $$
★のデータ $X$ は $Z=1$ から生成されたっぽい
次のGMMに従う確率変数 $X$ を生成し、ヒストグラムを書け
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
def gmm_sampling(sample_size):
z_sample = np.random.binomial(n=1, p=0.5, size=(sample_size,))
x_sample = np.random.randn(sample_size)
return x_sample + 10.0 * z_sample - 5.0
sample = gmm_sampling(10000)
plt.hist(sample, bins=100)
plt.show()
<matplotlib.figure.Figure at 0x10907de10>
$$ \theta^\star = \arg\max_{\theta\in\Theta}p(\mathcal{D} ; \theta) $$ をパラメタの推定値とする
各データの独立同分布性を仮定すると
$$ \begin{align} \log p(\mathcal{D}; \theta) &= \sum_{n=1}^N \log p(x_n; \theta)\\ \end{align} $$
モデルの仮定では、 $p(x;\theta) = \sum_{z=1}^{K}p(x \mid z;\theta)p(z;\theta)$ だったので、上式は、
$$ \begin{align} \sum_{n=1}^N \log \left( \sum_{z_n=1}^{K} p(x_n \mid z_n; \theta)p(z_n;\theta)\right)\tag{1} \end{align} $$
となる。
最尤推定量は式(1)を最大化することで求まる。
最大化の手法は二種類
隠れ変数があるモデルの最尤推定量を求めるアルゴリズム
$$ p(x_n, z_n; \theta) = \pi_{z_n} \mathcal{N}(x_n; \mu_{z_n}, \Sigma_{z_n}) $$
$$ \begin{align} -\sum_{n=1}^{N}\log p(x_n, z_n;\theta) &= -\sum_{n=1}^N \sum_{k=1}^K \mathbb{1}[z_n=k]\left(\log\pi_{k} + \log\mathcal{N}(x_n; \mu_{k}, \Sigma_{k})\right)\\ &=\sum_{n=1}^N \sum_{k=1}^K \mathbb{1}[z_n=k]\left(-\log\pi_{k} + \dfrac{1}{2}(x_n - \mu_{k})^\top \Sigma_{k}^{-1} (x_n - \mu_{k}) + \dfrac{D}{2}\log 2\pi + \dfrac{1}{2}\log\det\Sigma_{k}\right)\tag{2}\\ \end{align} $$
式(2)を$\mu_k$で微分すると $$ \sum_{n=1}^{N}\mathbb{1}[z_n=k]\Sigma_{k}^{-1}(x_n - \mu_k) $$ なので、$\mu_k$の最尤推定量は $$ \mu_k^{\star} = \dfrac{\sum_{n=1}^N \mathbb{1}[z_n=k]x_n}{\sum_{n=1}^N \mathbb{1}[z_n=k]} $$ となる。
式(2)を$\Sigma_k$で微分すると
$$ \dfrac{1}{2}\sum_{n=1}^N \mathbb{1}[z_n=k]\left(-\Sigma_k^{-1}(x_n - \mu_k)(x_n - \mu_k)^\top\Sigma_k^{-1} + \Sigma_k^{-1}\right) $$
なので、$\Sigma_k$の最尤推定量は
$$ \Sigma_k^\star = \dfrac{\sum_{n=1}^{N}\mathbb{1}[z_n=k](x_n - \mu_k^\star)(x_n-\mu_k^\star)^\top}{\sum_{n=1}^{N}\mathbb{1}[z_n=k]} $$
となる
$\pi_k$ は $\sum_{k=1}^{K}\pi_k=1$ を満たす必要があるため、 式(2)に$\lambda \left(\sum_{k=1}^K \pi_k - 1\right)$を足したものを$\pi_k$で微分して $$ \sum_{n=1}^N \mathbb{1}[z_n=k]\left(-\dfrac{1}{\pi_k^\star}\right) + \lambda=0 $$ を解けば良い。 $$ \lambda \pi_k^{\star} = \sum_{n=1}^N \mathbb{1}[z_n=k] $$ を $k=1,\dots,K$ で足すと $$ \lambda = N. $$ よって、 $$ \pi_k^{\star} = \dfrac{\sum_{n=1}^N \mathbb{1}[z_n=k]}{N} $$
(2) $p(Z \mid X; \theta) \propto p(X \mid Z; \theta)p(Z; \theta)$ なので、
$$ p(Z_n \mid X_n=x_n;\theta^\star) = \dfrac{\pi_{Z_n}^{\star}\mathcal{N}(x_n; \mu_{Z_n}^{\star}, \Sigma_{Z_n}^{\star})}{\sum_{k=1}^K\pi_{k}^{\star}\mathcal{N}(x_n; \mu_{k}^{\star}, \Sigma_{k}^{\star})} $$
$z_n$ が1つに決まっていると、 $$ \begin{align} \sum_{n=1}^N \log \left( \sum_{z_n=1}^{K} p(x_n \mid z_n; \theta)p(z_n;\theta)\right) \end{align} $$ の log のなかの足し算がなくなって、 $$ \begin{align} \sum_{n=1}^N \left(\log p(x_n \mid z_n; \theta) + \log p(z_n;\theta)\right) \end{align} $$ の最大化となるため、解析的に解ける。
任意の分布 $q(z)$ について $$ \begin{align} \log \left(\sum_{z}p(x\mid z; \theta) p(z;\theta)\right) = \log \left(\sum_{z}p(x\mid z; \theta) \dfrac{p(z;\theta)}{q(z)}q(z)\right) \geq \sum_{z}q(z)\log \left(p(x\mid z; \theta) \dfrac{p(z;\theta)}{q(z)}\right)\\ = \sum_{z}q(z)\left(\log p(x, z; \theta) - \log{q(z)}\right) \end{align} $$ が成り立つことを利用する。
とする。
$$ f\left(\sum_{n=1}^N w_n x_n\right)\leq \sum_{n=1}^N w_n f\left(x_n\right) $$ を示せ (Jensenの不等式)。
$f: \mathbb{R}^{D}\rightarrow\mathbb{R}$ が凸関数 $\Longleftrightarrow$ 任意の$x_1, x_2\in\mathbb{R}^D$, $w_1, w_2\in[0,1]$ s.t. $w_1 + w_2=1$ について $$ f(w_1 x_1 + w_2 x_2) \leq w_1 f(x_1) + w_2 f(x_2) $$
$N$ の時に成り立っているとして、$N+1$の時にも成り立つことを示す。 $$ \begin{align} f\left(\sum_{n=1}^{N+1} w_n x_n\right) &= f\left(w_{N+1}x_{N+1} + \sum_{n=1}^N w_n x_n\right)\\ &=f\left(w_{N+1}x_{N+1} + (1-w_{N+1})\sum_{n=1}^N {w_n}\dfrac{x_n}{1-w_{N+1}} \right)\\ &\leq w_{N+1}f(x_{N+1}) + (1-w_{N+1})f\left(\sum_{n=1}^N \dfrac{w_n}{1-w_{N+1}}x_n\right)\\ &\leq w_{N+1}f(x_{N+1}) + (1-w_{N+1})\sum_{n=1}^N \dfrac{w_n}{1-w_{N+1}}f\left(x_n\right)\ \ \left(\text{note that}\sum_{n=1}^N \dfrac{w_n}{1-w_{N+1}}=1\right)\\ &=\sum_{n=1}^{N+1}w_n f(x_n) \end{align} $$
$\log x$ は凹関数なので、任意の分布 $q(z)$ について $$ \begin{align} \log \left(\sum_{z}p(x\mid z; \theta) p(z;\theta)\right) = \log \left(\sum_{z}p(x\mid z; \theta) \dfrac{p(z;\theta)}{q(z)}q(z)\right) \geq \sum_{z}q(z)\log \left(p(x\mid z; \theta) \dfrac{p(z;\theta)}{q(z)}\right)\\ = \sum_{z}q(z)\left(\log p(x, z; \theta) - \log{q(z)}\right) \tag{3} \end{align} $$ が成り立つ。
尤度(式(3)の左側)を最大化する代わりに尤度の下界(式(3)の右側)を最大化する: $$ \sum_{n=1}^{N}\sum_{z_n}q(z_n)(\log p(x_n, z_n; \theta) - \log q(z_n)) $$
$$ p(x_n, z_n; \theta) = \pi_{z_n} \mathcal{N}(x_n; \mu_{z_n}, \Sigma_{z_n}) $$
$$ \begin{align} -\sum_{n=1}^{N}\sum_{k=1}^K q(z_n=k)\log p(x_n, z_n=k;\theta) &= -\sum_{n=1}^N \sum_{k=1}^K q(z_n=k)\left(\log\pi_{k} + \log\mathcal{N}(x_n; \mu_{k}, \Sigma_{k})\right)\\ &=\sum_{n=1}^N \sum_{k=1}^K q(z_n=k)\left(-\log\pi_{k} + \dfrac{1}{2}(x_n - \mu_{k})^\top \Sigma_{k}^{-1} (x_n - \mu_{k}) + \dfrac{D}{2}\log 2\pi + \dfrac{1}{2}\log\det\Sigma_{k}\right)\\ \end{align} $$
式(2)で $\mathbb{1}[z_n=k]$ を $q(z_n=k)$ に変えたやつだ!
よって $$ \begin{align} \mu_k^{\star} &= \dfrac{\sum_{n=1}^N q(z_n=k)x_n}{\sum_{n=1}^N q(z_n=k)}\\ \Sigma_k^\star &= \dfrac{\sum_{n=1}^{N}q(z_n=k)(x_n - \mu_k^\star)(x_n-\mu_k^\star)^\top}{\sum_{n=1}^{N}q(z_n=k)}\\ \pi_k^{\star} &= \dfrac{\sum_{n=1}^N q(z_n=k)}{N} \end{align} $$
$q$ は $\sum_{k=1}^K q(z_n=k)=1~(n=1,\dots,N)$ を満たす $N\times K$ 個の実数からなる。
$$ \begin{align} &\dfrac{\partial}{\partial q(z_n=k)}\left(\sum_{n=1}^{N}\sum_{k=1}^K q(z_n=k)(\log p(x_n, z_n=k; \theta) - \log q(z_n=k)) + \sum_{n=1}^N\lambda_n \left(\sum_{k=1}^K q(z_n=k) - 1\right)\right)\\ =&\log p(x_n, z_n=k;\theta) - \log q(z_n=k) - 1 + \lambda_n = 0 \end{align} $$ を解くと
$$ \begin{align} q(z_n=k) &= \dfrac{p(x_n, z_n=k;\theta)}{\sum_{k=1}^K p(x_n, z_n=k;\theta)} \\ &= \dfrac{\pi_k \mathcal{N}(x_n; \mu_k, \Sigma_k)}{\sum_{k=1}^K \pi_k \mathcal{N}(x_n; \mu_k, \Sigma_k)} \end{align} $$
適当な終了条件で繰り返しをやめる
補助的なものを持っていてもよい
内部状態として他のクラスのオブジェクトを持っていてもよい
正規分布クラス
GMM クラス
まずは正規分布クラスを実装してみよう
正規分布クラスを実装せよ(以前の資料からコピペでOK)
import numpy as np
class Gaussian:
def __init__(self, dim):
'''コンストラクタ(みたいなもの)
オブジェクトを作るときに初めに実行される。
内部状態の初期化に使う
'''
self.dim = dim
'''
self = オブジェクトを指す。 self.dim は、オブジェクトの dim という変数を指す。
上の命令は、 self.dim に dim の値を代入することを表す
'''
self.set_mean(np.random.randn(dim)) # オブジェクトの mean という変数をランダムに初期化
self.set_cov(np.identity(dim))
def log_pdf(self, X):
''' 確率密度関数の対数を返す
Parameters
----------
X : numpy.array, shape (sample_size, dim)
Returns
-------
log_pdf : array, shape (sample_size,)
'''
if X.shape[1] != self.dim: # 入力の形をチェックしています
raise ValueError('X.shape must be (sample_size, dim)')
return -0.5 * np.sum((X - self.mean) * (np.linalg.solve(self.cov, (X - self.mean).T).T), axis=1) \
-0.5 * self.dim * np.log(2.0 * np.pi) - 0.5 * np.linalg.slogdet(self.cov)[1]
def fit(self, X):
''' X を使って最尤推定をする
Parameters
----------
X : numpy.array, shape (sample_size, dim)
'''
if X.shape[1] != self.dim: # 入力の形をチェックしています
raise ValueError('X.shape must be (sample_size, dim)')
self.set_mean(np.mean(X, axis=0))
self.set_cov((X - self.mean).T @ (X - self.mean) / X.shape[0])
def sample(self, sample_size):
''' 現状のパラメタを使って `sample_size` のサイズのサンプルを生成する
Parameters
----------------
sample_size : int
Returns
-----------
X : numpy.array, shape (sample_size, dim)
各行は平均 `self.mean`, 分散 `self.cov` の正規分布に従う
'''
return np.random.multivariate_normal(self.mean, self.cov, size=sample_size)
def set_mean(self, mean):
if mean.shape != (self.dim,):
raise ValueError('input shape inconsistency')
self.mean = mean
def set_cov(self, cov):
if cov.shape != (self.dim, self.dim):
raise ValueError('input shape inconsistency')
if np.linalg.eigvalsh(cov)[0] <= 0:
raise ValueError('covariance matrix must be positive semidefinite.')
self.cov = cov
__init__
を書いてみようclass GMM:
def __init__(self, dim, num_components):
self.dim = dim
self.num_components = num_components
self.weight = np.ones(self.num_components) / self.num_components
self.gaussian_list = []
for _ in range(self.num_components):
self.gaussian_list.append(Gaussian(dim))
# gmm のオブジェクトができた
gmm = GMM(2, 10)
for each_gaussian in gmm.gaussian_list:
print(each_gaussian.mean)
print(gmm.weight)
[ 0.11684931 -1.71658838] [-1.10708776 0.25183766] [-1.24486871 0.55898262] [ 1.77706673 -1.59593316] [ 1.5407428 -0.58973061] [-1.81424689 0.16981966] [-0.12951037 0.52775457] [ 0.24461285 -0.3235077 ] [1.2561859 0.75503971] [ 0.15138818 -0.42148386] [0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1]
以降、EMアルゴリズムでパラメタ推定をする fit
を書きたい
log_pdf
: 現在のパラメタを用いてサンプルの対数尤度を計算するメソッドe_step
: Eステップを実行するメソッドm_step
: Mステップを実行するメソッドの3つを実装し、これらを組み合わせて fit
を書く
log_pdf
を GMM
に実装せよX
: サンプルサイズ$\times$次元の行列class GMM:
def __init__(self, dim, num_components):
self. dim = dim
self.num_components = num_components
self.gaussian_list = []
self.weight = np.ones(self.num_components) / self.num_components
for _ in range(self.num_components):
self.gaussian_list.append(Gaussian(dim))
def log_pdf(self, X):
sample_size = X.shape[0]
likelihood = np.zeros(sample_size) # 各データの尤度を計算する
'''
ここで現在の内部状態での likelihood を計算する
** ヒント **
self.gaussian_list の各要素は Gaussian クラスのオブジェクト
各データの対数尤度を計算する log_pdf という命令が実装してあった
'''
return np.log(likelihood) # 対数尤度が欲しいので対数をとる
self.gaussian_list[0].log_pdf(X)
はサンプル X
のデータそれぞれに対する対数尤度を計算するX
が sample_size
x dim
とすると、返り値は長さ sample_size
の配列self.weight[0]
は $p(z=0; \theta)$ に対応するself.weight[0] * np.exp(self.gaussian_list[0].log_pdf(X))
は np.exp(self.gaussian_list[0].log_pdf(X))
の各要素に self.weight[0]
を掛けた値を返すスカラー * 配列
と書くと、配列の各要素にスカラーを掛けてくれる(numpy
の記法)class GMM:
def __init__(self, dim, num_components):
self. dim = dim
self.num_components = num_components
self.gaussian_list = []
self.weight = np.ones(self.num_components) / self.num_components
for _ in range(self.num_components):
self.gaussian_list.append(Gaussian(dim))
def log_pdf(self, X):
sample_size = X.shape[0]
likelihood = np.zeros(sample_size) # 各データの尤度を計算する
for each_component in range(self.num_components):
likelihood = likelihood + self.weight[each_component] * np.exp(self.gaussian_list[each_component].log_pdf(X))
return np.log(likelihood)
gmm = GMM(2, 10)
gmm.log_pdf(np.random.randn(100, 2)) # とりあえず何か計算はできている
array([-2.78514385, -2.96952946, -3.46088844, -3.81387769, -2.45415219, -4.0092061 , -3.67552912, -3.83366615, -2.53445331, -3.74449755, -2.6104049 , -2.41452569, -2.4230176 , -2.81333828, -3.37597623, -2.78093397, -3.01763294, -3.26867491, -2.408466 , -2.44758434, -2.93138233, -2.65955736, -2.56725667, -3.63483237, -3.62195973, -2.99269766, -3.13356357, -3.6967527 , -3.00763763, -4.16354183, -2.66662783, -3.12049899, -2.99516738, -2.93773605, -2.55619206, -3.58616923, -2.91703624, -3.30964588, -2.39991612, -3.35450761, -2.65045314, -4.01245388, -3.04019383, -4.23433282, -2.99336927, -2.74891084, -2.94012484, -2.82226163, -2.6190409 , -2.66019962, -2.81912315, -6.57761508, -2.88257211, -2.54466193, -2.46019745, -2.50746067, -2.55682163, -2.50912637, -3.06287105, -3.67639262, -2.91834628, -2.58114342, -3.9217804 , -2.66797509, -3.2508557 , -3.24984471, -2.42023258, -3.05347674, -2.89008328, -2.70997084, -4.26476596, -2.96776401, -3.31425977, -2.64371565, -3.79660247, -2.6650101 , -3.39986012, -2.98218653, -3.41592214, -3.41550022, -2.50111109, -3.42796452, -2.4727389 , -2.56389171, -2.51620327, -2.99860948, -4.60361547, -3.08131667, -3.03534468, -3.37597112, -2.84828843, -3.09092155, -4.03144124, -2.43948881, -2.77699682, -2.75943703, -3.13733596, -2.92244085, -2.90269501, -2.58821306])
e_step
を実装せよX
: sample_size
$\times$ dim
の配列n_components
posterior
: sample_size
$\times$ n_components
の配列として出力posterior[n, k]
= $q(z_n=k)$E-step: for each $n=1,\dots,N, k=1,\dots,K$, $$q(z_n=k)\leftarrow \dfrac{\pi_k \mathcal{N}(x_n; \mu_k, \Sigma_k)}{\sum_{k=1}^K \pi_k \mathcal{N}(x_n; \mu_k, \Sigma_k)}$$
class GMM:
def __init__(self, dim, num_components):
self.dim = dim
self.num_components = num_components
self.gaussian_list = []
self.weight = np.ones(self.num_components) / self.num_components
for _ in range(self.num_components):
self.gaussian_list.append(Gaussian(dim))
def log_pdf(self, X):
sample_size = X.shape[0]
likelihood = np.zeros(sample_size) # 各データの尤度を計算する
for each_component in range(self.num_components):
likelihood = likelihood + self.weight[each_component] * np.exp(self.gaussian_list[each_component].log_pdf(X))
return np.log(likelihood)
def e_step(self, X):
sample_size = X.shape[0]
posterior = np.zeros((sample_size, self.num_components))
'''
ここを埋める
** ヒント **
各 n について、分母は共通
1. 分子を先に計算して posterior に入れてしまう
2. posterior[n, :].sum() は分母と等しくなる
3. posterior[n, :] = posterior[n, :] / posterior[n, :].sum() とすれば良さそう
'''
return posterior
class GMM:
def __init__(self, dim, num_components):
self.dim = dim
self.num_components = num_components
self.gaussian_list = []
self.weight = np.ones(self.num_components) / self.num_components
for _ in range(self.num_components):
self.gaussian_list.append(Gaussian(dim))
def log_pdf(self, X):
sample_size = X.shape[0]
likelihood = np.zeros(sample_size) # 各データの尤度を計算する
for each_component in range(self.num_components):
likelihood = likelihood + self.weight[each_component] * np.exp(self.gaussian_list[each_component].log_pdf(X))
return np.log(likelihood)
def e_step(self, X):
sample_size = X.shape[0]
posterior = np.zeros((sample_size, self.num_components))
# 各コンポーネントで対数尤度が計算できるので、それを利用
for each_component in range(self.num_components):
posterior[:, each_component] \
= self.weight[each_component] * np.exp(self.gaussian_list[each_component].log_pdf(X))
# まとめて正規化しているが、 for 文でやってもOK(遅くなるけど)
posterior = posterior / posterior.sum(axis=1).reshape(-1, 1)
return posterior
# q はデータがどちらのコンポーネントに近いかを表しているので、
# そんな感じの結果になって欲しい
gmm = GMM(2, 2)
X = gmm.gaussian_list[0].mean.reshape(1, 2)
print(gmm.e_step(X))
X = gmm.gaussian_list[1].mean.reshape(1, 2)
print(gmm.e_step(X))
[[0.96525446 0.03474554]] [[0.03474554 0.96525446]]
m_step
を実装せよX
: sample_size
$\times$ dim
の配列class GMM:
def __init__(self, dim, num_components):
self.dim = dim
self.num_components = num_components
self.gaussian_list = []
self.weight = np.ones(self.num_components) / self.num_components
for _ in range(self.num_components):
self.gaussian_list.append(Gaussian(dim))
def fit(self, X, eps=1e-8):
sample_size = X.shape[0]
converge = False
old_ll = -np.inf
new_ll = -np.inf
while not converge:
posterior = self.e_step(X)
self.m_step(X, posterior)
new_ll = self.log_pdf(X).sum()
if new_ll < old_ll:
raise ValueError('likelihood decreases!')
if np.abs(old_ll - new_ll) / np.abs(new_ll) < eps:
converge = True
old_ll = new_ll
return posterior
def e_step(self, X):
posterior = np.zeros((X.shape[0], self.num_components))
for each_component in range(self.num_components):
posterior[:, each_component] \
= self.weight[each_component] * np.exp(self.gaussian_list[each_component].log_pdf(X))
posterior = posterior / posterior.sum(axis=1).reshape(-1, 1)
return posterior
def m_step(self, X, posterior):
self.weight = posterior.sum(axis=0)
for each_component in range(self.num_components):
self.gaussian_list[each_component].set_mean(posterior[:, each_component] @ X / self.weight[each_component])
self.gaussian_list[each_component].set_cov(
(posterior[:, each_component] * (X - self.gaussian_list[each_component].mean).T) \
@ (X - self.gaussian_list[each_component].mean) / self.weight[each_component])
self.weight = self.weight / np.sum(self.weight)
def log_pdf(self, X):
sample_size = X.shape[0]
likelihood = np.zeros(sample_size) # 各データの尤度を計算する
for each_component in range(self.num_components):
likelihood = likelihood + self.weight[each_component] * np.exp(self.gaussian_list[each_component].log_pdf(X))
return np.log(likelihood)
X = np.vstack((np.random.randn(100, 3), np.random.randn(100, 3) + 3))
gmm = GMM(3, 2)
posterior = gmm.fit(X)
print(gmm.gaussian_list[0].mean)
print(gmm.gaussian_list[1].mean)
[-0.15634628 0.0826993 0.04664785] [2.99283013 3.03949123 2.96590465]
posterior
array([[9.99999972e-01, 2.80218650e-08], [9.97371053e-01, 2.62894687e-03], [9.99999983e-01, 1.65791801e-08], [9.99999198e-01, 8.01597957e-07], [9.97733881e-01, 2.26611868e-03], [9.99476715e-01, 5.23284529e-04], [1.00000000e+00, 5.67816857e-11], [9.99999944e-01, 5.63259856e-08], [9.99999202e-01, 7.98373347e-07], [9.99999991e-01, 8.98339412e-09], [9.99999993e-01, 7.14412263e-09], [9.99999999e-01, 7.20960106e-10], [9.99999990e-01, 9.79199031e-09], [9.99999938e-01, 6.21605991e-08], [9.99999869e-01, 1.30754432e-07], [9.99999999e-01, 7.47173169e-10], [9.99985013e-01, 1.49867177e-05], [9.99999998e-01, 1.76905802e-09], [9.99999962e-01, 3.82747890e-08], [1.00000000e+00, 6.07185145e-13], [9.99999127e-01, 8.72579183e-07], [9.99913754e-01, 8.62462203e-05], [9.99999913e-01, 8.65319842e-08], [9.99999983e-01, 1.73070999e-08], [9.99999986e-01, 1.39271511e-08], [9.99999892e-01, 1.07590678e-07], [9.88421571e-01, 1.15784293e-02], [9.99999964e-01, 3.59867788e-08], [9.99999663e-01, 3.37265939e-07], [9.99999985e-01, 1.49309649e-08], [9.99999572e-01, 4.27887629e-07], [9.59783355e-01, 4.02166454e-02], [9.97050613e-01, 2.94938667e-03], [9.99999961e-01, 3.91009276e-08], [1.00000000e+00, 9.10492798e-13], [9.99999878e-01, 1.22356081e-07], [9.99965215e-01, 3.47851055e-05], [1.00000000e+00, 7.48456732e-11], [9.99993642e-01, 6.35809155e-06], [9.99999986e-01, 1.39305840e-08], [9.99994125e-01, 5.87501848e-06], [1.00000000e+00, 4.47041114e-12], [9.99987397e-01, 1.26034971e-05], [1.00000000e+00, 1.11335739e-12], [9.99998851e-01, 1.14868081e-06], [9.99999993e-01, 6.87674223e-09], [9.99999998e-01, 2.02409122e-09], [9.99998894e-01, 1.10599962e-06], [9.99996332e-01, 3.66762392e-06], [9.99999995e-01, 5.14285315e-09], [9.99999997e-01, 3.22461769e-09], [9.99999402e-01, 5.97516589e-07], [9.99989099e-01, 1.09005786e-05], [9.99971098e-01, 2.89020294e-05], [9.99896801e-01, 1.03198835e-04], [9.99999920e-01, 8.00432335e-08], [9.99999660e-01, 3.39700553e-07], [9.99619582e-01, 3.80418356e-04], [1.00000000e+00, 7.35290604e-15], [1.00000000e+00, 7.35528489e-12], [9.99979356e-01, 2.06439507e-05], [9.99998913e-01, 1.08707283e-06], [9.99999998e-01, 2.07980454e-09], [1.00000000e+00, 2.57652463e-10], [9.99997782e-01, 2.21792869e-06], [9.99999971e-01, 2.94073784e-08], [1.00000000e+00, 1.84888247e-13], [9.99999997e-01, 3.30709327e-09], [9.99999989e-01, 1.07981319e-08], [9.99999995e-01, 5.15835688e-09], [9.99999998e-01, 2.09368217e-09], [9.99675433e-01, 3.24567488e-04], [9.99896928e-01, 1.03071596e-04], [9.99996710e-01, 3.29020892e-06], [9.99999998e-01, 1.59474924e-09], [1.00000000e+00, 6.52173363e-11], [9.99999934e-01, 6.63339570e-08], [9.99999995e-01, 4.77295676e-09], [9.99998473e-01, 1.52695122e-06], [9.99999388e-01, 6.12160297e-07], [1.00000000e+00, 1.86621547e-11], [9.99999811e-01, 1.88552843e-07], [9.99999978e-01, 2.21031636e-08], [9.99999952e-01, 4.83580056e-08], [1.00000000e+00, 2.18167492e-10], [1.00000000e+00, 2.38769747e-10], [9.99999747e-01, 2.53122619e-07], [9.99999963e-01, 3.66072857e-08], [9.99997640e-01, 2.36039863e-06], [9.99999897e-01, 1.02749511e-07], [9.99999963e-01, 3.71438255e-08], [9.99999920e-01, 7.95790592e-08], [9.98109261e-01, 1.89073896e-03], [9.99999987e-01, 1.29753444e-08], [9.99999994e-01, 6.49605132e-09], [9.99979095e-01, 2.09052371e-05], [9.99999619e-01, 3.80542622e-07], [9.99962290e-01, 3.77098388e-05], [9.99999929e-01, 7.09338253e-08], [1.00000000e+00, 9.39713822e-12], [2.57839929e-10, 1.00000000e+00], [7.10030580e-10, 9.99999999e-01], [7.77263991e-05, 9.99922274e-01], [4.87672154e-07, 9.99999512e-01], [1.06497653e-13, 1.00000000e+00], [1.39125574e-09, 9.99999999e-01], [1.45855962e-07, 9.99999854e-01], [1.15844233e-10, 1.00000000e+00], [1.30885221e-07, 9.99999869e-01], [4.01342547e-03, 9.95986575e-01], [2.23846844e-06, 9.99997762e-01], [4.80096836e-12, 1.00000000e+00], [2.53902784e-07, 9.99999746e-01], [1.33699810e-06, 9.99998663e-01], [9.26144795e-13, 1.00000000e+00], [6.63946614e-09, 9.99999993e-01], [4.74685878e-05, 9.99952531e-01], [7.80325429e-12, 1.00000000e+00], [4.09353206e-09, 9.99999996e-01], [1.03403537e-07, 9.99999897e-01], [7.36491730e-11, 1.00000000e+00], [1.61149398e-08, 9.99999984e-01], [3.57696778e-09, 9.99999996e-01], [4.07324020e-10, 1.00000000e+00], [8.32553012e-08, 9.99999917e-01], [2.49562814e-04, 9.99750437e-01], [1.06010371e-12, 1.00000000e+00], [2.00498829e-08, 9.99999980e-01], [8.40632056e-13, 1.00000000e+00], [8.50063744e-10, 9.99999999e-01], [2.44062509e-07, 9.99999756e-01], [2.30363365e-08, 9.99999977e-01], [1.54354318e-12, 1.00000000e+00], [8.33215085e-06, 9.99991668e-01], [1.17876940e-09, 9.99999999e-01], [5.30530954e-09, 9.99999995e-01], [5.99631715e-05, 9.99940037e-01], [5.46127020e-10, 9.99999999e-01], [1.51642669e-05, 9.99984836e-01], [3.05980804e-07, 9.99999694e-01], [1.02057016e-05, 9.99989794e-01], [9.14538689e-06, 9.99990855e-01], [1.00902475e-02, 9.89909752e-01], [8.56886241e-08, 9.99999914e-01], [8.12302937e-06, 9.99991877e-01], [5.16071738e-06, 9.99994839e-01], [3.19395709e-06, 9.99996806e-01], [2.09877679e-08, 9.99999979e-01], [3.56352670e-07, 9.99999644e-01], [8.71899847e-10, 9.99999999e-01], [1.41279230e-06, 9.99998587e-01], [2.36027283e-05, 9.99976397e-01], [6.41034443e-01, 3.58965557e-01], [5.23253972e-09, 9.99999995e-01], [1.32300243e-03, 9.98676998e-01], [9.08053107e-11, 1.00000000e+00], [6.73462148e-06, 9.99993265e-01], [1.35862410e-05, 9.99986414e-01], [1.55411117e-09, 9.99999998e-01], [1.78898163e-08, 9.99999982e-01], [5.56246657e-07, 9.99999444e-01], [2.15857223e-04, 9.99784143e-01], [3.36432353e-07, 9.99999664e-01], [3.31609686e-07, 9.99999668e-01], [6.36769143e-08, 9.99999936e-01], [3.22594193e-10, 1.00000000e+00], [6.34359329e-08, 9.99999937e-01], [1.98389286e-07, 9.99999802e-01], [2.74824322e-08, 9.99999973e-01], [3.03502827e-09, 9.99999997e-01], [3.03011961e-07, 9.99999697e-01], [5.11191743e-09, 9.99999995e-01], [3.98535732e-04, 9.99601464e-01], [1.06161725e-06, 9.99998938e-01], [3.34384016e-06, 9.99996656e-01], [6.93024425e-10, 9.99999999e-01], [3.38301508e-08, 9.99999966e-01], [2.04188713e-01, 7.95811287e-01], [4.71264963e-07, 9.99999529e-01], [1.91537294e-10, 1.00000000e+00], [6.60530787e-06, 9.99993395e-01], [1.36686530e-12, 1.00000000e+00], [1.24327968e-05, 9.99987567e-01], [3.92591447e-06, 9.99996074e-01], [2.39191117e-12, 1.00000000e+00], [5.18414949e-10, 9.99999999e-01], [6.89257801e-15, 1.00000000e+00], [4.46495438e-06, 9.99995535e-01], [2.60311464e-04, 9.99739689e-01], [3.14866310e-09, 9.99999997e-01], [5.24164837e-08, 9.99999948e-01], [1.59225146e-08, 9.99999984e-01], [3.06876781e-14, 1.00000000e+00], [4.60126666e-11, 1.00000000e+00], [1.57673959e-10, 1.00000000e+00], [1.62251036e-08, 9.99999984e-01], [1.77302902e-15, 1.00000000e+00], [7.44778750e-12, 1.00000000e+00], [6.25496083e-09, 9.99999994e-01], [3.59014236e-08, 9.99999964e-01]])