DiscreteFactor#

class pgmpy.factors.discrete.DiscreteFactor(variables, cardinality, values, state_names={})[source]#

Bases: BaseFactor, StateNameMixin

Initialize a DiscreteFactor class.

Defined above, we have the following mapping from variable assignments to the index of the row vector in the value field:

x1

x2

x3

phi(x1, x2, x3)

x1_0

x2_0

x3_0

phi.value(0)

x1_0

x2_0

x3_1

phi.value(1)

x1_0

x2_1

x3_0

phi.value(2)

x1_0

x2_1

x3_1

phi.value(3)

x1_1

x2_0

x3_0

phi.value(4)

x1_1

x2_0

x3_1

phi.value(5)

x1_1

x2_1

x3_0

phi.value(6)

x1_1

x2_1

x3_1

phi.value(7)

Parameters:
variables: list, array-like

List of variables on which the factor is to be defined i.e. scope of the factor.

cardinality: list, array_like

List of cardinalities/no.of states of each variable. cardinality array must have a value corresponding to each variable in variables.

values: list, array_like

List of values of factor. A DiscreteFactor’s values are stored in a row vector in the value using an ordering such that the left-most variables as defined in variables cycle through their values the fastest. Please refer to examples for usage examples.

Examples

>>> import numpy as np
>>> from pgmpy.factors.discrete import DiscreteFactor
>>> phi = DiscreteFactor(
...     variables=["x1", "x2", "x3"], cardinality=[2, 2, 2], values=np.ones(8)
... )
>>> phi
<DiscreteFactor representing phi(x1:2, x2:2, x3:2) at 0x...>
>>> print(phi)
+-------+-------+-------+-----------------+
| x1    | x2    | x3    |   phi(x1,x2,x3) |
+=======+=======+=======+=================+
| x1(0) | x2(0) | x3(0) |          1.0000 |
+-------+-------+-------+-----------------+
| x1(0) | x2(0) | x3(1) |          1.0000 |
+-------+-------+-------+-----------------+
| x1(0) | x2(1) | x3(0) |          1.0000 |
+-------+-------+-------+-----------------+
| x1(0) | x2(1) | x3(1) |          1.0000 |
+-------+-------+-------+-----------------+
| x1(1) | x2(0) | x3(0) |          1.0000 |
+-------+-------+-------+-----------------+
| x1(1) | x2(0) | x3(1) |          1.0000 |
+-------+-------+-------+-----------------+
| x1(1) | x2(1) | x3(0) |          1.0000 |
+-------+-------+-------+-----------------+
| x1(1) | x2(1) | x3(1) |          1.0000 |
+-------+-------+-------+-----------------+
assignment(index)[source]#

Returns a list of assignments (variable and state) for the corresponding index.

Parameters:
index: list, array-like

List of indices whose assignment is to be computed

Returns:
Full assignments: list

Returns a list of full assignments of all the variables of the factor.

Examples

>>> import numpy as np
>>> from pgmpy.factors.discrete import DiscreteFactor
>>> phi = DiscreteFactor(["diff", "intel"], [2, 2], np.ones(4))
>>> phi.assignment([1, 2])
[[('diff', 0), ('intel', 1)], [('diff', 1), ('intel', 0)]]
copy()[source]#

Returns a copy of the factor.

Returns:
Copy of self: pgmpy.factors.discrete.DiscreteFactor

A copy of the original discrete factor.

Examples

>>> import numpy as np
>>> from pgmpy.factors.discrete import DiscreteFactor
>>> phi = DiscreteFactor(
...     variables=["x1", "x2", "x3"],
...     cardinality=[2, 3, 3],
...     values=np.arange(18),
... )
>>> phi_copy = phi.copy()
>>> phi_copy.variables
['x1', 'x2', 'x3']
>>> phi_copy.cardinality
array([2, 3, 3])
>>> phi_copy.values
array([[[ 0.,  1.,  2.],
        [ 3.,  4.,  5.],
        [ 6.,  7.,  8.]],

       [[ 9., 10., 11.],
        [12., 13., 14.],
        [15., 16., 17.]]])
divide(phi1, inplace=True)[source]#

DiscreteFactor division by phi1.

Parameters:
phi1DiscreteFactor instance

The denominator for division.

inplace: boolean

If inplace=True it will modify the factor itself, else would return a new factor.

Returns:
Divided factor: pgmpy.factors.discrete.DiscreteFactor or None

If inplace=True (default) returns None else returns a new DiscreteFactor instance.

Examples

>>> from pgmpy.factors.discrete import DiscreteFactor
>>> phi1 = DiscreteFactor(
...     variables=["x1", "x2", "x3"], cardinality=[2, 3, 2], values=range(12)
... )
>>> phi2 = DiscreteFactor(
...     variables=["x3", "x1"], cardinality=[2, 2], values=range(1, 5)
... )
>>> phi1.divide(phi2)
>>> phi1.variables
['x1', 'x2', 'x3']
>>> phi1.cardinality
array([2, 3, 2])
>>> phi1.values
array([[[0.        , 0.33333333],
        [2.        , 1.        ],
        [4.        , 1.66666667]],

       [[3.        , 1.75      ],
        [4.        , 2.25      ],
        [5.        , 2.75      ]]])
get_cardinality(variables)[source]#

Returns the cardinality/no.of states of each variable in variables.

Parameters:
variables: list, array-like

A list of variable names.

Returns:
Cardinality of variables: dict

Dictionary of the form {variable: variable_cardinality}

Examples

>>> from pgmpy.factors.discrete import DiscreteFactor
>>> phi = DiscreteFactor(
...     variables=["x1", "x2", "x3"], cardinality=[2, 3, 2], values=range(12)
... )
>>> {k: int(v) for k, v in phi.get_cardinality(variables=["x1"]).items()}
{'x1': 2}
>>> {k: int(v) for k, v in phi.get_cardinality(variables=["x1", "x2"]).items()}
{'x1': 2, 'x2': 3}
get_value(**kwargs)[source]#

Returns the value of the given variable states. Assumes that the arguments specified are state names, and falls back to considering it as state no if can’t find the state name.

Parameters:
kwargs: named arguments of the form variable=state_name

Spcifies the state of each of the variable for which to get the value.

Returns:
value of kwargs: float

The value of specified states.

Examples

>>> from pgmpy.example_models import load_model
>>> model = load_model("bnlearn/asia")
>>> phi = model.get_cpds(node="either").to_factor()
>>> float(phi.get_value(lung="yes", tub="no", either="yes"))
1.0
identity_factor()[source]#

Returns the identity factor.

Def: The identity factor of a factor has the same scope and cardinality as the original factor,

but the values for all the assignments is 1. When the identity factor is multiplied with the factor it returns the factor itself.

Returns:
Identity factor: pgmpy.factors.discrete.DiscreteFactor.

Returns a factor with all values set to 1.

Examples

>>> from pgmpy.factors.discrete import DiscreteFactor
>>> phi = DiscreteFactor(
...     variables=["x1", "x2", "x3"], cardinality=[2, 3, 2], values=range(12)
... )
>>> phi_identity = phi.identity_factor()
>>> phi_identity.variables
['x1', 'x2', 'x3']
>>> phi_identity.values
array([[[1., 1.],
        [1., 1.],
        [1., 1.]],

       [[1., 1.],
        [1., 1.],
        [1., 1.]]])
is_valid_cpd()[source]#

Checks if the factor’s values can be used for a valid CPD.

marginalize(variables, inplace=True)[source]#

Modifies the factor with marginalized values.

Parameters:
variables: list, array-like

List of variables over which to marginalize.

inplace: boolean

If inplace=True it will modify the factor itself, else would return a new factor.

Returns:
Marginalized factor: pgmpy.factors.discrete.DiscreteFactor or None
If inplace=True (default) returns None else returns a new DiscreteFactor instance.

Examples

>>> from pgmpy.factors.discrete import DiscreteFactor
>>> phi = DiscreteFactor(
...     variables=["x1", "x2", "x3"], cardinality=[2, 3, 2], values=range(12)
... )
>>> phi.marginalize(variables=["x1", "x3"])
>>> phi.values
array([14., 22., 30.])
>>> phi.variables
['x2']
maximize(variables, inplace=True)[source]#

Maximizes the factor with respect to variables.

Parameters:
variables: list, array-like

List of variables with respect to which factor is to be maximized

inplace: boolean

If inplace=True it will modify the factor itself, else would return a new factor.

Returns:
Maximized factor: pgmpy.factors.discrete.DiscreteFactor or None

If inplace=True (default) returns None else inplace=False returns a new DiscreteFactor instance.

Examples

>>> from pgmpy.factors.discrete import DiscreteFactor
>>> phi = DiscreteFactor(
...     variables=["x1", "x2", "x3"],
...     cardinality=[3, 2, 2],
...     values=[
...         0.25,
...         0.35,
...         0.08,
...         0.16,
...         0.05,
...         0.07,
...         0.00,
...         0.00,
...         0.15,
...         0.21,
...         0.09,
...         0.18,
...     ],
... )
>>> phi.variables
['x1', 'x2', 'x3']
>>> phi.maximize(variables=["x2"])
>>> phi.variables
['x1', 'x3']
>>> phi.cardinality
array([3, 2])
>>> phi.values
array([[0.25, 0.35],
       [0.05, 0.07],
       [0.15, 0.21]])
normalize(inplace=True)[source]#

Normalizes the values of factor so that they sum to 1.

Parameters:
inplace: boolean

If inplace=True it will modify the factor itself, else would return a new factor

Returns:
Normalized factor: pgmpy.factors.discrete.DiscreteFactor or None

If inplace=True (default) returns None else returns a new DiscreteFactor instance.

Examples

>>> from pgmpy.factors.discrete import DiscreteFactor
>>> phi = DiscreteFactor(
...     variables=["x1", "x2", "x3"], cardinality=[2, 3, 2], values=range(12)
... )
>>> phi.values
array([[[ 0.,  1.],
        [ 2.,  3.],
        [ 4.,  5.]],

       [[ 6.,  7.],
        [ 8.,  9.],
        [10., 11.]]])
>>> phi.normalize()
>>> phi.variables
['x1', 'x2', 'x3']
>>> phi.cardinality
array([2, 3, 2])
>>> phi.values
array([[[0.        , 0.01515152],
        [0.03030303, 0.04545455],
        [0.06060606, 0.07575758]],

       [[0.09090909, 0.10606061],
        [0.12121212, 0.13636364],
        [0.15151515, 0.16666667]]])
product(phi1, inplace=True)[source]#

DiscreteFactor product with phi1.

Parameters:
phi1: float or `DiscreteFactor` instance

If float, all the values are multiplied with phi1. else if DiscreteFactor instance, mutliply based on matching rows.

inplace: boolean

If inplace=True it will modify the factor itself, else would return a new factor.

Returns:
Multiplied factor: pgmpy.factors.discrete.DiscreteFactor or None

If inplace=True (default) returns None else returns a new DiscreteFactor instance.

Examples

