/// <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);
        }
Exemple #2
0
        /// <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)));
     }
 }
Exemple #4
0
        /// <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);
        }
Exemple #5
0
        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;
 }