Exemplo n.º 1
0
    def initialise(self, init='exp', tauUV={}):
        self.tauU = tauUV['tauU'] if 'tauU' in tauUV else numpy.ones(
            (self.I, self.K))
        self.tauV = tauUV['tauV'] if 'tauV' in tauUV else numpy.ones(
            (self.J, self.K))

        assert init in ['exp', 'random'
                        ], "Unrecognised init option for F,G: %s." % init
        self.muU, self.muV = 1. / self.lambdaU, 1. / self.lambdaV
        if init == 'random':
            for i, k in itertools.product(xrange(0, self.I), xrange(0,
                                                                    self.K)):
                self.muU[i, k] = exponential_draw(self.lambdaU[i, k])
            for j, k in itertools.product(xrange(0, self.J), xrange(0,
                                                                    self.K)):
                self.muV[j, k] = exponential_draw(self.lambdaV[j, k])

        # Initialise the expectations and variances
        self.expU, self.varU = numpy.zeros((self.I, self.K)), numpy.zeros(
            (self.I, self.K))
        self.expV, self.varV = numpy.zeros((self.J, self.K)), numpy.zeros(
            (self.J, self.K))

        for k in xrange(0, self.K):
            self.update_exp_U(k)
        for k in xrange(0, self.K):
            self.update_exp_V(k)

        # Update tau using the updates
        self.update_tau()
        #self.alpha_s, self.beta_s = self.alpha, self.beta
        self.update_exp_tau()
Exemplo n.º 2
0
    def initialise(self,init_S='random',init_FG='random'):
        assert init_S in ['random','exp'], "Unknown initialisation option for S: %s. Should be 'random' or 'exp'." % init_S
        assert init_FG in ['random','exp','kmeans'], "Unknown initialisation option for S: %s. Should be 'random', 'exp', or 'kmeans." % init_FG
        
        self.S = 1./self.lambdaS
        if init_S == 'random':
            for k,l in itertools.product(xrange(0,self.K),xrange(0,self.L)):  
                self.S[k,l] = exponential_draw(self.lambdaS[k,l])
                
        self.F, self.G = 1./self.lambdaF, 1./self.lambdaG
        if init_FG == 'random':
            for i,k in itertools.product(xrange(0,self.I),xrange(0,self.K)):        
                self.F[i,k] = exponential_draw(self.lambdaF[i,k])
            for j,l in itertools.product(xrange(0,self.J),xrange(0,self.L)):
                self.G[j,l] = exponential_draw(self.lambdaG[j,l])
        elif init_FG == 'kmeans':
            print "Initialising F using KMeans."
            kmeans_F = KMeans(self.R,self.M,self.K)
            kmeans_F.initialise()
            kmeans_F.cluster()
            self.F = kmeans_F.clustering_results + 0.2            
            
            print "Initialising G using KMeans."
            kmeans_G = KMeans(self.R.T,self.M.T,self.L)   
            kmeans_G.initialise()
            kmeans_G.cluster()
            self.G = kmeans_G.clustering_results + 0.2

        self.tau = gamma_mode(self.alpha_s(), self.beta_s())
Exemplo n.º 3
0
    def initialise(self,init_S='random',init_FG='random'):
        assert init_S in ['random','exp'], "Unknown initialisation option for S: %s. Should be 'random' or 'exp'." % init_S
        assert init_FG in ['random','exp','kmeans'], "Unknown initialisation option for S: %s. Should be 'random', 'exp', or 'kmeans." % init_FG
        
        self.S = 1./self.lambdaS
        if init_S == 'random':
            for k,l in itertools.product(xrange(0,self.K),xrange(0,self.L)):  
                self.S[k,l] = exponential_draw(self.lambdaS[k,l])
                
        self.F, self.G = 1./self.lambdaF, 1./self.lambdaG
        if init_FG == 'random':
            for i,k in itertools.product(xrange(0,self.I),xrange(0,self.K)):        
                self.F[i,k] = exponential_draw(self.lambdaF[i,k])
            for j,l in itertools.product(xrange(0,self.J),xrange(0,self.L)):
                self.G[j,l] = exponential_draw(self.lambdaG[j,l])
        elif init_FG == 'kmeans':
            print "Initialising F using KMeans."
            kmeans_F = KMeans(self.R,self.M,self.K)
            kmeans_F.initialise()
            kmeans_F.cluster()
            self.F = kmeans_F.clustering_results + 0.2            
            
            print "Initialising G using KMeans."
            kmeans_G = KMeans(self.R.T,self.M.T,self.L)   
            kmeans_G.initialise()
            kmeans_G.cluster()
            self.G = kmeans_G.clustering_results + 0.2

        self.tau = self.alpha_s() / self.beta_s()