>>> from pgmpy.factors.discrete import DiscreteFactor
>>> phi1 = DiscreteFactor(
...     variables=["x1", "x2", "x3"], cardinality=[2, 3, 2], values=range(12)
... )
>>> phi2 = DiscreteFactor(
...     variables=["x3", "x4", "x1"], cardinality=[2, 2, 2], values=range(8)
... )
>>> phi1.product(phi2, inplace=True)
>>> phi1.variables
['x1', 'x2', 'x3', 'x4']
>>> phi1.cardinality
array([2, 3, 2, 2])
>>> phi1.values
array([[[[ 0,  0],
         [ 4,  6]],
        [[ 0,  4],
         [12, 18]],
        [[ 0,  8],
         [20, 30]]],
       [[[ 6, 18],
         [35, 49]],
        [[ 8, 24],
         [45, 63]],
        [[10, 30],
         [55, 77]]]]
reduce(values, inplace=True, show_warnings=True)[source]#

Reduces the factor to the context of given variable values. The variables which are reduced would be removed from the factor.

Parameters:
values: list, array-like

A list of tuples of the form (variable_name, variable_state).

inplace: boolean

If inplace=True it will modify the factor itself, else would return a new factor.

show_warnings: boolean

Whether to show warning when state name not found.

Returns:
Reduced factor: pgmpy.factors.discrete.DiscreteFactor or None

If inplace=True (default) returns None else returns a new DiscreteFactor instance.

Examples

>>> from pgmpy.factors.discrete import DiscreteFactor
>>> phi = DiscreteFactor(
...     variables=["x1", "x2", "x3"], cardinality=[2, 3, 2], values=range(12)
... )
>>> phi.reduce(values=[("x1", 0), ("x2", 0)])
>>> phi.variables
['x3']
>>> phi.cardinality
array([2])
>>> phi.values
array([0., 1.])
sample(n, seed=None)[source]#

Normalizes the factor and samples state combinations from it.

Parameters:
n: int

Number of samples to generate.

seed: int (default: None)

The seed value for the random number generator.

Examples

>>> from pgmpy.factors.discrete import DiscreteFactor
>>> phi1 = DiscreteFactor(
...     variables=["x1", "x2", "x3"], cardinality=[2, 3, 2], values=range(12)
... )
>>> phi1.sample(n=5)
    x1  x2  x3
0   1   2   1
1   1   0   0
2   1   0   1
3   1   1   1
4   1   2   0
scope()[source]#

Returns the scope of the factor i.e. the variables on which the factor is defined.

Returns:
Scope of the factor: list

List of variables on which the factor is defined.

Examples

>>> from pgmpy.factors.discrete import DiscreteFactor
>>> phi = DiscreteFactor(
...     variables=["x1", "x2", "x3"], cardinality=[2, 3, 2], values=np.ones(12)
... )
>>> phi.scope()
['x1', 'x2', 'x3']
set_value(value, **kwargs)[source]#

Sets the probability value of the given variable states.

Parameters:
value: float

The value for the specified state.

kwargs: named arguments of the form variable=state_name

Spcifies the state of each of the variable for which to get the probability value.

Returns:
None

Examples

>>> from pgmpy.example_models import load_model
>>> model = load_model("bnlearn/asia")
>>> phi = model.get_cpds(node="either").to_factor()
>>> phi.set_value(value=0.1, lung="yes", tub="no", either="yes")
>>> float(phi.get_value(lung="yes", tub="no", either="yes"))
0.1
sum(phi1, inplace=True)[source]#

DiscreteFactor sum with phi1.

Parameters:
phi1: float or `DiscreteFactor` instance.

If float, the value is added to each value in the factor. DiscreteFactor to be added.

inplace: boolean

If inplace=True it will modify the factor itself, else would return a new factor.

Returns:
Summed factor: pgmpy.factors.discrete.DiscreteFactor or None

If inplace=True (default) returns None else returns a new DiscreteFactor instance.

Examples

>>> from pgmpy.factors.discrete import DiscreteFactor
>>> phi1 = DiscreteFactor(
...     variables=["x1", "x2", "x3"], cardinality=[2, 3, 2], values=range(12)
... )
>>> phi2 = DiscreteFactor(
...     variables=["x3", "x4", "x1"], cardinality=[2, 2, 2], values=range(8)
... )
>>> phi1.sum(phi2, inplace=True)
>>> phi1.variables
['x1', 'x2', 'x3', 'x4']
>>> phi1.cardinality
array([2, 3, 2, 2])
>>> phi1.values
array([[[[ 0.,  2.],
         [ 5.,  7.]],

        [[ 2.,  4.],
         [ 7.,  9.]],

        [[ 4.,  6.],
         [ 9., 11.]]],


       [[[ 7.,  9.],
         [12., 14.]],

        [[ 9., 11.],
         [14., 16.]],

        [[11., 13.],
         [16., 18.]]]])