causalnex.network.BayesianNetwork¶
-
class
causalnex.network.
BayesianNetwork
(structure)[source]¶ Bases:
object
Base class for Bayesian Network (BN), a probabilistic weighted DAG where nodes represent variables, edges represent the causal relationships between variables.
BayesianNetwork
stores nodes with their possible states, edges and conditional probability distributions (CPDs) of each node.BayesianNetwork
is built on top of theStructureModel
, which is an extension ofnetworkx.DiGraph
(seecausalnex.structure.structuremodel.StructureModel()
).In order to define the
BayesianNetwork
, users should provide a relevantStructureModel
. OnceBayesianNetwork
is initialised, no changes to theStructureModel
can be made and CPDs can be learned from the data.The learned CPDs can be then used for likelihood estimation and predictions.
Example:
# Create a Bayesian Network with a manually defined DAG. from causalnex.structure import StructureModel from causalnex.network import BayesianNetwork sm = StructureModel() sm.add_edges_from([ ('rush_hour', 'traffic'), ('weather', 'traffic') ]) bn = BayesianNetwork(sm) # A created ``BayesianNetwork`` stores nodes and edges defined by the ``StructureModel`` bn.nodes ['rush_hour', 'traffic', 'weather'] bn.edges [('rush_hour', 'traffic'), ('weather', 'traffic')] # A ``BayesianNetwork`` doesn't store any CPDs yet bn.cpds {} # Learn the nodes' states from the data import pandas as pd data = pd.DataFrame({ 'rush_hour': [True, False, False, False, True, False, True], 'weather': ['Terrible', 'Good', 'Bad', 'Good', 'Bad', 'Bad', 'Good'], 'traffic': ['heavy', 'light', 'heavy', 'light', 'heavy', 'heavy', 'heavy'] }) bn = bn.fit_node_states(data) bn.node_states {'rush_hour': {False, True}, 'weather': {'Bad', 'Good', 'Terrible'}, 'traffic': {'heavy', 'light'}} # Learn the CPDs from the data bn = bn.fit_cpds(data) # Use the learned CPDs to make predictions on the unseen data test_data = pd.DataFrame({ 'rush_hour': [False, False, True, True], 'weather': ['Good', 'Bad', 'Good', 'Bad'] }) bn.predict(test_data, "traffic").to_dict() {'traffic_prediction': {0: 'light', 1: 'heavy', 2: 'heavy', 3: 'heavy'}} bn.predict_probability(test_data, "traffic").to_dict() {'traffic_prediction': {0: 'light', 1: 'heavy', 2: 'heavy', 3: 'heavy'}} {'traffic_light': {0: 0.75, 1: 0.25, 2: 0.3333333333333333, 3: 0.3333333333333333}, 'traffic_heavy': {0: 0.25, 1: 0.75, 2: 0.6666666666666666, 3: 0.6666666666666666}}
Attributes
Conditional Probability Distributions of each node within the Bayesian Network.
List of all edges contained within the Bayesian Network, as a Tuple(from_node, to_node).
Dictionary of all states that each node can take.
List of all nodes contained within the Bayesian Network.
StructureModel
defining the DAG of the Bayesian Network.Methods
BayesianNetwork.__delattr__
(name, /)Implement delattr(self, name).
BayesianNetwork.__dir__
()Default dir() implementation.
BayesianNetwork.__eq__
(value, /)Return self==value.
BayesianNetwork.__format__
(format_spec, /)Default object formatter.
BayesianNetwork.__ge__
(value, /)Return self>=value.
BayesianNetwork.__getattribute__
(name, /)Return getattr(self, name).
BayesianNetwork.__gt__
(value, /)Return self>value.
BayesianNetwork.__hash__
()Return hash(self).
BayesianNetwork.__init__
(structure)Create a
BayesianNetwork
with a DAG defined byStructureModel
.BayesianNetwork.__init_subclass__
This method is called when a class is subclassed.
BayesianNetwork.__le__
(value, /)Return self<=value.
BayesianNetwork.__lt__
(value, /)Return self<value.
BayesianNetwork.__ne__
(value, /)Return self!=value.
BayesianNetwork.__new__
(**kwargs)Create and return a new object.
BayesianNetwork.__reduce__
()Helper for pickle.
BayesianNetwork.__reduce_ex__
(protocol, /)Helper for pickle.
BayesianNetwork.__repr__
()Return repr(self).
BayesianNetwork.__setattr__
(name, value, /)Implement setattr(self, name, value).
BayesianNetwork.__sizeof__
()Size of object in memory, in bytes.
BayesianNetwork.__str__
()Return str(self).
BayesianNetwork.__subclasshook__
Abstract classes can override this to customize issubclass().
BayesianNetwork._predict_from_complete_data
(…)Predict state of node given all parents of node exist within data.
BayesianNetwork._predict_from_incomplete_data
(…)Predict state of node when some parents of node do not exist within data.
BayesianNetwork._predict_probability_from_complete_data
(…)Predict the probability of each possible state of a node, based on some input data.
BayesianNetwork._predict_probability_from_incomplete_data
(…)Predict the probability of each possible state of a node, based on some input data.
BayesianNetwork._state_to_index
(df[, nodes])Transforms all values in df to an integer, as defined by the mapping from fit_node_states.
BayesianNetwork.add_node
(node, edges_to_add, …)Adding a latent variable to the structure model, as well as its corresponding edges
BayesianNetwork.fit_cpds
(data[, method, …])Learn conditional probability distributions for all nodes in the Bayesian Network, conditioned on their incoming edges (parents).
BayesianNetwork.fit_latent_cpds
(lv_name, …)This runs the EM algorithm to estimate the CPDs of latent variables and their corresponding Markov blanket
Fit all states of nodes that can appear in the data.
Call fit_node_states and then fit_cpds.
BayesianNetwork.predict
(data, node)Predict the state of a node based on some input data, using the Bayesian Network.
BayesianNetwork.predict_probability
(data, node)Predict the probability of each possible state of a node, based on some input data.
BayesianNetwork.set_cpd
(node, df)Provide self-defined CPD to Bayesian Network
-
__init__
(structure)[source]¶ Create a
BayesianNetwork
with a DAG defined byStructureModel
.- Parameters
structure (
StructureModel
) –a graph representing a causal relationship between variables. In the structure
cycles are not allowed;
multiple (parallel) edges are not allowed;
isolated nodes and multiple components are not allowed.
- Raises
ValueError – If the structure is not a connected DAG.
-
add_node
(node, edges_to_add, edges_to_remove)[source]¶ Adding a latent variable to the structure model, as well as its corresponding edges
- Parameters
node (
str
) – Name of the nodeedges_to_add (
List
[Tuple
[str
,str
]]) – which edges to add to the structureedges_to_remove (
List
[Tuple
[str
,str
]]) – which edges to remove from the structure
- Return type
BayesianNetwork
- Returns
self
- Raises
ValueError – If lv_name exists in the network or if edges_to_add include edges NOT containing the latent variable or if edges_to_remove include edges containing the latent variable
-
property
cpds
¶ Conditional Probability Distributions of each node within the Bayesian Network.
The row-index of each dataframe is all possible states for the node. The col-index of each dataframe is a MultiIndex that describes all possible permutations of parent states.
For example, for a node \(P(A | B, D)\), where .. math:
- A \in \text{{"a", "b", "c", "d"}} - B \in \text{{"x", "y", "z"}} - C \in \text{{False, True}} b x y z d False True False True False True a a 0.265306 0.214286 0.066667 0.25 0.444444 0.000000 b 0.183673 0.214286 0.200000 0.25 0.222222 0.666667 c 0.285714 0.285714 0.400000 0.25 0.333333 0.333333 d 0.265306 0.285714 0.333333 0.25 0.000000 0.000000
- Return type
Dict
[str
,DataFrame
]- Returns
Conditional Probability Distributions of each node within the Bayesian Network.
-
property
edges
¶ List of all edges contained within the Bayesian Network, as a Tuple(from_node, to_node).
- Return type
List
[Tuple
[str
,str
]]- Returns
A list of all edges.
-
fit_cpds
(data, method='MaximumLikelihoodEstimator', bayes_prior=None, equivalent_sample_size=None)[source]¶ Learn conditional probability distributions for all nodes in the Bayesian Network, conditioned on their incoming edges (parents).
- Parameters
data (
DataFrame
) – dataframe containing one column per node in the Bayesian Network.method (
str
) – how to fit probabilities. One of: - “MaximumLikelihoodEstimator”: fit probabilities using Maximum Likelihood Estimation; - “BayesianEstimator”: fit probabilities using Bayesian Parameter Estimation. Use bayes_prior.bayes_prior (
Optional
[str
]) –how to construct the Bayesian prior used by method=”BayesianEstimator”. One of: - “K2”: shorthand for dirichlet where all pseudo_counts are 1
regardless of variable cardinality;
- ”BDeu”: equivalent of using Dirichlet and using uniform ‘pseudo_counts’ of
equivalent_sample_size / (node_cardinality * np.prod(parents_cardinalities)) for each node. Use equivelant_sample_size.
equivalent_sample_size (
Optional
[int
]) – used by BDeu bayes_prior to compute pseudo_counts.
- Return type
BayesianNetwork
- Returns
self
- Raises
ValueError – if an invalid method or bayes_prior is specified.
-
fit_latent_cpds
(lv_name, lv_states, data, box_constraints=None, priors=None, initial_params='random', non_missing_data_factor=1, n_runs=20, stopping_delta=0.0)[source]¶ This runs the EM algorithm to estimate the CPDs of latent variables and their corresponding Markov blanket
- Parameters
lv_name (
str
) – Latent variable namelv_states (
List
) – the states the LV can assumedata (
DataFrame
) – dataframe, must contain all variables in the Markov Blanket of the latent variable. Include one column with the latent variable name, filled with np.nan for missing info about LV. If some data is present about the LV, create complete columns.n_runs (
int
) – max number of EM alternationsstopping_delta (
float
) – if max difference in current - last iteration CPDS < stopping_delta => convergence reachedinitial_params (
Union
[str
,Dict
[str
,DataFrame
]]) – way to initialise parameters. Can be: - “random”: random values (default) - “avg”: uniform distributions everywhere. Not advised, as it may be the a stationary point on itself - if provide a dictionary of dataframes, this will be used as the initialisationbox_constraints (
Optional
[Dict
[str
,Tuple
[DataFrame
,DataFrame
]]]) – minimum and maximum values for each model parameter. Specified with a dictionary mapping: - Node - two dataframes, in order: Min(P(Node|Par(Node))) and Max(P(Node|Par(Node)))priors (
Optional
[Dict
[str
,DataFrame
]]) – priors, provided as a mapping Node -> dataframe with Dirichilet priors for P(Node|Par(Node))non_missing_data_factor (
int
) – This is a weight added to the non-missing data samples. The effect is as if the amount of data provided was bigger. Empirically, helps to set the factor to 10 if the non missing data is ~1% of the dataset
- Return type
BayesianNetwork
- Returns
self
- Raises
ValueError – if the latent variable is not a string or if the latent variable cannot be found in the network or if the latent variable is present/observed in the data if the latent variable states are empty if additional non-lv nodes are added to the subgraph without being fit
-
fit_node_states
(df)[source]¶ Fit all states of nodes that can appear in the data. The dataframe provided should contain every possible state (values that can be taken) for every column.
- Parameters
df (
DataFrame
) – data to fit node states from. Each column indicates a node and each row an observed combination of states.- Return type
BayesianNetwork
- Returns
self
- Raises
ValueError – if dataframe contains any missing data.
-
fit_node_states_and_cpds
(data, method='MaximumLikelihoodEstimator', bayes_prior=None, equivalent_sample_size=None)[source]¶ Call fit_node_states and then fit_cpds.
- Parameters
data (
DataFrame
) – dataframe containing one column per node in the Bayesian Network.method (
str
) – how to fit probabilities. One of: - “MaximumLikelihoodEstimator”: fit probabilities using Maximum Likelihood Estimation; - “BayesianEstimator”: fit probabilities using Bayesian Parameter Estimation. Use bayes_prior.bayes_prior (
Optional
[str
]) –how to construct the Bayesian prior used by method=”BayesianEstimator”. One of: - “K2”: shorthand for dirichlet where all pseudo_counts are 1
regardless of variable cardinality;
- ”BDeu”: equivalent of using dirichlet and using uniform ‘pseudo_counts’ of
equivalent_sample_size / (node_cardinality * np.prod(parents_cardinalities)) for each node. Use equivelant_sample_size.
equivalent_sample_size (
Optional
[int
]) – used by BDeu bayes_prior to compute pseudo_counts.
- Return type
BayesianNetwork
- Returns
self
-
property
node_states
¶ Dictionary of all states that each node can take.
- Returns
{node: state}`.
- Return type
A dictionary of node and its possible states, in format of `dict
-
property
nodes
¶ List of all nodes contained within the Bayesian Network.
- Return type
List
[str
]- Returns
A list of node names.
-
predict
(data, node)[source]¶ Predict the state of a node based on some input data, using the Bayesian Network.
- Parameters
data (
DataFrame
) – data to make prediction.node (
str
) – the node to predict.
- Return type
DataFrame
- Returns
A dataframe of predictions, containing a single column name {node}_prediction.
-
predict_probability
(data, node)[source]¶ Predict the probability of each possible state of a node, based on some input data.
- Parameters
data (
DataFrame
) – data to make prediction.node (
str
) – the node to predict probabilities.
- Return type
DataFrame
- Returns
A dataframe of predicted probabilities, contained one column per possible state, named {node}_{state}.
-
set_cpd
(node, df)[source]¶ Provide self-defined CPD to Bayesian Network
- Parameters
node (
str
) – the node to add self-defined cpd.df (
DataFrame
) – self-defined cpd in pandas DataFrame format.
- Return type
BayesianNetwork
- Returns
self
- Raises
IndexError – if the index names of the pandas DataFrame does not match the expected DataFrame.
ValueError – if node does not exist in Bayesian Network or a bad cpd table is provided.
-
property
structure
¶ StructureModel
defining the DAG of the Bayesian Network.- Return type
StructureModel
- Returns
A
StructureModel
of the Bayesian Network.
-