Exemplo n.º 4
0
    def initialise(self, init_UV='random'):
        ''' Initialise U, V, tau, and lambda (if ARD). '''
        assert init_UV in OPTIONS_INIT_UV, "Unknown initialisation option: %s. Should be in %s." % (
            init_UV, OPTIONS_INIT_UV)

        self.U = numpy.zeros((self.I, self.K))
        self.V = numpy.zeros((self.J, self.K))
        self.lambdak = numpy.zeros(self.K)

        # Initialise lambdak
        if self.ARD:
            for k in range(self.K):
                self.lambdak[k] = self.alpha0 / self.beta0

        # Initialise U, V
        for i, k in itertools.product(range(self.I), range(self.K)):
            hyperparam = self.lambdak[k] if self.ARD else self.lambdaU[i, k]
            self.U[i, k] = exponential_draw(
                hyperparam) if init_UV == 'random' else 1.0 / hyperparam
        for j, k in itertools.product(range(self.J), range(self.K)):
            hyperparam = self.lambdak[k] if self.ARD else self.lambdaV[j, k]
            self.V[j, k] = exponential_draw(
                hyperparam) if init_UV == 'random' else 1.0 / hyperparam

        # Initialise tau
        self.tau = gamma_draw(self.alpha_s(), self.beta_s())
Exemplo n.º 5
0
    def initialise(self, init_S='random', init_FG='random', tauFSG={}):
        self.tauF = tauFSG['tauF'] if 'tauF' in tauFSG else numpy.ones(
            (self.I, self.K))
        self.tauS = tauFSG['tauS'] if 'tauS' in tauFSG else numpy.ones(
            (self.K, self.L))
        self.tauG = tauFSG['tauG'] if 'tauG' in tauFSG else numpy.ones(
            (self.J, self.L))

        assert init_S in ['exp', 'random'
                          ], "Unrecognised init option for S: %s." % init_S
        self.muS = 1. / self.lambdaS
        if init_S == 'random':
            for k, l in itertools.product(xrange(0, self.K), xrange(0,
                                                                    self.L)):
                self.muS[k, l] = exponential_draw(self.lambdaS[k, l])

        assert init_FG in ['exp', 'random', 'kmeans'
                           ], "Unrecognised init option for F,G: %s." % init_FG
        self.muF, self.muG = 1. / self.lambdaF, 1. / self.lambdaG
        if init_FG == 'random':
            for i, k in itertools.product(xrange(0, self.I), xrange(0,
                                                                    self.K)):
                self.muF[i, k] = exponential_draw(self.lambdaF[i, k])
            for j, l in itertools.product(xrange(0, self.J), xrange(0,
                                                                    self.L)):
                self.muG[j, l] = exponential_draw(self.lambdaG[j, l])
        elif init_FG == 'kmeans':
            print "Initialising F using KMeans."
            kmeans_F = KMeans(self.R, self.M, self.K)
            kmeans_F.initialise()
            kmeans_F.cluster()
            self.muF = kmeans_F.clustering_results  #+ 0.2

            print "Initialising G using KMeans."
            kmeans_G = KMeans(self.R.T, self.M.T, self.L)
            kmeans_G.initialise()
            kmeans_G.cluster()
            self.muG = kmeans_G.clustering_results  #+ 0.2

        # Initialise the expectations and variances
        self.expF, self.varF = numpy.zeros((self.I, self.K)), numpy.zeros(
            (self.I, self.K))
        self.expS, self.varS = numpy.zeros((self.K, self.L)), numpy.zeros(
            (self.K, self.L))
        self.expG, self.varG = numpy.zeros((self.J, self.L)), numpy.zeros(
            (self.J, self.L))

        for k in range(0, self.K):
            self.update_exp_F(k)
        for k, l in itertools.product(xrange(0, self.K), xrange(0, self.L)):
            self.update_exp_S(k, l)
        for l in range(0, self.L):
            self.update_exp_G(l)

        # Initialise tau using the updates
        self.update_tau()
        #self.alpha_s, self.beta_s = self.alpha, self.beta
        self.update_exp_tau()
