Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DBNInference ValueError: Self loops are not allowed #1364

Closed
576774572 opened this issue Dec 22, 2020 · 4 comments · Fixed by #1447 or #1454
Closed

DBNInference ValueError: Self loops are not allowed #1364

576774572 opened this issue Dec 22, 2020 · 4 comments · Fixed by #1447 or #1454
Assignees

Comments

@576774572
Copy link

576774572 commented Dec 22, 2020

Hi!
when I try to construct model with DBN like this:

20201222145647

from pgmpy.models import DynamicBayesianNetwork as DBN
from pgmpy.factors.discrete import TabularCPD
from pgmpy.inference import DBNInference
dbn = DBN()
dbn.add_edges_from([(('a', 0),('b', 0)),(('a', 0),('a', 1)), (('a', 0),('b', 1))])
a_0=TabularCPD(('a', 0), 2, [[0.5],[0.5]])
b_0=TabularCPD(('b', 0), 2, [[0.3,0.7],[0.7,0.3]],[('a',0)],[2])
a_1=TabularCPD(('a', 1), 2, [[0.3,0.7],[0.7,0.3]],[('a',0)],[2])
dbn.add_cpds(a_0, b_0, a_1)
dbn_inf = DBNInference(dbn)

But when I execute the code I get this error:

File "C:\users\a5767\appdata\local\programs\python\python36\lib\site-packages\pgmpy\models\untitled9.py", line 25, in <module> dbn_inf = DBNInference(dbn)
File "c:\users\a5767\appdata\local\programs\python\python36\lib\site-packages\pgmpy\inference\dbn_inference.py", line 70, in __init__ start_markov_model.add_edges_from(combinations_slice_0[0])
File "c:\users\a5767\appdata\local\programs\python\python36\lib\site-packages\pgmpy\base\UndirectedGraph.py", line 252, in add_edges_from self.add_edge(edge[0], edge[1])
File "c:\users\a5767\appdata\local\programs\python\python36\lib\site-packages\pgmpy\models\MarkovModel.py", line 105, in add_edge raise ValueError("Self loops are not allowed")
ValueError: Self loops are not allowed

Thank you very much for someone who can help me with this error.

@FelipeGiro
Copy link
Contributor

I think I got the problem.

The issue is related to the function get_interference_nodes of DynamicBayesianNetwork model.

If we run dbn.get_inter_edges() you get [(a_0, a_1), (a_0, b_1)].Which is in, fact, correct. Although, when using dbn.get_interface_nodes(0) and dbn.get_interface_nodes(0), we get [a_0, a_0] and [a_1, a_1], and then the program accuses wrongly a self loop.

Going in deep to get_interference_nodes return value:

[DynamicNode(edge[0][0], time_slice) for edge in self.get_inter_edges()]

It gets the first letter of the first node of a edge and attach the input time_slice. This can work well when the edges are "parallels" (for example [(D_0, D_1), (I_0, I_1)], resulting in [D_0, I_0] and [D_1, I_1]), but not when you have the interception starting from the same node.

One possible solution is to set the inputs of DynamicNode directly from edge.

@FelipeGiro
Copy link
Contributor

@576774572 Keep in mind that perhaps your model is not completely correct, despite the bug. I would say that it would be more correct like this:

dbn = DBN()
dbn.add_edges_from([(('a', 0),('a', 1)), (('a', 0),('b', 1)), (('a', 1),('b', 1)), (('a', 0),('b', 0))])
a_0=TabularCPD(('a', 0), 2, [[0.5],[0.5]])
a_1=TabularCPD(('a', 1), 2, [[0.3,0.7],[0.7,0.3]],[('a',0)],[2])
b_0=TabularCPD(('b', 0), 2, [[0.3,0.7],[0.7,0.3]],[('a',0)],[2])
b_1=TabularCPD(('b', 1), 2, [[0.9,0.5,0.9,0.7],[0.1,0.5,0.1,0.3]],
               [('a',0), ('a',1)],[2,2])

dbn.add_cpds(a_0, a_1, b_0, b_1)

Because first, all 4 nodes in all time slices are represented by a CPD; second, all 4 edges are represented; and third, the CDP of b_1 receive two edges, from a_0 and a_1, having a "longer" table.

@FelipeGiro FelipeGiro mentioned this issue Jul 30, 2021
3 tasks
@ankurankan ankurankan reopened this Aug 7, 2021
@ankurankan
Copy link
Member

This doesn't seem to be fixed yet. Another example:

import numpy as np
from scipy.special import softmax
from pgmpy.models import DynamicBayesianNetwork
from pgmpy.inference import DBNInference
from pgmpy.factors.discrete import TabularCPD

edges=[
( ('A', 0) , ('A', 1) ),
( ('A', 0) , ('B', 1) ),
( ('B', 0) , ('A', 1) ),
( ('B', 0) , ('B', 1) ),
( ('L', 0) , ('A', 0) ),
( ('L', 0) , ('B', 0) ),
( ('L', 0) , ('L', 1) ),
( ('L', 1) , ('A', 1) ),
( ('L', 1) , ('B', 1) ),
]

bnet=DynamicBayesianNetwork(edges)#, latents=set('L'))

bnet_cpds = []
bnet_cpds.append(
    TabularCPD(('A',0), 2, softmax(np.ones((2,2)), axis=0), evidence=[('L', 0)], evidence_card=[2]))
bnet_cpds.append(
    TabularCPD(('B',0), 2, softmax(np.ones((2,2)), axis=0), evidence=[('L', 0)], evidence_card=[2]))
bnet_cpds.append(
    TabularCPD(('L',0), 2, softmax(np.ones((2,1)), axis=0)))
bnet_cpds.append(
    TabularCPD(('A', 1), 2, softmax(np.ones((2,8)), axis=0), evidence=[('A', 0), ('B', 0), ('L', 1)], evidence_card=[2,2,2]))
bnet_cpds.append(
    TabularCPD(('B', 1), 2, softmax(np.ones((2,8)), axis=0), evidence=[('A', 0), ('B', 0), ('L', 1)], evidence_card=[2,2,2]))
bnet_cpds.append(
    TabularCPD(('L',1), 2, softmax(np.ones((2,2)), axis=0), evidence=[('L', 0)], evidence_card=[2]))

bnet.add_cpds(*bnet_cpds)

ie=DBNInference(bnet)
# Error: Self loops are not allowed

@FelipeGiro
Copy link
Contributor

Ok, my tests were not so good to check the networks.

I think the issue is linked to this part, specially with combinations_slice_0 and combinations_slice_1.

combinations_slice_0 = tee(combinations(self.interface_nodes_0, 2), 2)
combinations_slice_1 = combinations(self.interface_nodes_1, 2)
start_markov_model.add_edges_from(combinations_slice_0[0])
one_and_half_markov_model.add_edges_from(
chain(combinations_slice_0[1], combinations_slice_1)
)

@ankurankan You can assign me to this issue to remember me to solve it in the following weeks, if you want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants