コード例 #1
0
  /**
   * Help determine if one event is conditionally independent of another.
   *
   * @param previousHead The previous head, as we traverse the list.
   * @param a The event to check.
   * @param goal The goal.
   * @param searched List of events searched.
   * @param given Given events.
   * @return True if conditionally independent.
   */
  private boolean isCondIndependent(
      boolean previousHead,
      BayesianEvent a,
      BayesianEvent goal,
      Set<BayesianEvent> searched,
      BayesianEvent... given) {

    // did we find it?
    if (a == goal) {
      return false;
    }

    // search children
    for (BayesianEvent e : a.getChildren()) {
      if (!searched.contains(e) || !isGiven(given, a)) {
        searched.add(e);
        if (!isCondIndependent(true, e, goal, searched, given)) return false;
      }
    }

    // search parents
    for (BayesianEvent e : a.getParents()) {
      if (!searched.contains(e)) {
        searched.add(e);
        if (!previousHead || isGivenOrDescendant(given, a))
          if (!isCondIndependent(false, e, goal, searched, given)) return false;
      }
    }

    return true;
  }
コード例 #2
0
 /** @return The number of parameters in this Bayesian network. */
 public int calculateParameterCount() {
   int result = 0;
   for (BayesianEvent e : this.eventMap.values()) {
     result += e.calculateParameterCount();
   }
   return result;
 }
コード例 #3
0
 /**
  * Remove the specified event.
  *
  * @param event The event to remove.
  */
 private void removeEvent(BayesianEvent event) {
   for (BayesianEvent e : event.getParents()) {
     e.getChildren().remove(event);
   }
   this.eventMap.remove(event.getLabel());
   this.events.remove(event);
 }
コード例 #4
0
  /**
   * Classify the input.
   *
   * @param input The input to classify.
   */
  @Override
  public int classify(MLData input) {

    if (this.classificationTarget < 0 || this.classificationTarget >= this.events.size()) {
      throw new BayesianError(
          "Must specify classification target by calling setClassificationTarget.");
    }

    int[] d = this.determineClasses(input);

    // properly tag all of the events
    for (int i = 0; i < this.events.size(); i++) {
      BayesianEvent event = this.events.get(i);
      if (i == this.classificationTarget) {
        this.query.defineEventType(event, EventType.Outcome);
      } else if (this.inputPresent[i]) {
        this.query.defineEventType(event, EventType.Evidence);
        this.query.setEventValue(event, d[i]);
      } else {
        this.query.defineEventType(event, EventType.Hidden);
        this.query.setEventValue(event, d[i]);
      }
    }

    // loop over and try each outcome choice
    BayesianEvent outcomeEvent = this.events.get(this.classificationTarget);
    this.classificationProbabilities = new double[outcomeEvent.getChoices().size()];
    for (int i = 0; i < outcomeEvent.getChoices().size(); i++) {
      this.query.setEventValue(outcomeEvent, i);
      this.query.execute();
      classificationProbabilities[i] = this.query.getProbability();
    }

    return EngineArray.maxIndex(this.classificationProbabilities);
  }
コード例 #5
0
  /**
   * @return Returns a string representation of the classification structure. Of the form P(a|b,c,d)
   */
  public String getClassificationStructure() {
    StringBuilder result = new StringBuilder();

    result.append("P(");
    boolean first = true;

    for (int i = 0; i < this.getEvents().size(); i++) {
      BayesianEvent event = this.events.get(i);
      EventState state = this.query.getEventState(event);
      if (state.getEventType() == EventType.Outcome) {
        if (!first) {
          result.append(",");
        }
        result.append(event.getLabel());
        first = false;
      }
    }

    result.append("|");

    first = true;
    for (int i = 0; i < this.getEvents().size(); i++) {
      BayesianEvent event = this.events.get(i);
      if (this.query.getEventState(event).getEventType() == EventType.Evidence) {
        if (!first) {
          result.append(",");
        }
        result.append(event.getLabel());
        first = false;
      }
    }

    result.append(")");
    return result.toString();
  }
コード例 #6
0
 /**
  * Create a dependency between two events.
  *
  * @param parentEvent The parent event.
  * @param childEvent The child event.
  */
 public void createDependency(BayesianEvent parentEvent, BayesianEvent childEvent) {
   // does the dependency exist?
   if (!hasDependency(parentEvent, childEvent)) {
     // create the dependency
     parentEvent.addChild(childEvent);
     childEvent.addParent(parentEvent);
   }
 }
コード例 #7
0
  /**
   * Create, or register, the specified event with this bayesian network.
   *
   * @param event The event to add.
   */
  public void createEvent(BayesianEvent event) {
    if (eventExists(event.getLabel())) {
      throw new BayesianError("The label \"" + event.getLabel() + "\" has already been defined.");
    }

    this.eventMap.put(event.getLabel(), event);
    this.events.add(event);
  }
コード例 #8
0
  /**
   * Determine the classes for the specified input.
   *
   * @param input The input.
   * @return An array of class indexes.
   */
  public int[] determineClasses(MLData input) {
    int[] result = new int[input.size()];

    for (int i = 0; i < input.size(); i++) {
      BayesianEvent event = this.events.get(i);
      int classIndex = event.matchChoiceToRange(input.getData(i));
      result[i] = classIndex;
    }

    return result;
  }
コード例 #9
0
  /** {@inheritDoc} */
  public String toString() {
    StringBuilder result = new StringBuilder();
    boolean first = true;

    for (BayesianEvent e : this.events) {
      if (!first) result.append(" ");
      first = false;
      result.append(e.toString());
    }

    return result.toString();
  }
コード例 #10
0
  /** Finalize the structure of this Bayesian network. */
  public void finalizeStructure() {
    for (BayesianEvent e : this.eventMap.values()) {
      e.finalizeStructure();
    }

    if (this.query != null) {
      this.query.finalizeStructure();
    }

    this.inputPresent = new boolean[this.events.size()];
    EngineArray.fill(this.inputPresent, true);
    this.classificationTarget = -1;
  }
コード例 #11
0
  public void testSampling3() {
    BayesianNetwork network = new BayesianNetwork();
    BayesianEvent a = network.createEvent("a");
    BayesianEvent x1 = network.createEvent("x1");
    BayesianEvent x2 = network.createEvent("x2");
    BayesianEvent x3 = network.createEvent("x3");

    network.createDependancy(a, x1, x2, x3);
    network.finalizeStructure();

    a.getTable().addLine(0.5, true); // P(A) = 0.5
    x1.getTable().addLine(0.2, true, true); // p(x1|a) = 0.2
    x1.getTable().addLine(0.6, true, false); // p(x1|~a) = 0.6
    x2.getTable().addLine(0.2, true, true); // p(x2|a) = 0.2
    x2.getTable().addLine(0.6, true, false); // p(x2|~a) = 0.6
    x3.getTable().addLine(0.2, true, true); // p(x3|a) = 0.2
    x3.getTable().addLine(0.6, true, false); // p(x3|~a) = 0.6
    network.validate();

    SamplingQuery query = new SamplingQuery(network);
    query.defineEventType(x1, EventType.Evidence);
    query.defineEventType(x3, EventType.Outcome);
    query.setEventValue(x1, true);
    query.setEventValue(x3, true);
    query.execute();
    testPercent(query.getProbability(), 50);
  }
コード例 #12
0
  /**
   * Determine if one event is a descendant of another.
   *
   * @param a The event to check.
   * @param b The event that has children.
   * @return True if a is amoung b's children.
   */
  public boolean isDescendant(BayesianEvent a, BayesianEvent b) {
    if (a == b) return true;

    for (BayesianEvent e : b.getChildren()) {
      if (isDescendant(a, e)) return true;
    }
    return false;
  }
コード例 #13
0
  public void testSampling1() {
    BayesianNetwork network = new BayesianNetwork();
    BayesianEvent a = network.createEvent("a");
    BayesianEvent b = network.createEvent("b");

    network.createDependancy(a, b);
    network.finalizeStructure();
    a.getTable().addLine(0.5, true); // P(A) = 0.5
    b.getTable().addLine(0.2, true, true); // p(b|a) = 0.2
    b.getTable().addLine(0.8, true, false); // p(b|~a) = 0.8	
    network.validate();

    SamplingQuery query = new SamplingQuery(network);
    query.defineEventType(a, EventType.Evidence);
    query.defineEventType(b, EventType.Outcome);
    query.setEventValue(b, true);
    query.setEventValue(a, true);
    query.execute();
    testPercent(query.getProbability(), 20);
  }
コード例 #14
0
 /** Validate the structure of this Bayesian network. */
 public void validate() {
   for (BayesianEvent e : this.eventMap.values()) {
     e.validate();
   }
 }