Exemplo n.º 6
0
    def initialise(self, init_FG='random', init_S='random'):
        ''' Initialise F, S, G, tau, and lambdaFk, lambdaGl (if ARD). '''
        assert init_FG in OPTIONS_INIT_FG, "Unknown initialisation option for F and G: %s. Should be in %s." % (
            init_FG, OPTIONS_INIT_FG)
        assert init_S in OPTIONS_INIT_S, "Unknown initialisation option for S: %s. Should be in %s." % (
            init_S, OPTIONS_INIT_S)

        self.F = numpy.zeros((self.I, self.K))
        self.S = numpy.zeros((self.K, self.L))
        self.G = numpy.zeros((self.J, self.L))
        self.lambdaFk = numpy.zeros(self.K)
        self.lambdaGl = numpy.zeros(self.L)

        # Initialise lambdaFk, lambdaGl
        if self.ARD:
            for k in range(self.K):
                self.lambdaFk[k] = self.alpha0 / self.beta0
            for l in range(self.L):
                self.lambdaGl[l] = self.alpha0 / self.beta0

        # Initialise F, G
        if init_FG == 'kmeans':
            print "Initialising F using KMeans."
            kmeans_F = KMeans(self.R, self.M, self.K)
            kmeans_F.initialise()
            kmeans_F.cluster()
            self.F = kmeans_F.clustering_results + 0.2

            print "Initialising G using KMeans."
            kmeans_G = KMeans(self.R.T, self.M.T, self.L)
            kmeans_G.initialise()
            kmeans_G.cluster()
            self.G = kmeans_G.clustering_results + 0.2
        else:
            # 'random' or 'exp'
            for i, k in itertools.product(range(self.I), range(self.K)):
                hyperparam = self.lambdaFk[k] if self.ARD else self.lambdaF[i,
                                                                            k]
                self.F[i, k] = exponential_draw(
                    hyperparam) if init_FG == 'random' else 1.0 / hyperparam
            for j, l in itertools.product(range(self.J), range(self.L)):
                hyperparam = self.lambdaGl[l] if self.ARD else self.lambdaG[j,
                                                                            l]
                self.G[j, l] = exponential_draw(
                    hyperparam) if init_FG == 'random' else 1.0 / hyperparam

        # Initialise S
        for k, l in itertools.product(range(self.K), range(self.L)):
            hyperparam = self.lambdaS[k, l]
            self.S[k, l] = exponential_draw(
                hyperparam) if init_S == 'random' else 1.0 / hyperparam

        # Initialise tau
        self.tau = gamma_draw(self.alpha_s(), self.beta_s())
Exemplo n.º 7
0
 def initialise(self,init_UV='random',expo_prior=1.):
     assert init_UV in ['ones','random','exponential'], "Unrecognised init option for U,V: %s." % init_UV
     if init_UV == 'ones':
         self.U = numpy.ones((self.I,self.K))
         self.V = numpy.ones((self.J,self.K))
     elif init_UV == 'random':
         self.U = numpy.random.rand(self.I,self.K)
         self.V = numpy.random.rand(self.J,self.K)
     elif init_UV == 'exponential':
         self.U = numpy.empty((self.I,self.K))
         self.V = numpy.empty((self.J,self.K))
         for i,k in itertools.product(xrange(0,self.I),xrange(0,self.K)):        
             self.U[i,k] = exponential_draw(expo_prior)
         for j,k in itertools.product(xrange(0,self.J),xrange(0,self.K)):
             self.V[j,k] = exponential_draw(expo_prior)
Exemplo n.º 8
0
 def initialise(self,init_S='random',init_FG='random',tauFSG={}):
     self.tauF = tauFSG['tauF'] if 'tauF' in tauFSG else numpy.ones((self.I,self.K))
     self.tauS = tauFSG['tauS'] if 'tauS' in tauFSG else numpy.ones((self.K,self.L))
     self.tauG = tauFSG['tauG'] if 'tauG' in tauFSG else numpy.ones((self.J,self.L))
     
     assert init_S in ['exp','random'], "Unrecognised init option for S: %s." % init_S
     self.muS = 1./self.lambdaS
     if init_S == 'random':
         for k,l in itertools.product(xrange(0,self.K),xrange(0,self.L)):  
             self.muS[k,l] = exponential_draw(self.lambdaS[k,l])
     
     assert init_FG in ['exp','random','kmeans'], "Unrecognised init option for F,G: %s." % init_FG
     self.muF, self.muG = 1./self.lambdaF, 1./self.lambdaG
     if init_FG == 'random':
         for i,k in itertools.product(xrange(0,self.I),xrange(0,self.K)):        
             self.muF[i,k] = exponential_draw(self.lambdaF[i,k])
         for j,l in itertools.product(xrange(0,self.J),xrange(0,self.L)):
             self.muG[j,l] = exponential_draw(self.lambdaG[j,l])
     elif init_FG == 'kmeans':
         print "Initialising F using KMeans."
         kmeans_F = KMeans(self.R,self.M,self.K)
         kmeans_F.initialise()
         kmeans_F.cluster()
         self.muF = kmeans_F.clustering_results #+ 0.2            
         
         print "Initialising G using KMeans."
         kmeans_G = KMeans(self.R.T,self.M.T,self.L)   
         kmeans_G.initialise()
         kmeans_G.cluster()
         self.muG = kmeans_G.clustering_results #+ 0.2
     
     # Initialise the expectations and variances
     self.expF, self.varF = numpy.zeros((self.I,self.K)), numpy.zeros((self.I,self.K))
     self.expS, self.varS = numpy.zeros((self.K,self.L)), numpy.zeros((self.K,self.L))
     self.expG, self.varG = numpy.zeros((self.J,self.L)), numpy.zeros((self.J,self.L))
     
     for k in range(0,self.K):
         self.update_exp_F(k)
     for k,l in itertools.product(xrange(0,self.K),xrange(0,self.L)):
         self.update_exp_S(k,l)
     for l in range(0,self.L):
         self.update_exp_G(l)
         
     # Initialise tau using the updates
     self.update_tau()
     #self.alpha_s, self.beta_s = self.alpha, self.beta
     self.update_exp_tau()
Exemplo n.º 9
0
 def initialise(self,init_UV='random',expo_prior=1.):
     ''' Initialise U and V. '''
     assert init_UV in OPTIONS_INIT_UV, "Unrecognised init option for U,V: %s. Should be one in %s." % (init_UV, OPTIONS_INIT_UV)
     
     if init_UV == 'ones':
         self.U = numpy.ones((self.I,self.K))
         self.V = numpy.ones((self.J,self.K))
     elif init_UV == 'random':
         self.U = numpy.random.rand(self.I,self.K)
         self.V = numpy.random.rand(self.J,self.K)
     elif init_UV == 'exponential':
         self.U = numpy.empty((self.I,self.K))
         self.V = numpy.empty((self.J,self.K))
         for i,k in itertools.product(xrange(0,self.I),xrange(0,self.K)):        
             self.U[i,k] = exponential_draw(expo_prior)
         for j,k in itertools.product(xrange(0,self.J),xrange(0,self.K)):
             self.V[j,k] = exponential_draw(expo_prior)
Exemplo n.º 10
0
 def initialise(self,init='random'):
     assert init in ['random','exp'], "Unknown initialisation option: %s. Should be 'random' or 'exp'." % init
     self.U = numpy.zeros((self.I,self.K))
     self.V = numpy.zeros((self.J,self.K))
     
     if init == 'random':
         for i,k in itertools.product(xrange(0,self.I),xrange(0,self.K)):
             self.U[i,k] = exponential_draw(self.lambdaU[i][k])
         for j,k in itertools.product(xrange(0,self.J),xrange(0,self.K)):
             self.V[j,k] = exponential_draw(self.lambdaV[j][k])
         
     elif init == 'exp':
         for i,k in itertools.product(xrange(0,self.I),xrange(0,self.K)):
             self.U[i,k] = 1.0/self.lambdaU[i][k]
         for j,k in itertools.product(xrange(0,self.J),xrange(0,self.K)):
             self.V[j,k] = 1.0/self.lambdaV[j][k]
     
     self.tau = gamma_mode(self.alpha_s(), self.beta_s())
