FunctionalCPD#

class pgmpy.factors.hybrid.FunctionalCPD(variable, fn, parents=[], vectorized=False)[source]#

Bases: BaseFactor

Defines a Functional CPD.

Functional CPD can represent any arbitrary conditional probability distribution where the distribution to represented is defined by function (input as parameter) which calls pyro.sample function.

Parameters:
variable: str

Name of the variable for which this CPD is defined.

fn: callable

A lambda function that takes a dictionary of parent variable values and returns a sampled value for the variable by calling pyro.sample.

parents: list[str], optional

List of parent variable names (default is None for no parents).

Examples

# For P(X3| X1, X2) = N(0.2x1 + 0.3x2 + 1.0; 1), we can write

>>> from pgmpy.factors.hybrid import FunctionalCPD
>>> import pyro.distributions as dist
>>> cpd = FunctionalCPD(
...     variable="x3",
...     fn=lambda parent_sample: dist.Normal(
...         0.2 * parent_sample["x1"] + 0.3 * parent_sample["x2"] + 1.0, 1
...     ),
...     parents=["x1", "x2"],
... )
>>> cpd.variable
'x3'
>>> cpd.parents
['x1', 'x2']
sample(n_samples=100, parent_sample=None)[source]#

Simulates a value for the variable based on its CPD.

Parameters:
n_samples: int, (default: 100)

The number of samples to generate.

parent_sample: pandas.DataFrame, optional

A DataFrame where each column represents a parent variable and rows are samples.

Returns:
sampled_values: numpy.ndarray

Array of sampled values for the variable.

Examples

>>> import torch
>>> from pgmpy.factors.hybrid import FunctionalCPD
>>> import pyro.distributions as dist
>>> seed_generator = torch.manual_seed(42)
>>> cpd = FunctionalCPD(
...     variable="x3",
...     fn=lambda parent_sample: dist.Normal(
...         1.0 + 0.2 * parent_sample["x1"] + 0.3 * parent_sample["x2"], 1
...     ),
...     parents=["x1", "x2"],
... )
>>> parent_samples = pd.DataFrame({"x1": [5, 10], "x2": [1, -1]})
>>> cpd.sample(2, parent_samples)
array([2.63669038, 2.8288095 ])