{ "cells": [ { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "# probabilistic Principle Component Analysis\n", "\n", "In this notebook, we will implement probabilistic Principle Component Analysis (PCA). \n", "We will work on both \n", "* maximum likelihood estimation, and \n", "* Bayesian PCA" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib as mpl\n", "from matplotlib import pyplot as plt\n", "from scipy.linalg import eigh\n", "\n", "%matplotlib inline\n", "mpl.rc(\"savefig\",dpi=100)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 1 Setting\n", "\n", "Here we consider a unsupervised learning problem. \n", "\n", "* Let $N \\in \\mathbb{N}$ be the number of data points, and\n", "* Let $d \\in \\mathbb{N}$ be the input dimension.\n", "* Denote input data by $x_0, x_1, \\dots , x_{N-1} \\in \\mathbb{R}^d$. \n", "* Denote the input data collectively by a matrix $X$, where $X_{n,i}$ is $i$-th component of $x_n$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 2 Theory\n", "\n", "\n", "## 2.1 Model\n", "\n", "\n", "* Let $m \\in \\mathbb{N}$ be the dimension of the latent variables.\n", "* Denote latent variables corresponding to input data points by $z_0, \\dots, z_{N-1} \\in \\mathbb{R}^{m}$. \n", "* Denote the latent variables collectively by $Z = (z_{n})_{ n \\in \\{ 0, 1, \\dots, N-1 \\} }$\n", "\n", "### 2.1.1 Maximum-likelihood approach\n", "\n", "In the maximum-likelihood approach, we consider the model\n", "$$\n", "\\begin{align}\n", " &{} p\\left(X,Z \\middle| W, \\mu, \\sigma^2 \\right) = \\prod_{n=0}^{N-1} p\\left(x_n \\middle| z_n, W, \\mu, \\sigma^2 \\right)p(z_n) \\\\\n", " &{} p\\left(z \\right) := \\mathcal{N}\\left(z \\middle| 0, I_m \\right) \\\\ \n", " &{} p\\left(x \\middle|z, W, \\mu, \\sigma^2 \\right) := \\mathcal{N}\\left(x \\middle| W z + \\mu, \\sigma^2 I_d \\right), \n", "\\end{align}\n", "$$\n", "where \n", "* $\\mathcal{N}\\left(\\cdot \\middle| \\mu , \\Sigma \\right)$ is a gaussian probability density with mean $\\mu$ and covariance matrix $\\Sigma$.\n", "* $\\mu \\in \\mathbb{R}^d$, $W$ is a $d \\times m$ matrix, $\\sigma > 0$, and they are the parameters of the model.\n", "\n", "### 2.1.2 Bayesian approach\n", "\n", "In the Bayesian approach, we consider the model defined by \n", "$$\n", "\\begin{align}\n", " &{} p\\left(X, Z, W \\middle| \\alpha, \\mu, \\sigma^2 \\right) := p\\left(X,Z \\middle| W, \\mu, \\sigma^2 \\right) p(W| \\alpha) \\\\\n", " &{} p\\left(W \\middle| \\alpha \\right) = \\prod_{i=0}^{m-1} \\left[ \\left( \\frac{\\alpha_i}{2\\pi}\\right)^{d/2} \\exp\\left( - \\frac{1}{2} \\alpha_i w_{i}^{T} w_i \\right) \\right]\n", "\\end{align}\n", "$$\n", "where\n", "* $p\\left(X,Z \\middle| W, \\mu, \\sigma^2 \\right)$ is the same as the previous model, \n", "* $W = (w_0, w_1, \\dots, w_{M-1})$, and $w_{i} \\in \\mathbb{R}^d$ represents column vector." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.2 Estimation\n", "\n", "### 2.2.1 Maximum likelihood estimation (analytical result)\n", "\n", "In the maximum-likelihood approach, our goal is to obtain $\\mu, W, \\sigma^2$ that maximizes the likelihood function\n", "$$\n", "\\begin{align}\n", " p\\left(X \\middle| \\mu, W, \\sigma^2 \\right) := \\int p\\left(X,Z \\middle| \\mu, W, \\sigma^2 \\right) dZ, \n", "\\end{align}\n", "$$\n", "whose form is shown in equation (12.43) of the book. \n", "\n", "An analytical solution to this maximization problem is given by\n", "\n", "$$\n", "\\begin{align}\n", " \\mu &= \\bar{x} := \\frac{1}{N} \\sum_{n=0}^{N-1} x_n \\\\\n", " W &= U_m \\left(L_m - \\sigma^2 I \\right)^{1/2} \\\\\n", " \\sigma^2 &= \\frac{1}{d-m} \\sum_{i=m}^{d-1} \\lambda_i, \n", "\\end{align}\n", "$$\n", "where \n", "* $U_m$ is a $d \\times m$ matrix, whose columns are eigenvectors of the data covariance matrix $S$ (whose definition is given below), that correspond to the largest $m$ eigenvalues.\n", "* $\\lambda_i$ are eigenvalues of $S$.\n", "* $L_m$ is a $m \\times m$ diagonal matrix, whose diagonal elements are $\\lambda_i$ corresponding to the eigenvectors listed as columns of $U_m$.\n", "\n", "$S$ is defined by\n", "$$\n", "\\begin{align}\n", " S := \\frac{1}{N} \\sum_{n=0}^{N-1} (x_n - \\bar{x}) (x_n - \\bar{x})^T, \n", "\\end{align}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### 2.2.2 Maximum likelihood estimation (EM algorithm)\n", "\n", "Here, instead of analytical solution, we take EM algorithm approach\n", "The benefit of this approach is given in Section 12.2.2 of the book. \n", "\n", "First, maximization with respect to $\\mu$ can be easily done, whose result is \n", "$$\n", "\\begin{align}\n", " \\mu = \\bar{x} := \\frac{1}{N} \\sum_{n=0}^{N-1}x_n. \n", "\\end{align}\n", "$$\n", "In this section, we will henceforth fix $\\mu$ to be this value.\n", "\n", "In EM algorithm for probabilistic PCA, we update parameters $W$ and $\\sigma^2$ as follows\n", "$$\n", "\\begin{align}\n", " & W_{new} = \\left[ \\sum_{n=0}^{N-1} (x_n - \\bar{x}) \\mathbb{E}_{old}[z_n]^T \\right] \n", " \\left[ \\sum_{n=0}^{N-1} \\mathbb{E}_{old}[z_n z_{n}^{T}] \\right]^{-1} \\\\\n", " & \\sigma^{2}_{new} = \\frac{1}{ND}\\sum_{n=0}^{N-1} \n", " \\left[ \\| x_n - \\bar{x} \\|^2 - 2 \\mathbb{E}_{old}\\left[ z_n\\right]^T W_{new}^{T} (x_n-\\bar{x})\n", " {} + \\mathrm{Tr}\\left( \\mathbb{E}_{old}\\left[ z_n z_{n}^{T} \\right] W_{new}^{T} W_{new} \\right) \\right] \\\\\n", " & \\mathbb{E}_{old}\\left[ z_n \\right] := M_{old}^{-1} W_{old}^{T} \\left( x_n - \\bar{x} \\right) \\\\\n", " & \\mathbb{E}_{old}\\left[ z_n z_{n}^{T} \\right] := \\sigma_{old}^{2} M_{old}^{-1} + \n", " \\mathbb{E}_{old}\\left[ z_n \\right] \\mathbb{E}_{old}\\left[ z_n \\right]^T \\\\\n", " & M_{old} := W_{old}^{T} W_{old} + \\sigma_{old}^{2} I_M\n", "\\end{align}\n", "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.2.3 Bayesian estimation\n", "\n", "Our goal here is to obtain $\\mu, \\alpha, \\sigma^2$ that maximizes the marginal likelihood function\n", "$$\n", "\\begin{align}\n", " p\\left(X \\middle| \\alpha, \\mu, \\sigma^2 \\right) &:= \\int p\\left(X,Z \\middle| W, \\mu, \\sigma^2 \\right) p\\left(W \\middle| \\alpha \\right) dW dZ \\\\\n", " &= \\int p\\left(X \\middle| W, \\mu, \\sigma^2 \\right) p\\left(W \\middle| \\alpha \\right) dW \n", "\\end{align}\n", "$$\n", "\n", "The maximization with respect to $\\mu$ can be easily done, whose result is\n", "$$\n", "\\begin{align}\n", " \\mu = \\bar{x} := \\frac{1}{N} \\sum_{n=0}^{N-1}x_n. \n", "\\end{align}\n", "$$\n", "In this section, we will henceforth fix $\\mu$ to be this value.\n", "\n", "The integral is not analytically tractable, and hence we resort to approximation. By applying Laplace approximation to the integral above, and neglecting the factor coming from hessian (Note : I am not sure under what kind of condition the latter approximation can be justified. ), the problem can be reduced to obtain $W, \\alpha, \\sigma^2$ that maximize\n", "$$\n", "\\begin{align}\n", " & \\frac{d}{2} \\sum_{i=0}^{m-1} \\log \\alpha_i + \\log p\\left( X \\middle| W, \\mu, \\sigma^2 \\right)\n", " {} - \\frac{1}{2} \\sum_{i=0}^{m-1} \\alpha_i \\| w_i \\|^2\n", "\\end{align}\n", "$$\n", "\n", "The maximization is done iteratively, and the update equations are as follows\n", "$$\n", "\\begin{align}\n", " & W_{new} = \\left[ \\sum_{n=0}^{N-1} (x_n - \\bar{x}) \\mathbb{E}_{old}[z_n]^T \\right] \n", " \\left[ \\sum_{n=0}^{N-1} \\mathbb{E}_{old}[z_n z_{n}^{T}] + \\sigma_{old}^{2} A \\right]^{-1} \\\\\n", " & A = \\mathrm{diag}\\left( \\alpha_{i, old} \\right) \\\\\n", " & \\sigma^{2}_{new} = \\frac{1}{ND}\\sum_{n=0}^{N-1} \n", " \\left[ \\| x_n - \\bar{x} \\|^2 - 2 \\mathbb{E}_{old}\\left[ z_n\\right]^T W_{new}^{T} (x_n-\\bar{x})\n", " {} + \\mathrm{Tr}\\left( \\mathbb{E}_{old}\\left[ z_n z_{n}^{T} \\right] W_{new}^{T} W_{new} \\right) \\right] \\\\\n", " & \\mathbb{E}_{old}\\left[ z_n \\right] := M_{old}^{-1} W_{old}^{T} \\left( x_n - \\bar{x} \\right) \\\\\n", " & \\mathbb{E}_{old}\\left[ z_n z_{n}^{T} \\right] := \\sigma_{old}^{2} M_{old}^{-1} + \n", " \\mathbb{E}_{old}\\left[ z_n \\right] \\mathbb{E}_{old}\\left[ z_n \\right]^T \\\\\n", " & M_{old} := W_{old}^{T} W_{old} + \\sigma_{old}^{2} I_m \\\\\n", " & \\alpha_{i,new} = \\frac{d}{\\|w_{i,new}\\|^2}\n", "\\end{align}\n", "$$\n", "\n", "(Note : As far as I understand, the process is not an EM algorithm, because it contains the re-estimation of $\\alpha$. Below, I use equations shown in the book, but I have not understood theoretical justifications of this iterative optimization process. )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.3 Transformation\n", "\n", "Suppose we have trained our PCA model. \n", "Let us consider a new data $\\xi$, whose corresponding latent variabl we denote $\\zeta$. \n", "\n", "The model can be used in two ways: \n", "* given the observation $\\xi$ and transform it to the corresponding latent variable $\\zeta$, or\n", "* given the latent variable $\\zeta$, inverse transform it to observable $\\xi$.\n", "\n", "Because the model is probabilistic, the output will be a probability distribution, which is given below\n", "$$\n", "\\begin{align}\n", " &{} p\\left( \\zeta \\middle| \\xi, X, W, \\mu, \\sigma^2 \\right) = \\mathcal{N}\\left( \\zeta \\middle| M^{-1} W^T (\\xi - \\mu), \\sigma^2 M^{-1} \\right)\\\\\n", " &{} p\\left( \\xi \\middle| z, W, \\mu, \\sigma^2 \\right) = \\mathcal{N}\\left( \\xi \\middle| W\\zeta + \\mu, \\sigma^2 I_d \\right) , \n", "\\end{align}\n", "$$\n", "where $M:= W^T W + \\sigma^2 I_m$.\n", "\n", "NOTE : In Bayesian case, in principle we have to integrating out $W$, but this is intractable. I simply replaced the posterior distribution of $W$ by a delta function peaked at the value of $W$ which gives the maximum of the posterior distribution (c.f. Laplace approximation in the previous section.). Under this approximation, the above result applies to both maximum-likelihood approach and Bayesian approach." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 3 From math to code\n", "\n", "We define two classes, namely, `MLPCA` class and `BPCA` class, where the former performs conventional PCA (or equivalently, maximum likelihood estimation), and the latter implements the Bayesian PCA.\n", "\n", "We first define `MLPCA` class, and then define `BPCA`, which inherits from `MLPCA`.\n", "\n", "\n", "## 3.1 `MLPCA` class\n", "\n", "### 3.1.1 Properties and methods\n", "\n", "We let `MLPCA` have the following properties and methods:\n", "\n", "#### Properties \n", "\n", "* `m` : positive integer representing $m$, i.e., the dimension of the latent variables\n", "* `d` : positive integer representing $d$, i.e., the dimension of the observable\n", "* `W` : 2D numpy array representing $W$\n", "* `mu` : 1D numpy array representing $\\mu$\n", "* `variance` : positive float representing $\\sigma^2$\n", "\n", "\n", "#### Methods\n", "\n", "* `_fit_analytical` : performing the fitting analytically.\n", "* `_init_params` : initializing model parameters `W`, `variance`, depending on the input `X`.\n", "* `_estep` : calculating and returning $\\mathbb{E}_{old}\\left[ z_n \\right]$ and $\\sum_{n=0}^{N-1} \\mathbb{E}_{old}\\left[ z_n z_{n}^{T} \\right]$\n", "* `_mstep` : updating $W$ and $\\sigma^2$ using $\\mathbb{E}_{old}\\left[ z_n \\right]$ and $\\sum_{n=0}^{N-1} \\mathbb{E}_{old}\\left[ z_n z_{n}^{T} \\right]$\n", "* `_fit_em` : performing the fitting by EM algorithm.\n", "* `fit` : performing fitting either by analytical solution or EM algorithm.\n", "* `transform` : transform a given dataset into the latent space.\n", "* `inverse_transform` : inverse transofmr a given dataset in the latent space to the original space.\n", "\n", "### 3.1.2 Code" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class MLPCA: \n", " def __init__(self, m):\n", " self.m = m\n", " self.d = None\n", " self.W = None\n", " self.mu = None\n", " self.variance = None\n", " \n", " def _fit_analytical(self, X):\n", " self.d = len(X[0])\n", " self.mu = np.mean(X, axis=0)\n", " S = np.cov(X, rowvar=False, ddof=0)\n", " eigenvals, eigenvecs = eigh(S)\n", " ind = np.argsort(eigenvals)[::-1][0:self.m] # sort the eigenvalues in decreasing order, and choose the largest m\n", " eigenvals_largest = eigenvals[ind]\n", " eigenvecs_largest = eigenvecs[:, ind]\n", " if self.d != self.m:\n", " self.variance = 1/(self.d - self.m) * np.sum(np.sort(eigenvals)[::-1][self.m:])\n", " else:\n", " self.variance = 0.0\n", " self.W = eigenvecs_largest @ np.diag( np.sqrt(eigenvals_largest - self.variance) )\n", " \n", " \n", " \n", " def _init_params(self, X, W=None, variance=None):\n", " '''\n", " Method for initializing model parameterse based on the size and variance of the input data array. \n", " \n", " Parameters\n", " ----------\n", " X : 2D numpy array\n", " 2D numpy array representing input data, where X[n, i] represents the i-th element of n-th point in X.\n", " W : 2D numpy array, default None\n", " 2D numpy array representing the initial value of parameter W\n", " variance : positive float, default is None\n", " positive float representing the initial value of parameter variance\n", " '''\n", " self.d = len(X[0])\n", " self.mu = np.mean(X, axis=0)\n", " self.W = np.eye(self.d)[:,:self.m] if (W is None) else W # probably there are better initializations \n", " self.variance = 1.0 if (variance is None) else variance\n", " \n", " def _estep(self, X):\n", " '''\n", " Method for performing E-step, returning \n", " $\\mathbb{E}_{old}\\left[ z_n \\right]$ and $\\sum_{n=0}^{N-1} \\mathbb{E}_{old}\\left[ z_n z_{n}^{T} \\right]$\n", " \n", " Parameters\n", " ----------\n", " X : 2D numpy array\n", " 2D numpy array representing input data, where X[n, i] represents the i-th element of n-th point in X.\n", " \n", " Returns\n", " ----------\n", " Ez : 2D numpy array\n", " (len(X), self.m) array, where Ez[n, i] = $\\mathbb{E}_{old}[z_n]_i$\n", " sumEzz : 2D numpy array\n", " (self.m, self.m) array, where sumEzz[i,j] = $\\sum_{n=0}^{N-1} \\mathbb{E}_{old}\\left[z_n z_{n}^{T} \\right]_{i,j}$\n", " '''\n", " Minv = np.linalg.inv( (self.W).T @ self.W + self.variance*np.eye(self.m) ) # we only use inverse of the matrix M\n", " dX = X - self.mu\n", " Ez = dX @ self.W @ (Minv.T)\n", " sumEzz = len(X) * self.variance * Minv + (Ez.T) @ Ez\n", " return Ez, sumEzz\n", " \n", " \n", " def _mstep(self, X, Ez, sumEzz):\n", " '''\n", " Method for performing M-step, and updating model parameters\n", " \n", " Parameters\n", " ----------\n", " X : 2D numpy array\n", " 2D numpy array representing input data, where X[n, i] represents the i-th element of n-th point in X.\n", " Ez : 2D numpy array\n", " (len(X), self.m) array, where Ez[n, i] = $\\mathbb{E}_{old}[z_n]_i$\n", " sumEzz : 2D numpy array\n", " (self.m, self.m) array, where sumEzz[i,j] = $\\sum_{n=0}^{N-1} \\mathbb{E}_{old}\\left[z_n z_{n}^{T} \\right]_{i,j}$\n", " '''\n", " dX = X - self.mu\n", " self.W = ((dX.T) @ Ez) @ np.linalg.inv(sumEzz)\n", " self.variance = ( np.linalg.norm(dX)**2 - 2*np.trace(Ez @ (self.W.T) @ (dX.T) ) + np.trace( sumEzz @ self.W.T @ self.W ) ) /(len(X)*self.d)\n", " \n", " \n", " def _fit_em(self, X, max_iter=100, tol=1e-4, disp_message=False, W0=None, variance0=None):\n", " '''\n", " Method for performing fitting by EM algorithm\n", " \n", " Parameters\n", " ----------\n", " X : 2D numpy array\n", " 2D numpy array representing input data, where X[n, i] represents the i-th element of n-th point in X.\n", " max_iter : positive int\n", " The maximum number of iteration allowed\n", " tol : positive float\n", " Threshold for termination of iteration. \n", " Concretely, the iteration is stopped when the change of W and variance is smaller than tol.\n", " disp_message : Boolean, default False\n", " If True, the number of iteration and convergence will displayed.\n", " W0 : 2D numpy array, default None\n", " 2D numpy array representing the initial value of parameter W\n", " variance0 : positive float, default is None\n", " positive float representing the initial value of parameter variance\n", " '''\n", " self._init_params(X, W=W0, variance=variance0)\n", " \n", " for i in range(max_iter):\n", " Wold = self.W\n", " varianceold = self.variance\n", " \n", " Ez, sumEzz = self._estep(X)\n", " self._mstep(X, Ez, sumEzz)\n", " \n", " err = np.sqrt(np.linalg.norm(self.W - Wold)**2 + (self.variance - varianceold)**2)\n", " if err < tol:\n", " break\n", " \n", " if disp_message:\n", " print(f\"n_iter : {i}\")\n", " print(f\"converged : {i < max_iter - 1}\")\n", "\n", " def fit(self, X, method='analytical', **kwargs):\n", " '''\n", " Method for performing fitting\n", " \n", " Parameters\n", " ----------\n", " X : 2D numpy array\n", " 2D numpy array representing input data, where X[n, i] represents the i-th element of n-th point in X.\n", " method : str, either 'analytical' or 'em'\n", " If method == 'analytical', _fit_analytical is invoked, while if method == 'em', _fit_em is invoked.\n", " '''\n", " if method == 'analytical':\n", " self._fit_analytical(X)\n", " elif method == 'em':\n", " self._fit_em(X, **kwargs)\n", " else:\n", " \"Method should be either `analytical` or `em`.\"\n", " \n", " \n", " def transform(self, X, return_cov=False):\n", " '''\n", " Method for performing transformation, transforming observables to latent variables\n", " \n", " Parameters\n", " ----------\n", " X : 2D numpy array\n", " (len(X), self.d) numpy array representing input data, where X[n, i] represents the i-th element of n-th point in X.\n", " return_cov : Boolean, default False\n", " If True, the covariance matrix of the predictive distribution is also returned\n", " \n", " Returns\n", " ----------\n", " Z : 2D numpy array\n", " (len(X), self.m) array representing the expectation values of the latent variables \n", " corresponding to the input observable X\n", " cov : 2D numpy array, returned only if return_cov is True\n", " (self.m, self.m) array representing the covariance matrix for the predictive distribution \n", " Concretely, it corresponds to $\\sigma^2 M^{-1}$\n", " '''\n", " Minv = np.linalg.inv( (self.W).T @ self.W + self.variance*np.eye(self.m) ) # we only use inverse of the matrix M\n", " dX = X - self.mu\n", " Z = dX @ self.W @ (Minv.T)\n", " if return_cov:\n", " cov = self.variance * Minv\n", " return Z, cov\n", " else:\n", " return Z\n", " \n", " def inverse_transform(self, Z, return_cov=False):\n", " '''\n", " Method for performing inverse transformation, transforming latent variables to observables\n", " \n", " Parameters\n", " ----------\n", " Z : 2D numpy array\n", " (len(Z), self.m) numpy array representing latent variables\n", " return_cov : Boolean, default False\n", " If True, the covariance matrix of the predictive distribution is also returned\n", " \n", " Returns\n", " ----------\n", " X : 2D numpy array\n", " (len(Z), self.d) numpy array representing input data, where X[n, i] represents the i-th element of n-th point in X.\n", " \n", " cov : 2D numpy array, returned only if return_cov is True\n", " (self.d, self.d) array representing the covariance matrix for the predictive distribution \n", " Concretely, it corresponds to $\\sigma^2 I_d$\n", " '''\n", " X = Z @ (self.W.T) + self.mu\n", " if return_cov:\n", " cov = self.variance * np.eye(self.d)\n", " return X, cov\n", " else:\n", " return X\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3.2 `BPCA` class\n", "\n", "### 3.2.1 Properties and methods\n", "\n", "We let `MLPCA` have the following properties and methods:\n", "\n", "#### Properties\n", "\n", "In addition to the properties the `MLPCA` class has, we let `BPCA` has the following property.\n", "\n", "* `alpha` : positive float representing $\\alpha$\n", "\n", "#### Methods\n", "\n", "The methods `_init_params`, `_m_step` and `fit` will be overridden appropriately, and we add the following method\n", "* `_calc_alpha` : updating $\\alpha$\n", "\n", "### 3.2.2 Code" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "class BPCA(MLPCA): \n", " def __init__(self, m):\n", " super().__init__(m)\n", " self.alpha = None\n", " \n", " def _init_params(self, X, W=None, variance=None, alpha=None):\n", " '''\n", " Method for initializing model parameterse based on the size and variance of the input data array. \n", " \n", " Parameters\n", " ----------\n", " X : 2D numpy array\n", " 2D numpy array representing input data, where X[n, i] represents the i-th element of n-th point in X.\n", " W : 2D numpy array, default None\n", " 2D numpy array representing the initial value of parameter W\n", " variance : positive float, default is None\n", " positive float representing the initial value of parameter variance\n", " alpha : positive float, default is None\n", " positive float representing the initial value of alpha\n", " '''\n", " super()._init_params(X, W, variance)\n", " self.alpha = np.ones(self.m) if (alpha is None) else alpha\n", " \n", " \n", " def _mstep(self, X, Ez, sumEzz):\n", " '''\n", " Method for performing M-step, and updating model parameters\n", " \n", " Parameters\n", " ----------\n", " X : 2D numpy array\n", " 2D numpy array representing input data, where X[n, i] represents the i-th element of n-th point in X.\n", " Ez : 2D numpy array\n", " (len(X), self.m) array, where Ez[n, i] = $\\mathbb{E}_{old}[z_n]_i$\n", " sumEzz : 2D numpy array\n", " (self.m, self.m) array, where sumEzz[i,j] = $\\sum_{n=0}^{N-1} \\mathbb{E}_{old}\\left[z_n z_{n}^{T} \\right]_{i,j}$\n", " '''\n", " dX = X - self.mu\n", " self.W = ((dX.T) @ Ez) @ np.linalg.inv(sumEzz + self.variance * np.diag(self.alpha))\n", " self.variance = ( np.linalg.norm(dX)**2 - 2*np.trace(Ez @ (self.W.T) @ (dX.T) ) + np.trace( sumEzz @ self.W.T @ self.W ) ) /(len(X)*self.d)\n", " \n", " \n", " def _calc_alpha(self):\n", " '''\n", " Method for updating the value of alpha for Bayesian approach\n", " '''\n", " wnorms = np.linalg.norm(self.W, axis=0)**2\n", " for i in range(self.m):\n", " self.alpha[i] = self.d/wnorms[i] if (wnorms[i] != 0) else np.inf\n", " \n", " def fit(self, X, max_iter=100, tol=1e-4, disp_message=False, W0=None, variance0=None, alpha0=None):\n", " '''\n", " Method for performing fitting\n", " \n", " Parameters\n", " ----------\n", " X : 2D numpy array\n", " 2D numpy array representing input data, where X[n, i] represents the i-th element of n-th point in X.\n", " max_iter : positive int\n", " The maximum number of iteration allowed\n", " tol : positive float\n", " Threshold for termination of iteration. \n", " Concretely, the iteration is stopped when the change of W and variance is smaller than tol.\n", " disp_message : Boolean, default False\n", " If True, the number of iteration and convergence will displayed.\n", " W0 : 2D numpy array, default None\n", " 2D numpy array representing the initial value of parameter W\n", " variance0 : positive float, default is None\n", " positive float representing the initial value of parameter variance\n", " alpha0 : positive float, default is None\n", " positive float representing the initial value of alpha \n", " '''\n", " self._init_params(X, W=W0, variance=variance0, alpha=alpha0)\n", " \n", " for i in range(max_iter):\n", " Wold = self.W\n", " varianceold = self.variance\n", " \n", " Ez, sumEzz = self._estep(X)\n", " self._mstep(X, Ez, sumEzz)\n", " self._calc_alpha()\n", " # convergence check. because we expect some components of alpha to be infinite, alpha is excluded from the convergence criterion\n", " err = np.sqrt(np.linalg.norm(self.W - Wold)**2 + (self.variance - varianceold)**2)\n", " if err < tol:\n", " break\n", " \n", " if disp_message:\n", " print(f\"n_iter : {i}\")\n", " print(f\"converged : {i < max_iter - 1}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 4 Experiment\n", "\n", "In this section, we shall apply our `MLPCA` and `BPCA` classes to several data.\n", "\n", "## 4.1 two dimensional Gaussian\n", "\n", "First, we consider toy example of two dimensional Gaussian distributed data." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "scrolled": true }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "rnd = np.random.RandomState(0)\n", "X = rnd.multivariate_normal(np.zeros(2), cov = np.array([[2,1],[1,2]]), size=200)\n", "plt.plot(X[:,0],X[:,1],'.')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Because the data is two-dimensional, the only meaningful choice of the latent variables dimension is $m=1$.\n", "\n", "We perform the three methods of PCA, and compare the results in two ways: \n", "\n", "1. $C$ matrix, which governs the predictive distribution, and defined by\n", "$$\n", "\\begin{align}\n", " C := W W^T + \\sigma^2 I_d. \n", "\\end{align}\n", "$$\n", "Note that $W$ is not unique in maximum-likelihood estimation, and hence directly comparing $W$ is not meaningful.\n", "2. Graphically looking at generated samples" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "n_iter : 32\n", "converged : True\n", "n_iter : 32\n", "converged : True\n" ] } ], "source": [ "max_iter = 1000\n", "\n", "mlpca1 = MLPCA(m=1)\n", "mlpca1.fit(X=X, method='analytical')\n", "\n", "mlpca2 = MLPCA(m=1)\n", "mlpca2.fit(X=X, method='em', disp_message=True, tol=1e-6, max_iter=max_iter)\n", "\n", "bpca = BPCA(m=1)\n", "bpca.fit(X=X, disp_message=True, tol=1e-6, max_iter=max_iter)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def calc_cmat(pca):\n", " W = pca.W\n", " variance = pca.variance\n", " d = len(W)\n", " return W @ (W.T) + variance*np.eye(d)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.6651931942223766e-06\n", "0.04384689691566826\n" ] } ], "source": [ "C1 = calc_cmat(mlpca1)\n", "C2 = calc_cmat(mlpca2)\n", "C3 = calc_cmat(bpca)\n", "\n", "print(np.linalg.norm(C1 - C2))\n", "print(np.linalg.norm(C1 - C3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see that the difference between the two maximum-likelihood approaches are almost negligible, as expected. " ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def plot_2dim_pca(ax, pca, X):\n", " N = len(X)\n", " \n", " rnd = np.random.RandomState(1)\n", " Z = rnd.multivariate_normal(np.zeros(1), cov=np.eye(1), size=N)\n", " X_mean, X_cov = pca.inverse_transform(Z=Z, return_cov=True)\n", " rnd = np.random.RandomState(2)\n", " noise = rnd.multivariate_normal(np.zeros(2), cov=X_cov, size=N)\n", " Xsample = X_mean + noise\n", "\n", " ax.plot(X[:, 0], X[:, 1], 'o', label='original data')\n", " ax.plot(X_mean[:,0], X_mean[:,1], label='low dimensional subset')\n", " ax.plot(Xsample[:,0], Xsample[:,1], '.', label='generated samples')\n", " ax.legend()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABBQAAAFpCAYAAAAsm3skAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzs3XucVHX9P/DXZ27sLCILuguyCgga\nmpK7uamFWeIFb9CGmZWlGWCZZvrzi4m31AxQultpslqWlpfUDTUFFay8YC7sGpqQSiw0CIvCIrKz\nO7fP74+zZ3Yu58ycM3POnDMzr2ePHhxnZ8+cM7vnNZ99n89FSClBRERERERERGSGx+kDICIiIiIi\nIqLyw4ICEREREREREZnGggIRERERERERmcaCAhERERERERGZxoICEREREREREZnGggIRERERERER\nmcaCAhERERERERGZxoICEREREREREZnGggIRERERERERmcaCAhERERERERGZ5nPiRffff385ceJE\nJ16aiEjXmjVr3pNS1jt9HKXAHCYit2IWExE5y0wOO1JQmDhxIjo6Opx4aSIiXUKIbqePoVSYw0Tk\nVsxiIiJnmclhDnkgIiIiIiIiItNYUCAiIiIiIiIi01hQICIiIiIiIiLTWFAgIiIiIiIiItNYUCAi\nIiIiIiIi01hQICIiIiIiIiLTLCsoCCG8QohOIcQTVu2TiIjMYRYTETmLOUxE1cTKHgrfBfCmhfsj\nIiLzmMVERM5iDhNR1bCkoCCEOBDAmQDarNgfERGZxywmInIWc5iIqo3Pov38DMBVAEZYtD8iR7V3\nhrBk+QZs7Q1jXF0Q82dMQWtzo9OHRZQPs5gqBnOYyhRzmCoKs5jyKbqHghDiLAA9Uso1eZ53kRCi\nQwjRsWPHjmJflsg27Z0hLHh0HUK9YUgAod4wFjy6Du2dIacPjUiXkSxmDlO5YA5TOWKbmCoNs5iM\nsGLIwzQAs4QQmwA8AGC6EOK+zCdJKe+SUrZIKVvq6+steFkieyxZvgHhaDztsXA0jiXLNzh0RESG\n5M1i5jCVC+YwlSm2iamiMIvJiKILClLKBVLKA6WUEwF8CcBKKeVXiz4yIods7Q2bepzIDZjFVEmY\nw1SOmMNUaZjFZISVqzwQVYRxdUFTjxMRkbWYw0REzmMWkxGWFhSklM9LKc+ycp9EpTZ/xhQE/d60\n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\nAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, axes = plt.subplots(1, 3, figsize=(18, 6))\n", "plot_2dim_pca(axes[0], mlpca1, X)\n", "plot_2dim_pca(axes[1], mlpca2, X)\n", "plot_2dim_pca(axes[2], bpca, X)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It seems that there are no visible differences between these three results, in terms of the generated data." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.2 High dimensional data\n", "\n", "Next, to see the benefit of the Bayesian approach, we shall consider a higher dimensional data.\n", "\n", "More speicfically, we assume that the data is 10 dimensional, and obey a Gaussian distribution, which has large variance in three directions." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": true }, "outputs": [], "source": [ "N = 300\n", "D = 10\n", "var = np.array([1.0, 0.1, 1.0, 0.1, 0.1, 0.1, 0.1, 0.1, 1.0, 0.1])\n", "rnd = np.random.RandomState(0)\n", "X = rnd.multivariate_normal(np.zeros(D), cov=np.diag(var), size=N)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We compare the result by visualizing $\\| w_i \\|$, and see how many degrees of freedom is remaining or suppressed." ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def plot_magnitude_of_coefficients(ax, pcas, labels):\n", " for i in range(len(pcas)):\n", " Wsize = np.linalg.norm(pcas[i].W, axis = 0)**2\n", " ax.plot(np.sort(Wsize)[::-1], 'o-', label=labels[i])\n", " ax.set_yscale('log')\n", " ax.set_xlabel(r'$i$')\n", " ax.set_ylabel(r'$\\|w_i\\|^2$')\n", " ax.legend()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "scrolled": true }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\sokohaku\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:49: RuntimeWarning: overflow encountered in double_scalars\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "n_iter : 49\n", "converged : True\n" ] }, { "data": { "image/png": "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\nAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "m = 9\n", "mlpca = MLPCA(m=m)\n", "mlpca.fit(X, method='analytical')\n", "bpca = BPCA(m=m)\n", "bpca.fit(X, max_iter=1000, tol=1e-5, disp_message=True)\n", "\n", "ax = plt.subplot(111)\n", "plot_magnitude_of_coefficients(ax, [mlpca, bpca], ['ML', 'Bayes'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It can be clearly seen that the Bayesian approach suppresses redundant degrees of freedom." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4.3 Hand-written digits\n", "\n", "Next, we consider hand-written digits data of the digit three.\n" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The number of data points : 183\n", "The dimension of the observables : 64\n" ] } ], "source": [ "from sklearn import datasets\n", "digits = datasets.load_digits()\n", "\n", "threes = digits.data[np.where(digits.target==3)]/16.0 # extracting the data corresponding threes, and perform scaling\n", "print(f\"The number of data points : {len(threes)}\")\n", "print(f\"The dimension of the observables : {len(threes[0])}\")" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAArwAAAC0CAYAAAB2dv8HAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAD6VJREFUeJzt3VGInWedBvDn3cSC1dYEG0Ta0klE\nhV5NaxCkIEGn4K5icrEWBRemN8mNYtgFE/eql82NTi9WaanaggUJVYKIrKS0kd0bMakDS40uJY40\nau1UEyt6EdR3LzK7tNs057R5zznf9/r7gdDE4Zm/49OPp6cnM6XWGgAA6NXfLfoAAACYJYMXAICu\nGbwAAHTN4AUAoGsGLwAAXTN4AQDomsELAEDXDF4AALpm8AIA0LXtswi96aab6tLS0iyi35Dnn3++\nWdYvf/nLJjnXXXddk5zbb7+9Sc62bdua5LSysbGRF198sczzc7bq7aVLl679mCS/+c1vmuQkyW9/\n+9smOa16smPHjiY5b3/725vkJMn111/fJOfMmTMv1lp3NQmbUqvu/uUvf7n2Y9L2mfvSSy81yfnT\nn/7UJKfV3wN79uxpkpMkN9544zVnLOKZmwxvLzz33HPNsl544YUmOW9+85ub5LzjHe9oktPyudvC\ntN2dyeBdWlrK6dOnZxH9hhw7dqxZ1tGjR5vk3HzzzU1ynnzyySY5O3fubJLTyt69e+f+OVv1dmNj\n49qPSbK2ttYkJ0keeeSRJjmthuqBAwea5KyurjbJSZLl5eUmOaWUXzQJeh1adffChQsNrmn7zD15\n8mSTnKeffrpJzg033NAk58tf/nKTnCRZWVm55oxFPHOT4e2Fw4cPN8t64IEHmuS85z3vaZLT6n9b\ny+duC9N211saAADomsELAEDXDF4AALpm8AIA0LWpBm8p5SOllJ+VUp4tpbT5U1swB7rLGOktY6W7\nDNXEwVtK2Zbk35L8fZLbk3yqlNLme2HBDOkuY6S3jJXuMmTTvML7/iTP1lrP1VovJflmkv2zPQua\n0F3GSG8ZK91lsKYZvDcnefl3Yj6/9XuvUEo5WEo5XUo5vbm52eo+uBYTu6u3DJBnLmOluwzWNIP3\nSj+9or7qN2p9qNa6t9a6d9euuf6QIXgtE7urtwyQZy5jpbsM1jSD93ySW1/261uS/Go250BTussY\n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\nRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, axes = plt.subplots(1, 4, figsize=(12, 6))\n", "for (i, ax) in enumerate(axes):\n", " ax.imshow(threes[i].reshape((8,8)), cmap='gray_r') " ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "scrolled": false }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\sokohaku\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:49: RuntimeWarning: overflow encountered in double_scalars\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "n_iter : 3532\n", "converged : True\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZgAAAEMCAYAAAD5zKAAAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzt3X2Ym3Wd7/H3N5lME6i00FaOzFCn\nXttTYC3b4iwLInsBLk+ekSJ6sJWjLkWre2T1PAC2Kiqs2p7tPqjAIgVqZXWLpdZaodqyQIHdC6Qt\nRWgtlYogmQqdVgaETtt5+J4/kkwzmTszyST3JJl8XtfVq82P5M73Lmk+83u6b3N3REREyi1S6QJE\nRGRsUsCIiEgoFDAiIhIKBYyIiIRCASMiIqFQwIiISCgUMCIiEgoFjIiIhEIBIyIioWiodAGVNHny\nZG9paal0GSIiNWXr1q373H3KcM+r64BpaWlhy5YtlS5DRKSmmNmLhTxPQ2QiIhIKBYyIiIRizAyR\nmdnRwL8Ah4FN7v6DCpckIlLXqjpgzGw50Absdfd3ZrVfBHwLiAJ3uPsS4DJgtbv/1Mx+CChgRGTE\nuru7SSaTHDx4sNKlVEw8Hqe5uZlYLDai11d1wAArgJuBuzINZhYFbgHOB5LAZjNbBzQDz6Sf1ju6\nZYrIWJNMJnnLW95CS0sLZlbpckadu7N//36SySTTpk0b0TGqOmDc/REza8lpPh3Y7e7PA5jZ3cAc\nUmHTDDzFEHNLZrYAWAAwderUomtau62dpRt2saezixMmJrj2whlcOrup6OOISHU7ePBg3YYLgJkx\nadIkOjo6RnyMWpzkbwJeynqcTLetAT5oZrcCP833Yndf5u6t7t46Zcqwy7gHWLutnUVrnqG9swsH\n2ju7WLTmGdZuay/+LESk6tVruGSUev5V3YPJI+iM3d3fBK4M842XbtjF+b0Pc13jKk6wfezxyfx9\nz+V8dV1EvRoRkRy12INJAidmPW4G9ozGG7e+fj9LYnfQHNlHxKA5so8lsTv439238cMDn+Q34z7C\nDw98kv/48b+oVyMiJTMzPvrRj/Y/7unpYcqUKbS1tQGwYsUKrr766kqVN6xa7MFsBqab2TSgHZgL\nfGQ03nhR4z0cxeEBbUfZYT4a/Xci6X5Vs+3jRl/G3/0kwtIN56pXI1InwpifPfroo9m+fTtdXV0k\nEgnuv/9+mppq53ukqnswZrYSeAyYYWZJM7vK3XuAq4ENwE5glbvvGI16jmdfYHskZ9DuKDvMZ/r+\nbdBczZfWPsNZSx5k2sL7OGvJg+rliIwRYc7PXnzxxdx3330ArFy5knnz5pV8zNFS1T0Ydw/8m3T3\n9cD6US4Hm9AMr700/BOBE2wf/9H42QFzNa8/AT9sWMUJ4/ax58BkvvnjuWx5cS4PPduhno5IFbvh\npzv41Z7X8/73bb/r5HBv34C2ru5erlv9NCuf+F3ga0454Ri+8v4/Hfa9586dy4033khbWxtPP/00\n8+fP59FHHy3uBCqkqgOm6rz3y/DTz0J3V3+TE7zqwEjN0UBq2Gxp7DYMo9F6+ttu9GXcs+VZPh15\nSqEjUsNyw2W49mKceuqpvPDCC6xcuZL3ve99JR9vNClginHq5anfH7gRXkvChGZs+gX0bPsBDb1H\ndvs6kLu6b5wN3vuZb/5m4RN9tPe9BzjS1d7y4h8GhQ6g1Wsio2C4nsZZSx6kvbNrUHvTxAQ//NSZ\nJb//JZdcwjXXXMOmTZvYv39/yccbLQqYYp16+ZGgSWuYesaA0Cl0GA2C52++0nAX17FqyOG1f/zR\nh7nX30N3rwMKIpFKuvbCGSxa8wxd3Ud+kEzEov3//ko1f/58JkyYwMyZM9m0aVNZjjkazN0rXUPF\ntLa2eij3g/nndxYVMrncB/aADnl0wPAawAFv5J7ev+S9kacGBNG6dM8nIxYxMPqDKNM2Pt5A54Fu\nBY5IHjt37uTkk08u+PlhrCIbP348b7zxxoC2TZs28Q//8A/ce++9/cuUJ06c2P/fH3/8cZqbm0t6\n32xBfw9mttXdW4d7rQImjIB5etWguRoiMXodot7d35Rv/qZQfT6wB5QvdACua1iVN4gSsSgffFeT\n5n1EshQbMGOVAmaEQgsYSIVM9rDZe7+cas9uyzd/U8LbFtL7OeRR3iTBRN7I2/NR6Ei9U8CklBIw\nmoMJS8BcTX97ltz5Gzv8JnT9YcRvW8jignHWyzhS3e5mS12N4F29vx7U8/n+40dCZ6g5HoWOiARR\nwFRabhCN0vBatqPsMB+L/nt/OGVCh24G9Gy6unv5/uNH1vQXu7AgqE3hJDJ2aYgsrCGyUhQ4vMYv\n/21gEGGkoqc89veNp4v4kIsIguRbWJDblm8YDhROUnkaIkvRHMwIVW3AFCo3iIJCJxJLjZv1Hs5/\nnDxy53MKXblWjNxILDWcFDpSLgqYFAXMCNV8wAQZrveTOBYOv5ETOIX3fEYjdAoVFE65y69BvSEZ\nGQVMigJmhMZkwBSikJ5PEQpdLj0aoZNNQ3VSimoImGg0ysyZM3F3otEoN998M+9+97tHtQYFzAjV\nbcAEyQ2dElezBYXOF3s/yY97zupvK++MUXkpnKTogAkaPQhaSVqE7I2WGzZs4Bvf+AYPP/xwSccs\nlpYpS+kKWc1WRCQEXQLn629ZwxP+V/1fsOeeNIUfbW0fcHmNQr/Yww6n7r7BRw9qC1pZd809T2Fm\nAy7jc+09vxxwDrq0zxiT++/ltZdSj6HkkMl4/fXXOfbYYwF44403mDNnDq+++ird3d187WtfY86c\nOVx//fVMnjyZz33ucwB88Ytf5Pjjj+ezn/0sS5cuZdWqVRw6dIgPfOAD3HDDDbz55ptcfvnlJJNJ\nent7uf766/nwhz9clnpBPRj1YIZS0FBaMV/1Bl/tHNASdHkNGP6n/6BwGgtiESArnFJthc0tKYTK\na8BP7j9bCC8/k//Jyc3Qe2hwe3QcNP958Gv+y0y4eMmQNWSGyA4ePMjvf/97HnzwQd71rnfR09PD\ngQMHOOaYY9i3bx9nnHEGzz33HC+++CKXXXYZTz75JH19fUyfPp0nnniCrVu3snr1am677TbcnUsu\nuYTrrruOjo4Ofv7zn3P77bcD8NprrzFhwoT8fw9p6sFI6YI2i+Ze2LOY0Jkw+PpIl85uCvxiLKSt\n9e3H9X/JTkjEePNwz7A9n0r0horR3Qe51XT3Oa8eSO2BytdDUm+owoLCZaj2AiUSCZ566ikAHnvs\nMT72sY+xfft23J0vfOELPPLII0QiEdrb23nllVdoaWlh0qRJbNu2jVdeeYXZs2czadIkNm7cyMaN\nG5k9ezaQ6gE999xznH322VxzzTV8/vOfp62tjbPPPrukenMpYKQ4Iw2dWOLIirYyyQ2ncvaGqjmc\negJCKGiortRhuaC2ug2nYXoaeS9wO+FEuPK+spRw5plnsm/fPjo6Oli/fj0dHR1s3bqVWCxGS0sL\nBw+mLjn1iU98ghUrVvDyyy8zf/58ANydRYsW8alPfWrQcbdu3cr69etZtGgRF1xwAV/+cvn+nWqI\nTENk4Xh6Ffzk6tRPcBNOLMuEZ5jqJZyCaO9RsKIm+YPmLGMJeP+3S/rcZ0/yP/vss7znPe/hlVde\n4eabb2b37t3cdNNNPPTQQ5x33nn89re/paWlhcOHDzNz5ky6u7t57rnniEajbNy4keuvv54HHniA\n8ePH097eTiwWo6enh+OOO454PM7atWtZsWIFa9euHfbvQUNkUlmnXg5P3gXeB1eO+t2ti1auobow\nwilsxSxo+MHjv+sPRQ3NZQm4GWE5fqjq6upi1qxZQKoX8r3vfY9oNMoVV1zB+9//flpbW5k1axYn\nnXRS/2saGxs599xzmThxItFoFIALLriAnTt3cuaZqZufjR8/nu9///vs3r2ba6+9lkgkQiwW49Zb\nby2p3lzqwagHE54VbTUTMJUyXM+p0LmlaukNAUQNIhGr+d5PNeyDGYm+vj5OO+007rnnHqZPn17y\n8dSDEalRhfScChm+K7Q3NBpB1OvQ21vYHNENP92h1XFl9Ktf/Yq2tjY+8IEPlCVcSjWmAsbMTgY+\nB0wGHnD38vb3RCqg0OG7QobqqmnOKHd1XL5FCUHnKsFOOeUUnn/++UqX0a9qAsbMlgNtwF53f2dW\n+0XAt4AocIe7513O4e47gU+bWQS4PeSSpRB1PAQ72soZRIWGUzlDJ9+8z1fX7ahYr8bdsdybLNWR\nUqdQqiZggBXAzcBdmQYziwK3AOcDSWCzma0jFTaLc14/3933mtklwML0sUQkRzkXNIzG0FxnVzed\nXUd6OqPVq4nH4+zfv59JkybVZci4O/v37ycej4/4GFU1yW9mLcC9mR6MmZ0JfNXdL0w/XgTg7rnh\nEnSs+9z9vw31HE3yh2xFG/T1wvyfVboSCdFI54hKMTER4+hxDaH2arq7u0kmk/37S+pRPB6nubmZ\nWCw2oH2sTPI3Adm7l5LAX+R7spmdA1wGjAMCly6Z2QJgAcDUqVPLVadI3RrJ0Fyhq+PyGY1eTSwW\nY9q0aWU7Xj2q9oAJ6pfm/fS5+yZg01AHdPdlwDJI9WBKqE1EijCSKy8cONzTvxBgKF3dvSzdsEuL\nAapMtQdMEjgx63EzsKdCtYhIGRW6RHvRmmcKGlpr7+zirCUPaolzFYlUuoBhbAamm9k0M2sE5gLr\nKlyTiIySS2c3sfiymTRNTGBA08QExx4Vy/v89s4unCPDZmu3tY9arTJY1fRgzGwlcA4w2cySwFfc\n/U4zuxrYQGrl2HJ331HBMkVklAUNrRXSq9GwWeVVTcC4+7w87evJM2EvtUDTXFJemcDInqtp7wy+\n3feePO0yOqomYERECpXbqzlryYOBIXP8MSPfwyGlq/Y5GKlldbg5TSrj2gtnkIhFB7W/eaibMxY/\nwLSF93HWkgc1JzPK1IMRkZoXNGx2ytvewv079/LHQ6m5mqFuL6B5mnAoYERkTAgaNssVdFVnXVAz\nPAoYERmTCp3gr/QFNccyzcGIyJh0wsREwc/t7OrWHpoQKGBEZEwKmvgvdNlJpldz1pIHtUCgBAoY\nCVcVXa1b6kvQVQCuOGNq4GqzIOrVlE5zMCIyZgVd7yz3nja6oGZ4FDASIu2Dkeoz0kvPgK4MUCwF\njIjUtaA9NPl6NcUsHBAFjIhIQb2aiMHZ0yfrlgBFUMCIiOTI7dVMPCrGqwe6WbXlJfrS61a0SXN4\nChgRkQC5vZpZN26kM2fYTBP/Q9MyZRGRAryWZ6WZJv7zU8BIyLQPRsaGfBP8mvjPTwEjIlKAoCsD\nxKLGtRfOqFBF1U9zMBIe3Q9GxpDcif/GhgiHe/rY9fIftbIsDwWMiEiBsif+Xz/YzQX/9DC3Pvyb\n/v+ulWUDaYhMRGQEjonHAmcYMyvLRAEjIjJie18/FNiulWUpChgRkRHSyrKhjZmAMbOImX3dzG4y\ns49Xuh4RGfuuvXAG4xoGfo0mYlGtLEurioAxs+VmttfMtue0X2Rmu8xst5ktHOYwc4AmoBtIhlWr\niEjGpbObuL7tlP7HTRMTLL5spib406oiYIAVwEXZDWYWBW4BLgZOAeaZ2SlmNtPM7s359VZgBvCY\nu/8f4G9GuX7JRzcckzHustNSYbLw4pP4z4XnKVyyVMUyZXd/xMxacppPB3a7+/MAZnY3MMfdFwNt\nuccwsyRwOP0w740dzGwBsABg6tSpJdcuQ9E+GBn74g2pzZcHC7ifTL2plh5MkCbgpazHyXRbPmuA\nC83sJuCRfE9y92Xu3ururVOmTClPpSJStyIRY1xDpKAbltWbqujB5BH042/e8RZ3PwBcFV45IiLB\n4rEoBw8rYHJVcw8mCZyY9bgZ2FOhWkRE8krEohzs7qt0GVWnmgNmMzDdzKaZWSMwF1hX4ZpERAZJ\nNEY1RBagKgLGzFYCjwEzzCxpZle5ew9wNbAB2AmscvcdlaxTRCSI5mCCVcUcjLvPy9O+Hlg/yuWI\niBQl0RjVKrIAVdGDkbFM+2Bk7Is3KGCCKGAkPLofjNQJzcEEU8CIiJRIq8iCKWBEREo0LhahS/tg\nBlHAiIiUKNWDUcDkUsCIiJRIARNMASMiUqJ4LDXJ77p6+AAKGBGREiUao/Q5dPcqYLIpYCRc+olO\n6kA8lrpkv5YqD6SAEREpUTyW+irVPMxAChgJkTZaSn1IxHTTsSAKGBGREmmILJgCRkSkRJkejDZb\nDqSAEREpUbx/iEyXi8mmgBERKZEm+YMpYERESpRo1BxMEAWMiEiJtIosmAJGQqaNljL2aRVZMAWM\nhEc3HJM6EdcqskAKGBGREmWGyA71aBVZNgWMiEiJYlEjYurB5BozAWNmp5jZKjO71cw+VOl6RKR+\nmJnuCROgKgLGzJab2V4z257TfpGZ7TKz3Wa2cJjDXAzc5O5/A3wstGJFRAJk7gkjRwwbMGZ2vpnd\nbmaz0o8XhFDHCuCinPeNAreQCo5TgHnpXspMM7s359dbgX8F5prZUmBSCDWKiOSlgBmsoYDn/E/g\nSuBLZnYcMKvcRbj7I2bWktN8OrDb3Z8HMLO7gTnuvhhoy3Ooz6SDaU25axQRGUqiMcohXSpmgEKG\nyDrcvdPdrwEuAP485JoymoCXsh4n022BzKzFzJYBdwFLh3jeAjPbYmZbOjo6ylas5KEbjkmdiMci\n6sHkKKQHc1/mD+6+0Mz+NsR6sgVtosj7beXuLwDDDt+5+zJgGUBra6u+/UKlfTBSPxKxqFaR5Ri2\nB+PuP8l5fFN45QyQBE7MetwM7Bml9xYRKUo8FuVgjwImWyE9GMxsaoHH63T310uoJ9tmYLqZTQPa\ngbnAR8p0bBGRsorHonT88VCly6gqBQUM8D1Sw1NDjXk4qdVgdxVbhJmtBM4BJptZEviKu99pZlcD\nG4AosNzddxR7bBGR0aB9MIMVFDDufm6YRbj7vDzt64H1Yb63iEg5pAJGq8iyFdqDGcTMbiTVs3gK\neMrdnytbVSIiNUaryAYraie/mcUzf3b3LwPfBv4IfNDMbi9zbSIiNSPeqI2WuYrtwWw2s43Are6+\n291fAX6e/iUSQCvBpT7EG6Ic7umjr8+JRLREH4q/FtmfAZuAfzaz+8yszUw3/ZA89NGQOpK5bbKW\nKh9RbMBMAHYANwA/Av4e+G25ixIRqTVHbpusif6MYofI9gOPAf9Jau5lGVCufS8iIjUrHkv9vK55\nmCOK7cG0Ar8GZgK/Ar7t7svLXpWISI3RbZMHKypg3P1Jd78SuAL4E+ARM/tCKJWJiNSQI0NkCpiM\noobIzGwTMB44itSu/j7gQ8A3yl6ZiEgNiStgBil2DuavgU7gNXddh11EJCOzikxzMEcUe7HLPuAY\n4Jg8q5PLebFLGQv0c4jUCa0iG6wqLnYpIlLrtIpssKq42KWMVdpoKfWjfw5Gq8j6FbtMWUREAvQH\njHby91PAiIiUQUL7YAZRwIiIlEH/RkvNwfRTwIiIlEE0YjRGI1pFlkUBIyJSJvFYRBstsyhgRETK\nJNEYVcBkUcBIyLTRUupHPKa7WmZTwEh4dMMxqTOJWFSryLIoYEREymRcLMrBHk3yZ9RswJjZO8zs\nTjNbndV2qZndbmY/MbMLKlmfiNSfRCyinfxZKhIwZrbczPaa2fac9ovMbJeZ7TazhUMdw92fd/er\nctrWuvsnSV31+cNlL1xEZAgJzcEMUOzl+stlBXAzWRfGNLMocAtwPpAENpvZOiAKLM55/Xx33zvE\n8b+UPpaIyKiJx7SKLFtFAsbdHzGzlpzm04Hd7v48gJndDcxx98VAWyHHtdQ9BJYAP3P3J/M8ZwGw\nAGDq1KlBTxERGRH1YAaqpjmYJuClrMfJdFsgM5tkZt8BZpvZonTz3wJ/BXzIzD4d9Dp3X+bure7e\nOmXKlDKVLiICce2DGaBSQ2RBgta05t1E4e77gU/ntH0b+HaZ65JS6IZjUkfiDVFdKiZLNfVgksCJ\nWY+bgT0VqkXKQvtgpL4kGiN0dfeiO8qnVFPAbAamm9k0M2sE5gLrKlyTiEjBErEovX1Od68CBiq3\nTHkl8Bgww8ySZnaVu/cAVwMbgJ3AKnffUYn6RERGQjcdG6hSq8jm5WlfD6wf5XJERMoi+7bJx8Rj\nFa6m8qppiExEpKb1B4wm+gEFjIhI2SR0V8sBFDAiImWSaEx9pSpgUhQwEjKtppH6EW/IDJEpYEAB\nI2HS/WCkzsQbNUSWTQEjIlImiaxVZKKAEREpG+2DGUgBIyJSJv2ryA5rmTIoYEREykbLlAdSwIiI\nlMm4WOorVavIUhQwIiJlMq4hgpkCJkMBI+HSNhipI2ZGvCFKl1aRAQoYEZGySjRGtYosTQEjIdJG\nS6k/iVhUq8jSFDAiImU0LhZRDyZNASMiUkaJWFQ7+dMUMCIiZZSIRbUPJk0BIyJSRvFYVMuU0xQw\nIiJlFI9F6dIdLQEFjIhIWSUa1YPJUMBIyLTTUupLvCGigEmr2YAxs3eY2Z1mtjqr7Rwze9TMvmNm\n51SwPAHdcEzqUqJRk/wZFQkYM1tuZnvNbHtO+0VmtsvMdpvZwqGO4e7Pu/tVuc3AG0AcSJa3ahGR\n4cVjulRMRkOF3ncFcDNwV6bBzKLALcD5pMJhs5mtA6LA4pzXz3f3vQHHfdTdHzaz44F/Aq4IoXYR\nkbzisSiHevro63MikfruxVckYNz9ETNryWk+Hdjt7s8DmNndwBx3Xwy0FXjczNKNV4Fx5alWRKRw\nmXvCHOrpI9EYrXA1lVVNczBNwEtZj5PptkBmNsnMvgPMNrNF6bbLzOw24F9J9ZCCXrfAzLaY2ZaO\njo7yVS8iAsTT94TRPEzlhsiCBPUl8y5Bcvf9wKdz2tYAa4Z6E3dfBiwDaG1t1RInESmrTA9GK8mq\nqweTBE7MetwM7KlQLSIiI5IZFlMPproCZjMw3cymmVkjMBdYV+GapFSuTqLUl3EN6sFkVGqZ8krg\nMWCGmSXN7Cp37wGuBjYAO4FV7r6jEvWJiIxUpgejgKncKrJ5edrXA+tHuRwRkbLJzMHopmPVNUQm\nIlLzMqvI1INRwIiIlFV/D0YBo4ARESmnuAKmnwJGRKSMMgFzSAGjgBERKSftgzlCASMh0z4YqS/x\nhvSlYrSKTAEjIdL9YKQONUQjxKLGwR71YBQwIiJlpnvCpChgRETKLB6Lah8MChgRkbJLKGAABYyI\nSNklYlGtIkMBIyJSdvFYhIPdWkWmgBERKbO4ejCAAkbCpvvBSB3SJH+KAkZEpMw0yZ+igJEQaaOl\n1KdEo4bIQAEjIlJ28VhEl4pBASMiUnbxWFRXU0YBIyJSdtoHk6KAEREps3gsSk+f091b38NkChgR\nkTLL3Da53leS1WzAmNk7zOxOM1ud1TbVzNaZ2XIzW1jJ+kSkfsV10zEAGirxpma2HGgD9rr7O7Pa\nLwK+BUSBO9x9Sb5juPvzwFXZAQP8V+A+d7/NzO4Kp3opjjZaSn1Zu62df9y4C4D33/QfLLr4ZACW\nbtjFns4uTpiY4NoLZxTcdunspsqcSBmYV2CntZn9JfAGcFcmYMwsCvwaOB9IApuBeaTCZnHOIea7\n+97061a7+4fSf54ErCb1rfav7v7doepobW31LVu2lO28JMeqj0HHLvjMLypdicioWLutnUVrnhnQ\nc2mIgJnR3XvkuzYWMTCGbUvEonzwXU089GxHVYWOmW1199bhnleRHoy7P2JmLTnNpwO70z0TzOxu\nYI67LybV2ynElcBX0sdfDQwZMCIi5bR0w65Bw2I9fZDbk+/uG/yDfVBbV3cvP3j8d/2vbu/sYtGa\nZ9jy4h+qLnSCVNMcTBPwUtbjZLotkJlNMrPvALPNbFG6+efAZ9PtL+R53QIz22JmWzo6OspTuYgI\nsKezq+zHzI2dTOi0d3bhHAmdtdvay/7epapIDyaPoOuK5B2/c/f9wKdz2rYDHxrqTdx9GbAMUkNk\nxZcpIhLshIkJ2kMImVxBofPVdTuqbv6mmgImCZyY9bgZ2FOhWkREinbthTMGzcEUOt8S1GYUvkym\ns6ubzq5uoHqG0qopYDYD081sGtAOzAU+UtmSREQKl/nyHumKsdy2c0+awo+2tg8IrEJDJ9/8TXad\nYavUMuWVwDnAZDNLkpqYv9PMrgY2kFo5ttzdd1SiPhGRkbp0dlPgF/hI21rfftywoZNP0FDa0g27\nxnbAuPu8PO3rgfWjXI6ESTccEylJUGDlhs6Bwz28eqC7oOOFsRAhn2oaIpMxR/eDEQlDbugE7b/J\nN5R2wsRE+AWmVdMyZRERGYFLZzex+LKZNE1MYEDTxARXnDG1/5poGbGo9c/1jAb1YERExoDhhtLG\nNUQ43NvHn7x1/KjVpIARERmjskPn1TcP875vP8pff/cJYtEIL792MPSlyxoiExGpA8ce3cgHT2ti\n3xuH+f1rB0flKgAKGBGROvHjbYP3rmeWLodBASMiUifyLVEOa+myAkZCpn0wItUi3xLlsJYuK2Ak\nPKZ9MCLV5NoLZwxaupyIRUNbuqxVZCIidSLftdLCWkWmgBERqSP5rpUWBg2RiYhIKBQwIiISCgWM\niIiEQgEjIiKhUMBIuHQ/GJG6ZV7HXwBm1gG8OMKXTwb2lbGcShgL5wBj4zx0DtVB51CYt7v7lOGe\nVNcBUwoz2+LurZWuoxRj4RxgbJyHzqE66BzKS0NkIiISCgWMiIiEQgEzcssqXUAZjIVzgLFxHjqH\n6qBzKCPNwYiISCjUgxERkVAoYEbAzC4ys11mttvMFla6nkKY2XIz22tm27PajjOz+83sufTvx1ay\nxuGY2Ylm9pCZ7TSzHWb2uXR7zZyHmcXN7Akz+2X6HG5It08zs1+kz+GHZtZY6VqHY2ZRM9tmZvem\nH9fUOZjZC2b2jJk9ZWZb0m0181kCMLOJZrbazJ5N/7s4s5rOQQFTJDOLArcAFwOnAPPM7JTKVlWQ\nFcBFOW0LgQfcfTrwQPpxNesB/q+7nwycAXwm/XdfS+dxCDjP3f8MmAVcZGZnAP8P+Of0ObwKXFXB\nGgv1OWBn1uNaPIdz3X1W1rLeWvosAXwL+Lm7nwT8Gan/H9VzDu6uX0X8As4ENmQ9XgQsqnRdBdbe\nAmzPerwLeFv6z28DdlW6xiJQd7oKAAADIklEQVTP5yfA+bV6HsBRwJPAX5DaGNeQbh/wGavGX0Az\nqS+v84B7AavBc3gBmJzTVjOfJeAY4Lek59Kr8RzUgyleE/BS1uNkuq0WHe/uvwdI//7WCtdTMDNr\nAWYDv6DGziM9tPQUsBe4H/gN0OnuPemn1MJn6pvAdUBf+vEkau8cHNhoZlvNbEG6rZY+S+8AOoDv\npocq7zCzo6mic1DAFC/oPsBaijeKzGw88CPgf7n765Wup1ju3uvus0j1Ak4HTg562uhWVTgzawP2\nuvvW7OaAp1btOaSd5e6nkRru/oyZ/WWlCypSA3AacKu7zwbepMqG9BQwxUsCJ2Y9bgb2VKiWUr1i\nZm8DSP++t8L1DMvMYqTC5QfuvibdXHPnAeDuncAmUvNJE80sc4fZav9MnQVcYmYvAHeTGib7JrV1\nDrj7nvTve4Efkwr7WvosJYGku/8i/Xg1qcCpmnNQwBRvMzA9vWKmEZgLrKtwTSO1Dvh4+s8fJzWn\nUbXMzIA7gZ3u/k9Z/6lmzsPMppjZxPSfE8BfkZqYfQj4UPppVX0O7r7I3ZvdvYXU5/9Bd7+CGjoH\nMzvazN6S+TNwAbCdGvosufvLwEtmNiPd9F7gV1TROWij5QiY2ftI/cQWBZa7+9crXNKwzGwlcA6p\nK62+AnwFWAusAqYCvwP+u7v/oVI1DsfM3gM8CjzDkbH/L5Cah6mJ8zCzU4HvkfrsRIBV7n6jmb2D\nVG/gOGAb8D/c/VDlKi2MmZ0DXOPubbV0Dulaf5x+2AD8m7t/3cwmUSOfJQAzmwXcATQCzwNXkv5c\nUQXnoIAREZFQaIhMRERCoYAREZFQKGBERCQUChgREQmFAkZEREKhgBERkVAoYEREJBQKGJEqZGbv\nztwrRqRWaaOliIiEQj0YkSpkZvekL40jUrMUMCLV6Z2krrkmUrMUMCJVxsziQMzdX6t0LSKlUMCI\nVJ8/JXXZdZGapoARqT4zgacrXYRIqRQwItVHASNjgpYpi4hIKNSDERGRUChgREQkFAoYEREJhQJG\nRERCoYAREZFQKGBERCQUChgREQmFAkZERELx/wGhlA1Y7JMJ+wAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "m = 63\n", "max_iter = 10000\n", "\n", "mlpca = MLPCA(m=m)\n", "mlpca.fit(threes)\n", "\n", "bpca = BPCA(m=m)\n", "bpca.fit(threes, disp_message=True, max_iter=max_iter, tol=1e-4)\n", "\n", "ax = plt.subplot(111)\n", "plot_magnitude_of_coefficients(ax, [mlpca, bpca], ['ML', 'Bayes'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Again, we can see that the Bayesian approach suppresses redundant degrees of freedom." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.6" } }, "nbformat": 4, "nbformat_minor": 2 }