Exemplo n.º 11
0
 def initialise(self, init_UV='random', expo_prior=1.):
     assert init_UV in ['ones', 'random', 'exponential'
                        ], "Unrecognised init option for U,V: %s." % init_UV
     if init_UV == 'ones':
         self.U = numpy.ones((self.I, self.K))
         self.V = numpy.ones((self.J, self.K))
     elif init_UV == 'random':
         self.U = numpy.random.rand(self.I, self.K)
         self.V = numpy.random.rand(self.J, self.K)
     elif init_UV == 'exponential':
         self.U = numpy.empty((self.I, self.K))
         self.V = numpy.empty((self.J, self.K))
         for i, k in itertools.product(xrange(0, self.I), xrange(0,
                                                                 self.K)):
             self.U[i, k] = exponential_draw(expo_prior)
         for j, k in itertools.product(xrange(0, self.J), xrange(0,
                                                                 self.K)):
             self.V[j, k] = exponential_draw(expo_prior)
Exemplo n.º 12
0
    def initialise(self, init_FG='random', init_S='random', expo_prior=1.):
        ''' Initialise F, S and G. '''
        assert init_FG in OPTIONS_INIT_FG, "Unrecognised init option for F,G: %s. Should be one in %s." % (
            init_FG, OPTIONS_INIT_FG)
        assert init_S in OPTIONS_INIT_S, "Unrecognised init option for S: %s. Should be one in %s." % (
            init_S, OPTIONS_INIT_S)

        if init_S == 'ones':
            self.S = numpy.ones((self.K, self.L))
        elif init_S == 'random':
            self.S = numpy.random.rand(self.K, self.L)
        elif init_S == 'exponential':
            self.S = numpy.empty((self.K, self.L))
            for k, l in itertools.product(xrange(0, self.K), xrange(0,
                                                                    self.L)):
                self.S[k, l] = exponential_draw(expo_prior)

        if init_FG == 'ones':
            self.F = numpy.ones((self.I, self.K))
            self.G = numpy.ones((self.J, self.L))
        elif init_FG == 'random':
            self.F = numpy.random.rand(self.I, self.K)
            self.G = numpy.random.rand(self.J, self.L)
        elif init_FG == 'exponential':
            self.F = numpy.empty((self.I, self.K))
            self.G = numpy.empty((self.J, self.L))
            for i, k in itertools.product(xrange(0, self.I), xrange(0,
                                                                    self.K)):
                self.F[i, k] = exponential_draw(expo_prior)
            for j, l in itertools.product(xrange(0, self.J), xrange(0,
                                                                    self.L)):
                self.G[j, l] = exponential_draw(expo_prior)
        elif init_FG == 'kmeans':
            print "Initialising F using KMeans."
            kmeans_F = KMeans(self.R, self.M, self.K)
            kmeans_F.initialise()
            kmeans_F.cluster()
            self.F = kmeans_F.clustering_results + 0.2

            print "Initialising G using KMeans."
            kmeans_G = KMeans(self.R.T, self.M.T, self.L)
            kmeans_G.initialise()
            kmeans_G.cluster()
            self.G = kmeans_G.clustering_results + 0.2
Exemplo n.º 13
0
    def initialise(self,init_UV='exp'):
        ''' Initialise U, V, tau, and lambda (if ARD). '''
        assert init_UV in OPTIONS_INIT_UV, "Unknown initialisation option: %s. Should be in %s." % (init_UV, OPTIONS_INIT_UV)
        
        # Initialise lambdak, and compute expectation
        if self.ARD:
            self.alphak_s, self.betak_s = numpy.zeros(self.K), numpy.zeros(self.K)
            self.exp_lambdak, self.exp_loglambdak = numpy.zeros(self.K), numpy.zeros(self.K)
            for k in range(self.K):
                self.alphak_s[k] = self.alpha0
                self.betak_s[k] = self.beta0
                self.update_exp_lambdak(k)
                
        # Initialise parameters U, V
        self.mu_U, self.tau_U = numpy.zeros((self.I,self.K)), numpy.zeros((self.I,self.K))
        self.mu_V, self.tau_V = numpy.zeros((self.J,self.K)), numpy.zeros((self.J,self.K))
        
        for i,k in itertools.product(range(self.I),range(self.K)):  
            self.tau_U[i,k] = 1.
            hyperparam = self.exp_lambdak[k] if self.ARD else self.lambdaU[i,k]
            self.mu_U[i,k] = exponential_draw(hyperparam) if init_UV == 'random' else 1.0/hyperparam
        for j,k in itertools.product(range(self.J),range(self.K)):
            self.tau_V[j,k] = 1.
            hyperparam = self.exp_lambdak[k] if self.ARD else self.lambdaV[j,k]
            self.mu_V[j,k] = exponential_draw(hyperparam) if init_UV == 'random' else 1.0/hyperparam
        
        # Compute expectations and variances U, V
        self.exp_U, self.var_U = numpy.zeros((self.I,self.K)), numpy.zeros((self.I,self.K))
        self.exp_V, self.var_V = numpy.zeros((self.J,self.K)), numpy.zeros((self.J,self.K))
        
        for k in range(self.K):
            self.update_exp_U(k)
        for k in range(self.K):
            self.update_exp_V(k)

        # Initialise tau and compute expectation
        self.update_tau()
        self.update_exp_tau()
