/// <summary> /// Create a dependency between two labels. /// </summary> /// <param name="parentEventLabel">The parent event.</param> /// <param name="childEventLabel">The child event.</param> public void CreateDependency(String parentEventLabel, String childEventLabel) { BayesianEvent parentEvent = GetEventError(parentEventLabel); BayesianEvent childEvent = GetEventError(childEventLabel); CreateDependency(parentEvent, childEvent); }
/// <summary> /// Determine if two events are conditionally independent. /// </summary> /// <param name="a">The first event.</param> /// <param name="b">The second event.</param> /// <param name="given">What is "given".</param> /// <returns>True of they are cond. independent.</returns> public bool IsCondIndependent(BayesianEvent a, BayesianEvent b, params BayesianEvent[] given) { IDictionary <BayesianEvent, Object> searched = new Dictionary <BayesianEvent, Object>(); return(IsCondIndependent(false, a, b, searched, given)); }
/// <summary> /// Remove the specified event. /// </summary> /// <param name="theEvent">The event to remove.</param> private void RemoveEvent(BayesianEvent theEvent) { foreach (BayesianEvent e in theEvent.Parents) { e.Children.Remove(theEvent); } _eventMap.Remove(theEvent.Label); _events.Remove(theEvent); }
/// <summary> /// Determine if one event is a descendant of another. /// </summary> /// <param name="a">The event to check.</param> /// <param name="b">The event that has children.</param> /// <returns>True if a is amoung b's children.</returns> public bool IsDescendant(BayesianEvent a, BayesianEvent b) { if (a == b) { return(true); } return(b.Children.Any(e => IsDescendant(a, e))); }
/// <summary> /// Create a dependency between a parent and multiple children. /// </summary> /// <param name="parentEvent">The parent event.</param> /// <param name="children">The child events.</param> public void CreateDependency(BayesianEvent parentEvent, params BayesianEvent[] children) { foreach (BayesianEvent childEvent in children) { parentEvent.AddChild(childEvent); childEvent.AddParent(parentEvent); } }
/// <summary> /// Require the specified event, thrown an error if it does not exist. /// </summary> /// <param name="label">The label.</param> /// <returns>The event.</returns> public BayesianEvent RequireEvent(String label) { BayesianEvent result = GetEvent(label); if (result == null) { throw new BayesianError("The event " + label + " is not defined."); } return(result); }
/// <summary> /// Create a dependency between two events. /// </summary> /// <param name="parentEvent">The parent event.</param> /// <param name="childEvent">The child event.</param> public void CreateDependency(BayesianEvent parentEvent, BayesianEvent childEvent) { // does the dependency exist? if (!HasDependency(parentEvent, childEvent)) { // create the dependency parentEvent.AddChild(childEvent); childEvent.AddParent(parentEvent); } }
/// <summary> /// Create, or register, the specified event with this bayesian network. /// </summary> /// <param name="theEvent">The event to add.</param> public void CreateEvent(BayesianEvent theEvent) { if (EventExists(theEvent.Label)) { throw new BayesianError("The label \"" + theEvent.Label + "\" has already been defined."); } _eventMap[theEvent.Label] = theEvent; _events.Add(theEvent); }
///<summary> /// Get the index of the given event. ///</summary> ///<param name="theEvent">The event to get the index of.</param> ///<returns>The index of the event.</returns> public int GetEventIndex(BayesianEvent theEvent) { for (int i = 0; i < _events.Count; i++) { if (theEvent == _events[i]) { return(i); } } return(-1); }
/// <summary> /// Determine the classes for the specified input. /// </summary> /// <param name="input">The input.</param> /// <returns>An array of class indexes.</returns> public int[] DetermineClasses(IMLData input) { var result = new int[input.Count]; for (int i = 0; i < input.Count; i++) { BayesianEvent e = _events[i]; int classIndex = e.MatchChoiceToRange(input[i]); result[i] = classIndex; } return(result); }
/// <summary> /// Define a classification structure of the form P(A|B) = P(C) /// </summary> /// <param name="line">The structure.</param> public void DefineClassificationStructure(String line) { IList <ParsedProbability> list = ParseProbability.ParseProbabilityList(this, line); if (list.Count > 1) { throw new BayesianError("Must only define a single probability, not a chain."); } if (list.Count == 0) { throw new BayesianError("Must define at least one probability."); } // first define everything to be hidden foreach (BayesianEvent e in _events) { Query.DefineEventType(e, EventType.Hidden); } // define the base event ParsedProbability prob = list[0]; if (prob.BaseEvents.Count == 0) { return; } BayesianEvent be = GetEvent(prob.ChildEvent.Label); _classificationTarget = _events.IndexOf(be); Query.DefineEventType(be, EventType.Outcome); // define the given events foreach (ParsedEvent parsedGiven in prob.GivenEvents) { BayesianEvent given = GetEvent(parsedGiven.Label); Query.DefineEventType(given, EventType.Evidence); } Query.LocateEventTypes(); // set the values foreach (ParsedEvent parsedGiven in prob.GivenEvents) { BayesianEvent e = GetEvent(parsedGiven.Label); Query.SetEventValue(e, ParseInt(parsedGiven.Value)); } Query.SetEventValue(be, ParseInt(prob.BaseEvents[0].Value)); }
/// <summary> /// Format the event name with +, - and =. For example +a or -1, or a=red. /// </summary> /// <param name="theEvent">The event to format.</param> /// <param name="value">The value to format for.</param> /// <returns>The formatted name.</returns> public static String FormatEventName(BayesianEvent theEvent, int value) { var str = new StringBuilder(); if (theEvent.IsBoolean) { str.Append(value == 0 ? "+" : "-"); } str.Append(theEvent.Label); if (!theEvent.IsBoolean) { str.Append("="); str.Append(value); } return(str.ToString()); }
/// <summary> /// Create the specified events based on a variable number of options, or choices. /// </summary> /// <param name="label">The label of the event to create.</param> /// <param name="options">The states that the event can have.</param> /// <returns>The newly created event.</returns> public BayesianEvent CreateEvent(String label, params String[] options) { if (label == null) { throw new BayesianError("Can't create event with null label name"); } if (EventExists(label)) { throw new BayesianError("The label \"" + label + "\" has already been defined."); } BayesianEvent e = options.Length == 0 ? new BayesianEvent(label) : new BayesianEvent(label, options); CreateEvent(e); return(e); }
/// <summary> /// Classify the input. /// </summary> /// <param name="input">The input to classify.</param> /// <returns>The classification.</returns> public int Classify(IMLData input) { if (_classificationTarget < 0 || _classificationTarget >= _events.Count) { throw new BayesianError("Must specify classification target by calling setClassificationTarget."); } int[] d = DetermineClasses(input); // properly tag all of the events for (int i = 0; i < _events.Count; i++) { BayesianEvent e = _events[i]; if (i == _classificationTarget) { Query.DefineEventType(e, EventType.Outcome); } else if (_inputPresent[i]) { Query.DefineEventType(e, EventType.Evidence); Query.SetEventValue(e, d[i]); } else { Query.DefineEventType(e, EventType.Hidden); Query.SetEventValue(e, d[i]); } } // loop over and try each outcome choice BayesianEvent outcomeEvent = _events[_classificationTarget]; _classificationProbabilities = new double[outcomeEvent.Choices.Count]; for (int i = 0; i < outcomeEvent.Choices.Count; i++) { Query.SetEventValue(outcomeEvent, i); Query.Execute(); _classificationProbabilities[i] = Query.Probability; } return(EngineArray.MaxIndex(_classificationProbabilities)); }
/// <summary> /// Help determine if one event is conditionally independent of another. /// </summary> /// <param name="previousHead">The previous head, as we traverse the list.</param> /// <param name="a">The event to check.</param> /// <param name="goal">List of events searched.</param> /// <param name="searched"></param> /// <param name="given">Given events.</param> /// <returns>True if conditionally independent.</returns> private bool IsCondIndependent(bool previousHead, BayesianEvent a, BayesianEvent goal, IDictionary <BayesianEvent, Object> searched, params BayesianEvent[] given) { // did we find it? if (a == goal) { return(false); } // search children foreach (BayesianEvent e in a.Children) { if (!searched.ContainsKey(e) || !IsGiven(given, a)) { searched[e] = null; if (!IsCondIndependent(true, e, goal, searched, given)) { return(false); } } } // search parents foreach (BayesianEvent e in a.Parents) { if (!searched.ContainsKey(e)) { searched[e] = null; if (!previousHead || IsGivenOrDescendant(given, a)) { if (!IsCondIndependent(false, e, goal, searched, given)) { return(false); } } } } return(true); }
/// <summary> /// Perform a query. /// </summary> /// <param name="line">The query.</param> /// <returns>The probability.</returns> public double PerformQuery(String line) { if (Query == null) { throw new BayesianError("This Bayesian network does not have a query to define."); } var parse = new ParseProbability(this); ParsedProbability parsedProbability = parse.Parse(line); // create a temp query IBayesianQuery q = Query.Clone(); // first, mark all events as hidden q.Reset(); // deal with evidence (input) foreach (ParsedEvent parsedEvent in parsedProbability.GivenEvents) { BayesianEvent e = RequireEvent(parsedEvent.Label); q.DefineEventType(e, EventType.Evidence); q.SetEventValue(e, parsedEvent.ResolveValue(e)); } // deal with outcome (output) foreach (ParsedEvent parsedEvent in parsedProbability.BaseEvents) { BayesianEvent e = RequireEvent(parsedEvent.Label); q.DefineEventType(e, EventType.Outcome); q.SetEventValue(e, parsedEvent.ResolveValue(e)); } q.LocateEventTypes(); q.Execute(); return(q.Probability); }
/// <summary> /// Add a parent event. /// </summary> /// <param name="e">The parent event.</param> public void AddParent(BayesianEvent e) { _parents.Add(e); }
/// <summary> /// Determine if one Bayesian event is in an array of others. /// </summary> /// <param name="given">The events to check.</param> /// <param name="e">See if e is amoung given.</param> /// <returns>True if e is amoung given.</returns> private static bool IsGiven(IEnumerable<BayesianEvent> given, BayesianEvent e) { return given.Any(e2 => e == e2); }
/// <summary> /// Determine if one event is a descendant of another. /// </summary> /// <param name="a">The event to check.</param> /// <param name="b">The event that has children.</param> /// <returns>True if a is amoung b's children.</returns> public bool IsDescendant(BayesianEvent a, BayesianEvent b) { if (a == b) return true; return b.Children.Any(e => IsDescendant(a, e)); }
/// <summary> /// Add a child event. /// </summary> /// <param name="e">The child event.</param> public void AddChild(BayesianEvent e) { _children.Add(e); }
/// <summary> /// Remove a dependency, if it it exists. /// </summary> /// <param name="parent">The parent event.</param> /// <param name="child">The child event.</param> private void RemoveDependency(BayesianEvent parent, BayesianEvent child) { parent.Children.Remove(child); child.Parents.Remove(parent); }
/// <summary> /// Determine if the two events have a dependency. /// </summary> /// <param name="parentEvent">The parent event.</param> /// <param name="childEvent">The child event.</param> /// <returns>True if a dependency exists.</returns> private bool HasDependency(BayesianEvent parentEvent, BayesianEvent childEvent) { return (parentEvent.Children.Contains(childEvent)); }
/// <summary> /// Create the specified events based on a variable number of options, or choices. /// </summary> /// <param name="label">The label of the event to create.</param> /// <param name="options">The states that the event can have.</param> /// <returns>The newly created event.</returns> public BayesianEvent CreateEvent(String label, params String[] options) { if (label == null) { throw new BayesianError("Can't create event with null label name"); } if (EventExists(label)) { throw new BayesianError("The label \"" + label + "\" has already been defined."); } BayesianEvent e; if (options.Length == 0) { e = new BayesianEvent(label); } else { e = new BayesianEvent(label, options); } CreateEvent(e); return e; }
/// <summary> /// Add a child event. /// </summary> /// <param name="e">The child event.</param> public void AddChild(BayesianEvent e) { _children.Add(e); }
/// <summary> /// Determine if the two events have a dependency. /// </summary> /// <param name="parentEvent">The parent event.</param> /// <param name="childEvent">The child event.</param> /// <returns>True if a dependency exists.</returns> private static bool HasDependency(BayesianEvent parentEvent, BayesianEvent childEvent) { return(parentEvent.Children.Contains(childEvent)); }
/// <summary> /// Add a parent event. /// </summary> /// <param name="e">The parent event.</param> public void AddParent(BayesianEvent e) { _parents.Add(e); }
/// <summary> /// True if this event is given or conditionally dependant on the others. /// </summary> /// <param name="given">The others to check.</param> /// <param name="e">The event to check.</param> /// <returns>True, if is given or descendant.</returns> private bool IsGivenOrDescendant(IEnumerable<BayesianEvent> given, BayesianEvent e) { return given.Any(e2 => IsDescendant(e2, e)); }
/// <summary> /// Remove a dependency, if it it exists. /// </summary> /// <param name="parent">The parent event.</param> /// <param name="child">The child event.</param> private static void RemoveDependency(BayesianEvent parent, BayesianEvent child) { parent.Children.Remove(child); child.Parents.Remove(parent); }
/// <summary> /// Create, or register, the specified event with this bayesian network. /// </summary> /// <param name="theEvent">The event to add.</param> public void CreateEvent(BayesianEvent theEvent) { if (EventExists(theEvent.Label)) { throw new BayesianError("The label \"" + theEvent.Label + "\" has already been defined."); } this.eventMap[theEvent.Label] = theEvent; this.events.Add(theEvent); }
/// <summary> /// Determine if one Bayesian event is in an array of others. /// </summary> /// <param name="given">The events to check.</param> /// <param name="e">See if e is amoung given.</param> /// <returns>True if e is amoung given.</returns> private bool IsGiven(BayesianEvent[] given, BayesianEvent e) { foreach (BayesianEvent e2 in given) { if (e == e2) return true; } return false; }
/// <summary> /// Create a dependency between two events. /// </summary> /// <param name="parentEvent">The parent event.</param> /// <param name="childEvent">The child event.</param> public void CreateDependency(BayesianEvent parentEvent, BayesianEvent childEvent) { // does the dependency exist? if (!HasDependency(parentEvent, childEvent)) { // create the dependency parentEvent.AddChild(childEvent); childEvent.AddParent(parentEvent); } }
/// <summary> /// True if this event is given or conditionally dependant on the others. /// </summary> /// <param name="given">The others to check.</param> /// <param name="e">The event to check.</param> /// <returns>True, if is given or descendant.</returns> private bool IsGivenOrDescendant(BayesianEvent[] given, BayesianEvent e) { foreach (BayesianEvent e2 in given) { if (IsDescendant(e2, e)) return true; } return false; }
/// <summary> /// Create a dependency between a parent and multiple children. /// </summary> /// <param name="parentEvent">The parent event.</param> /// <param name="children">The child events.</param> public void CreateDependency(BayesianEvent parentEvent, params BayesianEvent[] children) { foreach (BayesianEvent childEvent in children) { parentEvent.AddChild(childEvent); childEvent.AddParent(parentEvent); } }
/// <summary> /// Determine if two events are conditionally independent. /// </summary> /// <param name="a">The first event.</param> /// <param name="b">The second event.</param> /// <param name="given">What is "given".</param> /// <returns>True of they are cond. independent.</returns> public bool IsCondIndependent(BayesianEvent a, BayesianEvent b, params BayesianEvent[] given) { IDictionary<BayesianEvent, Object> searched = new Dictionary<BayesianEvent, Object>(); return IsCondIndependent(false, a, b, searched, given); }
/// <summary> /// Remove the specified event. /// </summary> /// <param name="theEvent">The event to remove.</param> private void RemoveEvent(BayesianEvent theEvent) { foreach (BayesianEvent e in theEvent.Parents) { e.Children.Remove(theEvent); } this.eventMap.Remove(theEvent.Label); this.events.Remove(theEvent); }
/// <summary> /// Format the event name with +, - and =. For example +a or -1, or a=red. /// </summary> /// <param name="theEvent">The event to format.</param> /// <param name="value">The value to format for.</param> /// <returns>The formatted name.</returns> public static String FormatEventName(BayesianEvent theEvent, int value) { var str = new StringBuilder(); if (theEvent.IsBoolean) { str.Append(value == 0 ? "+" : "-"); } str.Append(theEvent.Label); if (!theEvent.IsBoolean) { str.Append("="); str.Append(value); } return str.ToString(); }
/// <summary> /// Determine if one event is a descendant of another. /// </summary> /// <param name="a">The event to check.</param> /// <param name="b">The event that has children.</param> /// <returns>True if a is amoung b's children.</returns> public bool IsDescendant(BayesianEvent a, BayesianEvent b) { if (a == b) return true; foreach (BayesianEvent e in b.Children) { if (IsDescendant(a, e)) return true; } return false; }
/// <summary> /// Determine if one Bayesian event is in an array of others. /// </summary> /// <param name="given">The events to check.</param> /// <param name="e">See if e is amoung given.</param> /// <returns>True if e is amoung given.</returns> private static bool IsGiven(IEnumerable <BayesianEvent> given, BayesianEvent e) { return(given.Any(e2 => e == e2)); }
/// <summary> /// Help determine if one event is conditionally independent of another. /// </summary> /// <param name="previousHead">The previous head, as we traverse the list.</param> /// <param name="a">The event to check.</param> /// <param name="goal">List of events searched.</param> /// <param name="searched"></param> /// <param name="given">Given events.</param> /// <returns>True if conditionally independent.</returns> private bool IsCondIndependent(bool previousHead, BayesianEvent a, BayesianEvent goal, IDictionary<BayesianEvent, Object> searched, params BayesianEvent[] given) { // did we find it? if (a == goal) { return false; } // search children foreach (BayesianEvent e in a.Children) { if (!searched.ContainsKey(e) || !IsGiven(given, a)) { searched[e] = null; if (!IsCondIndependent(true, e, goal, searched, given)) return false; } } // search parents foreach (BayesianEvent e in a.Parents) { if (!searched.ContainsKey(e)) { searched[e] = null; if (!previousHead || IsGivenOrDescendant(given, a)) if (!IsCondIndependent(false, e, goal, searched, given)) return false; } } return true; }
/// <summary> /// True if this event is given or conditionally dependant on the others. /// </summary> /// <param name="given">The others to check.</param> /// <param name="e">The event to check.</param> /// <returns>True, if is given or descendant.</returns> private bool IsGivenOrDescendant(IEnumerable <BayesianEvent> given, BayesianEvent e) { return(given.Any(e2 => IsDescendant(e2, e))); }
public int GetEventIndex(BayesianEvent theEvent) { for (int i = 0; i < this.events.Count; i++) { if (theEvent == events[i]) return i; } return -1; }
/// <inheritdoc/> public void Save(Stream os, Object obj) { EncogWriteHelper o = new EncogWriteHelper(os); BayesianNetwork b = (BayesianNetwork)obj; o.AddSection("BAYES-NETWORK"); o.AddSubSection("BAYES-PARAM"); String queryType = ""; String queryStr = b.ClassificationStructure; if (b.Query != null) { queryType = b.Query.GetType().Name; } o.WriteProperty("queryType", queryType); o.WriteProperty("query", queryStr); o.WriteProperty("contents", b.Contents); o.AddSubSection("BAYES-PROPERTIES"); o.AddProperties(b.Properties); o.AddSubSection("BAYES-TABLE"); foreach (BayesianEvent e in b.Events) { foreach (TableLine line in e.Table.Lines) { if (line == null) { continue; } StringBuilder str = new StringBuilder(); str.Append("P("); str.Append(BayesianEvent.FormatEventName(e, line.Result)); if (e.Parents.Count > 0) { str.Append("|"); } int index = 0; bool first = true; foreach (BayesianEvent parentEvent in e.Parents) { if (!first) { str.Append(","); } first = false; int arg = line.Arguments[index++]; if (parentEvent.IsBoolean) { if (arg == 0) { str.Append("+"); } else { str.Append("-"); } } str.Append(parentEvent.Label); if (!parentEvent.IsBoolean) { str.Append("="); if (arg >= parentEvent.Choices.Count) { throw new BayesianError("Argument value " + arg + " is out of range for event " + parentEvent.ToString()); } str.Append(parentEvent.GetChoice(arg)); } } str.Append(")="); str.Append(line.Probability); str.Append("\n"); o.Write(str.ToString()); } } o.Flush(); }