pgmpy / pgmpy

Python Library for learning (Structure and Parameter), inference (Probabilistic and Causal), and simulations in Bayesian Networks.
https://pgmpy.org/
MIT License
2.72k stars 702 forks source link

Key Error in MPLP Inference over Markov Network #1738

Open superctj opened 7 months ago

superctj commented 7 months ago

Subject of the issue

Hi, thank you for open-sourcing this great library, which is very valuable to my project! I was running MPLP approximate inference for a Markov Network and had a key error. My Markov network consists of unary factors (factors over single nodes) and ternary factors (factors over a clique of three nodes). I found the problem is caused by the default setting of tighten_triplet=True in the map_query method. If I set it to False then the algorithm runs to complete.

Your environment

Steps to reproduce

Tell us how to reproduce this issue. Please provide a minimal reproducible code of the issue you are facing if possible.

from itertools import combinations

from pgmpy.factors.discrete import DiscreteFactor
from pgmpy.inference import Mplp
from pgmpy.models import MarkovNetwork

UNARY_TABLE = [0.5, 0.5]
TERNARY_TABLE = [1, 1, 1, 0, 1, 0, 0, 1]

def test_mplp_inference():
    mrf = MarkovNetwork()

    # Add variables and unary factors
    variable_names = ["R_1-2", "R_1-3", "R_1-4", "R_2-3", "R_2-4", "R_3-4"]

    for var_name in variable_names:
        mrf.add_node(var_name)

        unary_factor = DiscreteFactor(
            [var_name], cardinality=[2], values=UNARY_TABLE
        )
        mrf.add_factors(unary_factor)

    # Add ternary factors
    ternary_combos = combinations(range(1, 5), 3)

    for combo in ternary_combos:
        var1 = f"R_{combo[0]}-{combo[1]}"
        var2 = f"R_{combo[0]}-{combo[2]}"
        var3 = f"R_{combo[1]}-{combo[2]}"

        mrf.add_edges_from([(var1, var2), (var1, var3), (var2, var3)])
        ternary_factor = DiscreteFactor(
            [var1, var2, var3], cardinality=[2, 2, 2], values=TERNARY_TABLE
        )
        ternary_factor.normalize()

        mrf.add_factors(ternary_factor)

    mplp = Mplp(mrf)
    results = mplp.map_query()
    print(results)    

Expected behaviour

No error.

Actual behavior

Traceback (most recent call last): File "/home/congtj/openforge/openforge/mrf_inference_mplp.py", line 164, in results = mplp.map_query(tighten_triplet=True) File "/home/congtj/miniconda3/envs/openforge/lib/python3.10/site-packages/pgmpy/inference/mplp.py", line 580, in map_query self._tighten_triplet(max_iterations, later_iter, max_triplets, prolong) File "/home/congtj/miniconda3/envs/openforge/lib/python3.10/site-packages/pgmpy/inference/mplp.py", line 446, in _tighten_triplet triplet_scores = self._get_triplet_scores(triangles) File "/home/congtj/miniconda3/envs/openforge/lib/python3.10/site-packages/pgmpy/inference/mplp.py", line 383, in _get_triplet_scores [ File "/home/congtj/miniconda3/envs/openforge/lib/python3.10/site-packages/pgmpy/inference/mplp.py", line 384, in np.amax(self.objective[frozenset(intersect)].values) KeyError: frozenset({'R_2-14', 'R_10-14'})

I was also wondering if it is possible to plug in evidence to MPLP inference like in query method of Belief Propagation. Thanks!

ankurankan commented 7 months ago

@superctj Thanks for reporting the issue. I had a quick look at it but I am unsure what is causing this. I will try to dig deeper and update here.