Exemplo n.º 14
0
 def initialise(self,init_S='random',init_FG='random',expo_prior=1.):
     assert init_S in ['ones','random','exponential'], "Unrecognised init option for S: %s." % init_S
     assert init_FG in ['ones','random','exponential','kmeans'], "Unrecognised init option for F,G: %s." % init_FG
     
     if init_S == 'ones':
         self.S = numpy.ones((self.K,self.L))
     elif init_S == 'random':
         self.S = numpy.random.rand(self.K,self.L)
     elif init_S == 'exponential':
         self.S = numpy.empty((self.K,self.L))
         for k,l in itertools.product(xrange(0,self.K),xrange(0,self.L)):        
             self.S[k,l] = exponential_draw(expo_prior)
     
     if init_FG == 'ones':
         self.F = numpy.ones((self.I,self.K))
         self.G = numpy.ones((self.J,self.L))
     elif init_FG == 'random':
         self.F = numpy.random.rand(self.I,self.K)
         self.G = numpy.random.rand(self.J,self.L)
     elif init_FG == 'exponential':
         self.F = numpy.empty((self.I,self.K))
         self.G = numpy.empty((self.J,self.L))
         for i,k in itertools.product(xrange(0,self.I),xrange(0,self.K)):        
             self.F[i,k] = exponential_draw(expo_prior)
         for j,l in itertools.product(xrange(0,self.J),xrange(0,self.L)):
             self.G[j,l] = exponential_draw(expo_prior)
     elif init_FG == 'kmeans':
         print "Initialising F using KMeans."
         kmeans_F = KMeans(self.R,self.M,self.K)
         kmeans_F.initialise()
         kmeans_F.cluster()
         self.F = kmeans_F.clustering_results + 0.2            
         
         print "Initialising G using KMeans."
         kmeans_G = KMeans(self.R.T,self.M.T,self.L)   
         kmeans_G.initialise()
         kmeans_G.cluster()
         self.G = kmeans_G.clustering_results + 0.2
Exemplo n.º 15
0
    def initialise(self, init='random'):
        assert init in [
            'random', 'exp'
        ], "Unknown initialisation option: %s. Should be 'random' or 'exp'." % init
        self.U = numpy.zeros((self.I, self.K))
        self.V = numpy.zeros((self.J, self.K))

        if init == 'random':
            for i, k in itertools.product(xrange(0, self.I), xrange(0,
                                                                    self.K)):
                self.U[i, k] = exponential_draw(self.lambdaU[i][k])
            for j, k in itertools.product(xrange(0, self.J), xrange(0,
                                                                    self.K)):
                self.V[j, k] = exponential_draw(self.lambdaV[j][k])

        elif init == 'exp':
            for i, k in itertools.product(xrange(0, self.I), xrange(0,
                                                                    self.K)):
                self.U[i, k] = 1.0 / self.lambdaU[i][k]
            for j, k in itertools.product(xrange(0, self.J), xrange(0,
                                                                    self.K)):
                self.V[j, k] = 1.0 / self.lambdaV[j][k]

        self.tau = self.alpha_s() / self.beta_s()
