Example #1
0
 def __init__(self, **kwargs):
     super(Boa, self).__init__(**kwargs)
     self.network = BayesNet(numVariables=self.config.space.dim,
                             **self.config.__properties__)
     self.network = StructureProposal(**self.config.__properties__).search(
         self.network)
     self.trained = False
Example #2
0
 def update(self, history, fitness):
    super(Boa, self).update(history,fitness)
    if history.lastPopulation() is None:
       return
    
    population = [x for x,s in history.lastPopulation()]
    selected = int(self.config.truncate * len(population))
    self.network = BayesNet(numVariables=self.config.space.dim,
                            **self.config.__properties__)
    self.network.config.data = None
    self.network = StructureProposal(**self.network.config.__properties__).search(self.network)
    self.network.config.data = population
    self.network.structureSearch(population)
    self.network.update(self.history.updates, population)
Example #3
0
    def update(self, history, fitness):
        super(Boa, self).update(history, fitness)
        if history.lastPopulation() is None:
            return

        population = [x for x, s in history.lastPopulation()]
        selected = int(self.config.truncate * len(population))
        self.network = BayesNet(numVariables=self.config.space.dim,
                                **self.config.__properties__)
        self.network.config.data = None
        self.network = StructureProposal(
            **self.network.config.__properties__).search(self.network)
        self.network.config.data = population
        self.network.structureSearch(population)
        self.network.update(self.history.updates, population)
Example #4
0
    def parse(self, fname):
        f = open(fname)
        totalLine = ""
        done = False
        for line in f:
            totalLine += line
            lefts = len(totalLine.split("("))
            rights = len(totalLine.split(")"))
            if lefts == rights:
                self.processLine(totalLine)
                totalLine = ""
        categories = [[]] * self.index
        for name, idx in self.indexMap.iteritems():
            categories[idx] = self.variables[name]['vals']

        cfg = Config()
        cfg.numVariables = len(self.variables)
        cfg.variableGenerator = MultinomialVariableGenerator(categories)
        cfg.randomizer = MultinomialRandomizer()
        cfg.sampler = DAGSampler()
        cfg.structureGenerator = StructureProposal(cfg)

        net = BayesNet(cfg)
        for variable in net.variables:
            variable.tables = self.variables[self.revIndexMap[
                variable.index]]['cpt']
            #print names[variable.index], self.variables[self.revIndexMap[variable.index]]['parents']
            variable.known = [
                self.indexMap[parent] for parent in self.variables[
                    self.revIndexMap[variable.index]]['parents']
            ]
            variable.known = sorted(variable.known)
            variable.parents = dict([(i, net.variables[i])
                                     for i in variable.known])
        net.dirty = True
        net.computeEdgeStatistics()
        """
      for variable in net.variables:
         print "(var ", self.revIndexMap[variable.index], " (", " ".join(variable.categories[variable.index]), "))"
      
      for variable in net.variables:
         print "(parents ", self.revIndexMap[variable.index], " (", " ".join([self.revIndexMap[i] for i in variable.known]), ") "
         for key, val in variable.tables.iteritems():
            if key == "":
               expanded = ""
            else:
               cfg = array([int(num) for num in key.split(",")])
               expanded = " ".join(self.variables[self.revIndexMap[variable.known[k]]]['vals'][c-1] for k,c in enumerate(cfg))
            
            total = val.sum()
            vals = " ".join([str(i) for i in val])
            print "((", expanded, ") ", vals, (1. - total), ")"
         print ")"
      """
        return net
Example #5
0
    def __init__(self, space):
        self.space = space
        self.sampler = DAGSampler()

        if hasattr(space, 'dim'):
            self.numVariables = space.dim
        else:
            raise ValueError("Cannot determine the number of dimensions "
                             "for BinaryBayesStructure space based on given "
                             "space; expected space to have property dim "
                             "indicating the number of required variables. ")

        super(BinaryBayesStructure, self).__init__(self.numVariables**2)

        self.config = Config(numVariables=self.numVariables,
                             variableGenerator=self.variable,
                             randomizer=self.randomize,
                             sampler=self.sample)
        self.proposal = StructureProposal(**self.config.__properties__)
        self.config.structureGenerator = self.proposal
