/// <summary> /// Learn a bayesian network for the given hazard, states and faults with a constraint-based learning algorithm and model checking. /// </summary> /// <param name="hazard">The hazard expression which should be analyzed</param> /// <param name="states">An optional dictionary for arbitrary named state expressions that should be analyzed</param> /// <param name="faults">An optional fault list to restrict the analyzed set or to give a chronological order for causal fallback algorithms</param> /// <returns>A learning bayesian network including a DAG and a fully calculated probability distribution</returns> public BayesianNetwork LearnConstraintBasedBayesianNetwork(Func <bool> hazard, Dictionary <string, Func <bool> > states = null, IList <Fault> faults = null) { CreateRandomVariables(hazard, states, faults); var allVars = AllRandomVariables(); var probCalculator = new OnDemandProbabilityDistributionCalculator(_model, allVars, _stepBounds, Tolerance, Config); var independenceCalculator = new IndependencyCalculator(probCalculator, Tolerance, Config); var independencies = independenceCalculator.FindIndependencies(_faultVars, _mcsVars, _states, _hazardVar); independenceCalculator.PrettyPrintIndependencies(); var structureLearner = new ConstraintBasedStructureLearner(allVars, independencies); structureLearner.LearnDag(); structureLearner.UseDccaForOrientations(_mcsVars, _faultVars, _hazardVar); var dag = structureLearner.DagPatternToDag(); Console.Out.WriteLine($"Calculated {probCalculator.NumberOfCalculatedDistributions()} out of {probCalculator.NumberOfMaxDistributions()} possible distributions"); var bayesianNetwork = BayesianNetwork.FromDagPattern(dag, probCalculator); bayesianNetwork.PrintBayesianNetwork(); Console.Out.WriteLine($"Calculated {probCalculator.NumberOfCalculatedDistributions()} out of {probCalculator.NumberOfMaxDistributions()} possible distributions"); CheckResultingNetwork(bayesianNetwork); StoreBayesianNetwork(bayesianNetwork); return(bayesianNetwork); }
/// <summary> /// Creates a Bayesian Network from a given DagPattern which has to be a DAG and uses the given distributions if they fit the DAG structure. /// </summary> /// <exception cref="ArgumentException">Thrown when the given DagPattern is no DAG or the distributions don't fit the DAG structure</exception> public static BayesianNetwork FromDagPattern(DagPattern <RandomVariable> dag, IEnumerable <ProbabilityDistribution> distributions) { if (!dag.IsDag()) { throw new ArgumentException("BayesianNetworks need a DAG, but the given DAG was actually a DAG pattern!"); } var network = new BayesianNetwork(dag); var processed = new bool[network.RandomVariables.Count]; foreach (var distribution in distributions) { var rvar = distribution.RandomVariable; var parents = dag.GetParents(rvar); // do the conditions fit with the dag structure? if (parents.Except(distribution.Conditions).Any() || parents.Count != distribution.Conditions.Count) { throw new ArgumentException($"The random variable {rvar.Name} has parents {string.Join(",", parents)} but conditions {string.Join(",", distribution.Conditions)}"); } network.Distributions[rvar] = distribution; processed[network.RandomVariables.IndexOf(rvar)] = true; // fill distributions in random variables without parents if (parents.Count == 0) { rvar.Probability = distribution.Distribution; } } if (!processed.All(p => p)) { throw new ArgumentException("The given probability distribution did not include all random variables!"); } return(network); }
/// <summary> /// Store the given BayesianNetwork in the file path of the config, if it is defined there /// </summary> private void StoreBayesianNetwork(BayesianNetwork bayesianNetwork) { if (!string.IsNullOrWhiteSpace(Config.BayesianNetworkSerializationPath)) { File.WriteAllText(Config.BayesianNetworkSerializationPath, JsonConvert.SerializeObject(bayesianNetwork, new BayesianNetworkConverter(bayesianNetwork.RandomVariables))); } }
/// <summary> /// Creates a Bayesian Network from a given DagPattern which has to be a DAG and calculates the conditional distributions according to the DAG structure. /// </summary> /// <exception cref="ArgumentException">Thrown when the given DagPattern is no DAG</exception> public static BayesianNetwork FromDagPattern(DagPattern <RandomVariable> dag, IProbabilityDistributionCalculator calc) { if (!dag.IsDag()) { throw new ArgumentException("BayesianNetworks need a DAG, but the given DAG was actually a DAG pattern!"); } var network = new BayesianNetwork(dag); foreach (var rvar in dag.Nodes) { var parents = dag.GetParents(rvar).ToList(); var distribution = calc.CalculateConditionalProbabilityDistribution(rvar, parents); network.Distributions[rvar] = new ProbabilityDistribution(rvar, parents, distribution); } return(network); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var randomVariableNames = _randomVariables.Select(rvar => rvar.Name).ToList(); var randomVariableMapping = new Dictionary <string, RandomVariable>(); foreach (var randomVariable in _randomVariables) { randomVariableMapping[randomVariable.Name] = randomVariable; } var json = JObject.Load(reader); // construct DagPattern var dag = json.Property(DagProperty); var edges = dag.Value.Value <JArray>(EdgesProperty).ToObject <int[]>(); var nodes = dag.Value.Value <JArray>(NodesProperty).ToObject <string[]>(); var realEdges = new int[nodes.Length, nodes.Length]; for (var i = 0; i < nodes.Length; i++) { for (var j = 0; j < nodes.Length; j++) { // given random variables could be in another order, so lookup the index realEdges[randomVariableNames.IndexOf(nodes[i]), randomVariableNames.IndexOf(nodes[j])] = edges[i * nodes.Length + j]; } } var dagPattern = DagPattern <RandomVariable> .InitDagWithMatrix(_randomVariables, realEdges); // construct probability distributions var distributions = json.Property(DistributionsProperty).Value.Children(); var realDistributions = new List <ProbabilityDistribution>(); foreach (var distribution in distributions) { var randomVariable = distribution.Value <string>(RandomVariableProperty); var realRandomVariable = randomVariableMapping[randomVariable]; var conditions = distribution.Value <JArray>(ConditionsProperty).ToObject <string[]>(); var realConditions = conditions.Select(condition => randomVariableMapping[condition]).ToList(); var distributionValues = distribution.Value <JArray>(DistributionProperty).ToObject <double[]>(); var realDistributionValues = distributionValues.Select(distValue => new Probability(distValue)).ToList(); realDistributions.Add(new ProbabilityDistribution(realRandomVariable, realConditions, realDistributionValues)); } return(BayesianNetwork.FromDagPattern(dagPattern, realDistributions)); }
/// <summary> /// Checks the resulting DAG for causal edges that should be included and warns if some are absent. /// </summary> private void CheckResultingNetwork(BayesianNetwork network) { const string message = "You may consider including DCCA results or using other learning algorithms."; foreach (var criticalSet in _mcsVars) { foreach (var includedFault in criticalSet.FaultVariables) { if (!network.Dag.IsDirectedEdge(includedFault, criticalSet)) { Console.Out.WriteLine($"WARNING: There was no edge from {includedFault} to {criticalSet}! {message}"); } } if (!network.Dag.IsDirectedEdge(criticalSet, _hazardVar)) { Console.Out.WriteLine($"WARNING: There was no edge from {criticalSet} to {_hazardVar}! {message}"); } } }
private BayesianNetwork ToBayesianNetwork(BayesianNetworkResult result) { var allVariables = MapToAllVariables(); var nodes = result.Nodes.Select(node => allVariables[node]).ToList(); var dag = DagPattern <RandomVariable> .InitEmptyDag(nodes); foreach (var arc in result.Arcs) { dag.AddEdge(allVariables[arc.From], allVariables[arc.To]); } var distributions = new List <ProbabilityDistribution>(); foreach (var probTable in result.ProbTables) { var rvar = allVariables[probTable.Rvar.First()]; var conditions = probTable.Conditions.Select(condition => allVariables[condition]).ToList(); var probabilities = ToProbabilityArray(probTable.Probs, conditions.Count + 1); distributions.Add(new ProbabilityDistribution(rvar, conditions, probabilities)); } return(BayesianNetwork.FromDagPattern(dag, distributions)); }
private void PrintBayesianNetwork(BayesianNetwork bayesianNetwork) { bayesianNetwork.PrintBayesianNetwork(); }
public BayesianNetworkProbabilityDistributionCalculator(BayesianNetwork network, double tolerance) { _network = network; _randomVariables = _network.RandomVariables; _tolerance = tolerance; }