コード例 #15
0
  /** {@inheritDoc} */
  @Override
  public final void save(final OutputStream os, final Object obj) {
    final EncogWriteHelper out = new EncogWriteHelper(os);
    final BayesianNetwork b = (BayesianNetwork) obj;
    out.addSection("BAYES-NETWORK");
    out.addSubSection("BAYES-PARAM");
    String queryType = "";
    String queryStr = b.getClassificationStructure();

    if (b.getQuery() != null) {
      queryType = b.getQuery().getClass().getSimpleName();
    }

    out.writeProperty("queryType", queryType);
    out.writeProperty("query", queryStr);
    out.writeProperty("contents", b.getContents());
    out.addSubSection("BAYES-PROPERTIES");
    out.addProperties(b.getProperties());

    out.addSubSection("BAYES-TABLE");
    for (BayesianEvent event : b.getEvents()) {
      for (TableLine line : event.getTable().getLines()) {
        if (line == null) continue;
        StringBuilder str = new StringBuilder();
        str.append("P(");

        str.append(BayesianEvent.formatEventName(event, line.getResult()));

        if (event.getParents().size() > 0) {
          str.append("|");
        }

        int index = 0;
        boolean first = true;
        for (BayesianEvent parentEvent : event.getParents()) {
          if (!first) {
            str.append(",");
          }
          first = false;
          int arg = line.getArguments()[index++];
          if (parentEvent.isBoolean()) {
            if (arg == 0) {
              str.append("+");
            } else {
              str.append("-");
            }
          }
          str.append(parentEvent.getLabel());
          if (!parentEvent.isBoolean()) {
            str.append("=");
            if (arg >= parentEvent.getChoices().size()) {
              throw new BayesianError(
                  "Argument value " + arg + " is out of range for event " + parentEvent.toString());
            }
            str.append(parentEvent.getChoice(arg));
          }
        }
        str.append(")=");
        str.append(line.getProbability());
        str.append("\n");
        out.write(str.toString());
      }
    }

    out.flush();
  }
コード例 #16
0
 /**
  * Determine if the two events have a dependency.
  *
  * @param parentEvent The parent event.
  * @param childEvent The child event.
  * @return True if a dependency exists.
  */
 private boolean hasDependency(BayesianEvent parentEvent, BayesianEvent childEvent) {
   return (parentEvent.getChildren().contains(childEvent));
 }
コード例 #17
0
 /**
  * Create a dependency between a parent and multiple children.
  *
  * @param parentEvent The parent event.
  * @param children The child events.
  */
 public void createDependency(BayesianEvent parentEvent, BayesianEvent... children) {
   for (BayesianEvent childEvent : children) {
     parentEvent.addChild(childEvent);
     childEvent.addParent(parentEvent);
   }
 }
コード例 #18
0
  /**
   * Define the structure of the Bayesian network as a string.
   *
   * @param line The string to define events and relations.
   */
  public void setContents(String line) {
    List<ParsedProbability> list = ParseProbability.parseProbabilityList(this, line);
    List<String> labelList = new ArrayList<String>();

    // ensure that all events are there
    for (ParsedProbability prob : list) {
      ParsedEvent parsedEvent = prob.getChildEvent();
      String eventLabel = parsedEvent.getLabel();
      labelList.add(eventLabel);

      // create event, if not already here
      BayesianEvent e = getEvent(eventLabel);
      if (e == null) {
        List<BayesianChoice> cl = new ArrayList<BayesianChoice>();

        for (ParsedChoice c : parsedEvent.getList()) {
          cl.add(new BayesianChoice(c.getLabel(), c.getMin(), c.getMax()));
        }

        createEvent(eventLabel, cl);
      }
    }

    // now remove all events that were not covered
    for (int i = 0; i < events.size(); i++) {
      BayesianEvent event = this.events.get(i);
      if (!labelList.contains(event.getLabel())) {
        removeEvent(event);
      }
    }

    // handle dependencies
    for (ParsedProbability prob : list) {
      ParsedEvent parsedEvent = prob.getChildEvent();
      String eventLabel = parsedEvent.getLabel();

      BayesianEvent event = requireEvent(eventLabel);

      // ensure that all "givens" are present
      List<String> givenList = new ArrayList<String>();
      for (ParsedEvent given : prob.getGivenEvents()) {
        if (!event.hasGiven(given.getLabel())) {
          BayesianEvent givenEvent = requireEvent(given.getLabel());
          this.createDependency(givenEvent, event);
        }
        givenList.add(given.getLabel());
      }

      // now remove givens that were not covered
      for (int i = 0; i < event.getParents().size(); i++) {
        BayesianEvent event2 = event.getParents().get(i);
        if (!givenList.contains(event2.getLabel())) {
          removeDependency(event2, event);
        }
      }
    }

    // finalize the structure
    finalizeStructure();
    if (this.query != null) {
      this.query.finalizeStructure();
    }
  }
コード例 #19
0
 /** {@inheritDoc} */
 @Override
 public void reset(int seed) {
   for (BayesianEvent event : this.events) {
     event.reset();
   }
 }
コード例 #20
0
 /** Remove all relations between nodes. */
 public void removeAllRelations() {
   for (BayesianEvent event : this.events) {
     event.removeAllRelations();
   }
 }
コード例 #21
0
 /**
  * Remove a dependency, if it it exists.
  *
  * @param parent The parent event.
  * @param child The child event.
  */
 private void removeDependency(BayesianEvent parent, BayesianEvent child) {
   parent.getChildren().remove(child);
   child.getParents().remove(parent);
 }