Example #6
0
class Boa(PopulationDistribution):
    """The Bayesian Optimization Algorithm of Martin Pelikan. """
    config = Config(
        variableGenerator=BinaryVariable,
        branchFactor=3,
        structureGenerator=GreedyStructureSearch(
            3, BayesianInformationCriterion()),
        randomizer=lambda net: TernaryString(0L, -1L, net.numVariables),
        sampler=DAGSampler(),
        data=None,
        truncate=0.60,  # percentage of the population to keep
        space=BinaryReal(realDim=5),
        history=SortedMarkovHistory)

    def __init__(self, **kwargs):
        super(Boa, self).__init__(**kwargs)
        self.network = BayesNet(numVariables=self.config.space.dim,
                                **self.config.__properties__)
        self.network = StructureProposal(**self.config.__properties__).search(
            self.network)
        self.trained = False

    def compatible(self, history):
        return hasattr(history, "lastPopulation") and history.sorted

    def sample(self):
        x = self.network.__call__()
        cnt = 0
        while not self.config.space.in_bounds(x):
            if cnt > 10000:
                raise ValueError(
                    "Rejection sampling failed after 10,000 attempts in BOA")
            x = self.network.__call__()
            cnt += 1
        return x

    def batch(self, num):
        return [self.sample() for i in xrange(num)]

    def update(self, history, fitness):
        super(Boa, self).update(history, fitness)
        if history.lastPopulation() is None:
            return

        population = [x for x, s in history.lastPopulation()]
        selected = int(self.config.truncate * len(population))
        self.network = BayesNet(numVariables=self.config.space.dim,
                                **self.config.__properties__)
        self.network.config.data = None
        self.network = StructureProposal(
            **self.network.config.__properties__).search(self.network)
        self.network.config.data = population
        self.network.structureSearch(population)
        self.network.update(self.history.updates, population)
Example #7
0
 def __init__(self, space):
     self.space = space
     self.sampler = DAGSampler()
     
     if hasattr(space, 'dim'):
         self.numVariables = space.dim
     else:
         raise ValueError("Cannot determine the number of dimensions "
                          "for BinaryBayesStructure space based on given "
                          "space; expected space to have property dim "
                          "indicating the number of required variables. ")
     
     super(BinaryBayesStructure, self).__init__(self.numVariables**2)
     
     self.config = Config(numVariables=self.numVariables,
                          variableGenerator=self.variable,
                          randomizer=self.randomize,
                          sampler=self.sample)
     self.proposal = StructureProposal(**self.config.__properties__)
     self.config.structureGenerator = self.proposal
Example #8
0
class Boa(PopulationDistribution):
   """The Bayesian Optimization Algorithm of Martin Pelikan. """
   config = Config(variableGenerator=BinaryVariable,
                   branchFactor=3,
                   structureGenerator=GreedyStructureSearch(3, BayesianInformationCriterion()),
                   randomizer = lambda net: TernaryString(0L, -1L, net.numVariables),
                   sampler = DAGSampler(),
                   data = None,
                   truncate = 0.60, # percentage of the population to keep
                   space = BinaryReal(realDim=5),
                   history=SortedMarkovHistory)

   def __init__(self, **kwargs):
      super(Boa, self).__init__(**kwargs)
      self.network = BayesNet(numVariables=self.config.space.dim,
                              **self.config.__properties__)
      self.network = StructureProposal(**self.config.__properties__).search(self.network)
      self.trained = False

   def compatible(self, history):
      return hasattr(history, "lastPopulation") and history.sorted

   def sample(self):
      x = self.network.__call__()
      cnt = 0
      while not self.config.space.in_bounds(x):
         if cnt > 10000:
            raise ValueError("Rejection sampling failed after 10,000 attempts in BOA")
         x = self.network.__call__()
         cnt += 1
      return x

   def batch(self, num):
      return [self.sample() for i in xrange(num)]

   def update(self, history, fitness):
      super(Boa, self).update(history,fitness)
      if history.lastPopulation() is None:
         return
      
      population = [x for x,s in history.lastPopulation()]
      selected = int(self.config.truncate * len(population))
      self.network = BayesNet(numVariables=self.config.space.dim,
                              **self.config.__properties__)
      self.network.config.data = None
      self.network = StructureProposal(**self.network.config.__properties__).search(self.network)
      self.network.config.data = population
      self.network.structureSearch(population)
      self.network.update(self.history.updates, population)