Exemplo n.º 16
0
    def initialise(self, init_FG='random', init_S='random'):
        ''' Initialise F, S, G, tau, and lambdaFk, lambdaGl (if ARD). '''
        assert init_FG in OPTIONS_INIT_FG, "Unknown initialisation option for F and G: %s. Should be in %s." % (
            init_FG, OPTIONS_INIT_FG)
        assert init_S in OPTIONS_INIT_S, "Unknown initialisation option for S: %s. Should be in %s." % (
            init_S, OPTIONS_INIT_S)

        # Initialise lambdaFk, lambdaGl, and compute expectations
        if self.ARD:
            self.alphaFk_s, self.betaFk_s = numpy.zeros(self.K), numpy.zeros(
                self.K)
            self.alphaGl_s, self.betaGl_s = numpy.zeros(self.L), numpy.zeros(
                self.L)
            self.exp_lambdaFk, self.exp_loglambdaFk = numpy.zeros(
                self.K), numpy.zeros(self.K)
            self.exp_lambdaGl, self.exp_loglambdaGl = numpy.zeros(
                self.L), numpy.zeros(self.L)
            for k in range(self.K):
                self.alphaFk_s[k] = self.alpha0
                self.betaFk_s[k] = self.beta0
                self.update_exp_lambdaFk(k)
            for l in range(self.L):
                self.alphaGl_s[l] = self.alpha0
                self.betaGl_s[l] = self.beta0
                self.update_exp_lambdaGl(l)

        # Initialise parameters F, G
        self.mu_F, self.tau_F = numpy.zeros((self.I, self.K)), numpy.zeros(
            (self.I, self.K))
        self.mu_G, self.tau_G = numpy.zeros((self.J, self.L)), numpy.zeros(
            (self.J, self.L))
        self.mu_S, self.tau_S = numpy.zeros((self.K, self.L)), numpy.zeros(
            (self.K, self.L))

        if init_FG == 'kmeans':
            print "Initialising F using KMeans."
            kmeans_F = KMeans(self.R, self.M, self.K)
            kmeans_F.initialise()
            kmeans_F.cluster()
            self.mu_F = kmeans_F.clustering_results

            for i, k in itertools.product(range(self.I), range(self.K)):
                self.tau_F[i, k] = 1.

            print "Initialising G using KMeans."
            kmeans_G = KMeans(self.R.T, self.M.T, self.L)
            kmeans_G.initialise()
            kmeans_G.cluster()
            self.mu_G = kmeans_G.clustering_results

            for j, l in itertools.product(range(self.J), range(self.L)):
                self.tau_G[j, l] = 1.
        else:
            # 'random' or 'exp'
            for i, k in itertools.product(range(self.I), range(self.K)):
                self.tau_F[i, k] = 1.
                hyperparam = self.exp_lambdaFk[
                    k] if self.ARD else self.lambdaF[i, k]
                self.mu_F[i, k] = exponential_draw(
                    hyperparam) if init_FG == 'random' else 1.0 / hyperparam
            for j, l in itertools.product(range(self.J), range(self.L)):
                self.tau_G[j, l] = 1.
                hyperparam = self.exp_lambdaGl[
                    l] if self.ARD else self.lambdaG[j, l]
                self.mu_G[j, l] = exponential_draw(
                    hyperparam) if init_FG == 'random' else 1.0 / hyperparam

        # Initialise parameters S
        for k, l in itertools.product(range(self.K), range(self.L)):
            self.tau_S[k, l] = 1.
            hyperparam = self.lambdaS[k, l]
            self.mu_S[k, l] = exponential_draw(
                hyperparam) if init_S == 'random' else 1.0 / hyperparam

        # Compute expectations and variances F, G, S
        self.exp_F, self.var_F = numpy.zeros((self.I, self.K)), numpy.zeros(
            (self.I, self.K))
        self.exp_G, self.var_G = numpy.zeros((self.J, self.L)), numpy.zeros(
            (self.J, self.L))
        self.exp_S, self.var_S = numpy.zeros((self.K, self.L)), numpy.zeros(
            (self.K, self.L))

        for k in range(self.K):
            self.update_exp_F(k)
        for l in range(self.L):
            self.update_exp_G(l)
        for k, l in itertools.product(range(self.K), range(self.L)):
            self.update_exp_S(k, l)

        # Initialise tau and compute expectation
        self.update_tau()
        self.update_exp_tau()