Ejemplo n.º 1
0
    def stepwise_e_step(self, data, varNames):
        '''collect sufficient statistics for each variable
        data: 2d numpy array
        varNames: list of string
        '''
        ctp = NaturalCliqueTreePropagation(self._model)
        tree = ctp.cliqueTree()
        cliques = tree.cliques

        # set up evidence
        datacase = ContinuousDatacase.create(varNames)
        datacase.synchronize(self._model)

        for i in range(len(data)):
            datacase.putValues(data[i])
            evidence = datacase.getEvidence()
            ctp.use(evidence)
            ctp.propagate()

            for j in range(len(cliques)):
                self.batchSufficientStatistics[j].add(cliques[j].potential)

        # construct variable to statisticMap
        variableStatisticMap = dict()
        for node in self._model.nodes:
            clique = tree.getClique(node.variable)
            index = cliques.index(clique)
            variableStatisticMap[node.variable] = (
                self.sufficientStatistics[index],
                self.batchSufficientStatistics[index])
        return variableStatisticMap
Ejemplo n.º 2
0
 def initializeSufficientStatistics(self, batch_size):
     ctp = NaturalCliqueTreePropagation(self._model)
     ctp.initializePotentials()
     tree = ctp.cliqueTree()
     cliques = tree.cliques
     sufficientStatistics = [None] * len(cliques)
     batchSufficientStatistics = [None] * len(cliques)
     for i in range(len(cliques)):
         if isinstance(cliques[i], DiscreteClique):
             sufficientStatistics[i] = DiscreteCliqueSufficientStatistics(
                 cliques[i], batch_size)
             batchSufficientStatistics[
                 i] = DiscreteCliqueSufficientStatistics(
                     cliques[i], batch_size)
         elif isinstance(cliques[i], MixedClique):
             sufficientStatistics[i] = MixedCliqueSufficientStatistics(
                 cliques[i], batch_size)
             batchSufficientStatistics[i] = MixedCliqueSufficientStatistics(
                 cliques[i], batch_size)
         else:
             raise Exception("unknown type of clique")
     return sufficientStatistics, batchSufficientStatistics
Ejemplo n.º 3
0
    def grad(self, x):
        datacase = ContinuousDatacase.create(self.varNames)
        datacase.synchronize(self._model)
        ctp = NaturalCliqueTreePropagation(self._model)
        num, dim = x.shape
        out = np.zeros((num, dim), dtype=np.float32)

        datacase.putValues(x)
        evidence = datacase.getEvidence()
        ctp.use(evidence)
        ctp.propagate()

        tree = ctp.cliqueTree()
        gradient = np.zeros((num, dim))
        for node in self._model.getLeafNodes():
          clique = tree.getClique(node.variable)
          cliquePotential = clique.potential.clone()
          cliquePotential.normalize()

          moGpotential = node.potential.clone()
          
          vars = moGpotential.continuousVariables
          value = evidence.getValues(vars)

          b = np.zeros(len(vars))
          subgradient = np.zeros((num, len(vars)))
          for j in range(moGpotential.size):
            sol = np.linalg.solve(moGpotential.get(j).covar, (np.expand_dims(moGpotential.get(j).mu, axis=0) - value).T).T
            # subgradient += sol * np.expand_dims(cliquePotential.p[:, j], axis=1)
            subgradient += sol * np.expand_dims(np.exp(cliquePotential.logp[:, j]), axis=1)

          for j in range(len(vars)):
            index = datacase.variables.index(vars[j])
            gradient[:, index] = subgradient[:, j]

        return gradient