Example #9
0
class BayesNetStructure(Space, PreBayesSpace):
    """Space for Bayesian network structure search.
    
    Built on top of a variable space that determines the variables of the
    Bayes net. For example, a Euclidean space, say $\mathbb{R}^d$, would have
    $d$ :class:`GaussianVariable`s. Or, a Binary space would have
    :class:`BinaryVariable`s.
    
    The default choice of variable is controlled by the ``_mapping`` class
    variable based on the ``type`` field of the variable space. To have mixed
    networks, use a :class:`Product` space.
    
    :param space: The space of variables
    :type space: :class:`Space`
    
    """
    _mappings = {  # map space types to bayesian variables
        np.ndarray: GaussianVariable,
        TernaryString: BinaryVariable,
    }

    def __init__(self, space):
        super(BayesNetStructure, self).__init__(BayesNet)
        self.space = space
        self.sampler = DAGSampler()

        if hasattr(space, 'dim'):
            self.numVariables = space.dim
        else:
            raise ValueError("Cannot determine the number of dimensions "
                             "for BayesNetStructure space based on given "
                             "space; expected space to have property dim "
                             "indicating the number of required variables. ")

        self.config = Config(numVariables=self.numVariables,
                             variableGenerator=self.variable,
                             randomizer=self.randomize,
                             sampler=self.sample)
        self.proposal = StructureProposal(**self.config.__properties__)
        self.config.structureGenerator = self.proposal

        self.edges = []
        self.nedges = []

    def in_bounds(self, network, **kwargs):
        c = network.config
        return (isinstance(network, BayesNet)
                and len(network.variables) == self.numVariables and np.all([
                    v.__class__ == self.variable(v.index, c).__class__
                    for v in network.variables
                ]))

    def proportion(self, smaller, larger, index):
        return 2.0**((len(smaller.edges) + len(smaller.nedges)) -
                     (len(larger.edges) + len(larger.nedges)))

    def area(self, **kwargs):
        return 1.0

    def random(self):
        network = BayesNet(**self.config.__properties__)
        for i in xrange(5):
            self.proposal.search(network)
        return network

    def extent(self):
        return self.nedges, self.edges
        #raise NotImplementedError("Bayesian networks do not have a "
        #                          "well-defined notion of spatial extent; "
        #                          "If you have something in mind, please "
        #                          "subclass the space or submit a pull "
        #                          "request.")

    def hash(self, point):
        point.computeEdgeStatistics()
        return str(point.edges)
Example #10
0
class BinaryBayesStructure(Binary, PreBayesSpace):
    """A binary genotype with a Bayesian network structure phenotype.
    
    Bits indicate the presence or absence of an edge.
    
    Built on top of a variable space that determines the variables of the
    Bayes net. For example, a Euclidean space, say $\mathbb{R}^d$, would have
    $d$ :class:`GaussianVariable`s. Or, a Binary space would have
    :class:`BinaryVariable`s.
    
    The default choice of variable is controlled by the ``_mapping`` class
    variable based on the ``type`` field of the variable space. To have mixed
    networks, use a :class:`Product` space.
    
    :param space: The space of variables
    :type space: :class:`Space`
    
    """
    _mappings = {  # map space types to bayesian variables
        np.ndarray: GaussianVariable,
        TernaryString: BinaryVariable,
    }

    def __init__(self, space):
        self.space = space
        self.sampler = DAGSampler()

        if hasattr(space, 'dim'):
            self.numVariables = space.dim
        else:
            raise ValueError("Cannot determine the number of dimensions "
                             "for BinaryBayesStructure space based on given "
                             "space; expected space to have property dim "
                             "indicating the number of required variables. ")

        super(BinaryBayesStructure, self).__init__(self.numVariables**2)

        self.config = Config(numVariables=self.numVariables,
                             variableGenerator=self.variable,
                             randomizer=self.randomize,
                             sampler=self.sample)
        self.proposal = StructureProposal(**self.config.__properties__)
        self.config.structureGenerator = self.proposal

    def convert(self, x):
        if not isinstance(x, self.type):
            cname = self.__class__.__name__
            raise ValueError("Type mismatch in {0}.convert".format(cname))

        try:
            net = BayesNet(**self.config.__properties__)
            edges = []
            indexMap = {}
            for var in net.variables:
                indexMap[var.index] = var
            self.proposal.network = net
            for i in xrange(x.length):
                if x[i]:
                    frm, to = i % self.numVariables, i // self.numVariables
                    child = indexMap[frm]
                    parent = indexMap[to]
                    try:
                        self.proposal.addEdge(child, parent, self.config.data)
                    except CyclicException:
                        pass
            self.proposal.network = None
            return net
        except Exception:
            traceback.print_exc()
            raise ValueError("Unable to convert point due to exception")
Example #11
0
class BayesNetStructure(Space, PreBayesSpace):
    """Space for Bayesian network structure search.
    
    Built on top of a variable space that determines the variables of the
    Bayes net. For example, a Euclidean space, say $\mathbb{R}^d$, would have
    $d$ :class:`GaussianVariable`s. Or, a Binary space would have
    :class:`BinaryVariable`s.
    
    The default choice of variable is controlled by the ``_mapping`` class
    variable based on the ``type`` field of the variable space. To have mixed
    networks, use a :class:`Product` space.
    
    :param space: The space of variables
    :type space: :class:`Space`
    
    """
    _mappings = {  # map space types to bayesian variables
        np.ndarray: GaussianVariable,
        TernaryString: BinaryVariable,
    }
    
    def __init__(self, space):
        super(BayesNetStructure, self).__init__(BayesNet)
        self.space = space
        self.sampler = DAGSampler()
        
        if hasattr(space, 'dim'):
            self.numVariables = space.dim
        else:
            raise ValueError("Cannot determine the number of dimensions "
                             "for BayesNetStructure space based on given "
                             "space; expected space to have property dim "
                             "indicating the number of required variables. ")
        
        self.config = Config(numVariables=self.numVariables,
                             variableGenerator=self.variable,
                             randomizer=self.randomize,
                             sampler=self.sample)
        self.proposal = StructureProposal(**self.config.__properties__)
        self.config.structureGenerator = self.proposal
        
        self.edges = []
        self.nedges = []
    
    def in_bounds(self, network, **kwargs):
        c = network.config
        return (isinstance(network, BayesNet) and
                len(network.variables) == self.numVariables and
                np.all([v.__class__ == self.variable(v.index,c).__class__
                        for v in network.variables]))
        
    def proportion(self, smaller, larger, index):
        return  2.0 ** ((len(smaller.edges) + len(smaller.nedges)) -
                        (len(larger.edges) + len(larger.nedges)))
    
    def area(self, **kwargs):
        return 1.0
    
    def random(self):
        network = BayesNet(**self.config.__properties__)
        for i in xrange(5):
            self.proposal.search(network)
        return network
    
    def extent(self):
        return self.nedges, self.edges
        #raise NotImplementedError("Bayesian networks do not have a "
        #                          "well-defined notion of spatial extent; "
        #                          "If you have something in mind, please "
        #                          "subclass the space or submit a pull "
        #                          "request.")

    def hash(self, point):
        point.computeEdgeStatistics()
        return str(point.edges)
Example #12
0
class BinaryBayesStructure(Binary, PreBayesSpace):
    """A binary genotype with a Bayesian network structure phenotype.
    
    Bits indicate the presence or absence of an edge.
    
    Built on top of a variable space that determines the variables of the
    Bayes net. For example, a Euclidean space, say $\mathbb{R}^d$, would have
    $d$ :class:`GaussianVariable`s. Or, a Binary space would have
    :class:`BinaryVariable`s.
    
    The default choice of variable is controlled by the ``_mapping`` class
    variable based on the ``type`` field of the variable space. To have mixed
    networks, use a :class:`Product` space.
    
    :param space: The space of variables
    :type space: :class:`Space`
    
    """
    _mappings = {  # map space types to bayesian variables
        np.ndarray: GaussianVariable,
        TernaryString: BinaryVariable,
    }
    
    def __init__(self, space):
        self.space = space
        self.sampler = DAGSampler()
        
        if hasattr(space, 'dim'):
            self.numVariables = space.dim
        else:
            raise ValueError("Cannot determine the number of dimensions "
                             "for BinaryBayesStructure space based on given "
                             "space; expected space to have property dim "
                             "indicating the number of required variables. ")
        
        super(BinaryBayesStructure, self).__init__(self.numVariables**2)
        
        self.config = Config(numVariables=self.numVariables,
                             variableGenerator=self.variable,
                             randomizer=self.randomize,
                             sampler=self.sample)
        self.proposal = StructureProposal(**self.config.__properties__)
        self.config.structureGenerator = self.proposal
        
       
    def convert(self, x):
        if not isinstance(x, self.type):
            cname = self.__class__.__name__
            raise ValueError("Type mismatch in {0}.convert".format(cname))
        
        try:
            net = BayesNet(**self.config.__properties__)
            edges = []
            indexMap = {}
            for var in net.variables:
                indexMap[var.index] = var
            self.proposal.network = net
            for i in xrange(x.length):
                if x[i]:
                    frm, to = i % self.numVariables, i // self.numVariables
                    child = indexMap[frm]
                    parent = indexMap[to]
                    try:
                        self.proposal.addEdge(child, parent, self.config.data)
                    except CyclicException:
                        pass
            self.proposal.network = None
            return net
        except Exception:
            traceback.print_exc()
            raise ValueError("Unable to convert point due to exception")
Example #13
0
 def __init__(self, **kwargs):
    super(Boa, self).__init__(**kwargs)
    self.network = BayesNet(numVariables=self.config.space.dim,
                            **self.config.__properties__)
    self.network = StructureProposal(**self.config.__properties__).search(self.network)
    self.trained = False