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 error with cardinality of variable #877

Open
Fenix0817 opened this issue Apr 22, 2017 · 5 comments
Open

DBNInference error with cardinality of variable #877

Fenix0817 opened this issue Apr 22, 2017 · 5 comments
Projects

Comments

@Fenix0817
Copy link

Fenix0817 commented Apr 22, 2017

Hi @ankurankan,

I want to take advantage of the opportunity to thank you for this excellent tool.

Nowadays, I am implementing DBN on a project and I am using this model:

dbn = DBN()
dbn.add_nodes_from(['A', 'B', 'C'])
dbn.add_edges_from([(('B', 0), ('A', 0)), (('C', 0), ('B', 0)), (('C', 0), ('A', 0)), 
                    (('C', 0), ('C', 1))])

C_cpd = TabularCPD(('C', 0), 3, [[0.0714286, 0.307143, 0.621429]])

A_cpd = TabularCPD(('A', 0), 2, [[0.5, 0.0, 1.0, 0.0, 0.456140350877, 0.5],
                                 [0.5, 1.0, 0.0, 1.0, 0.543859649123, 0.5]],
                   evidence=[('C', 0),('B', 0)],
                   evidence_card=[3,2])

B_cpd = TabularCPD(('B', 0), 2, [[0.0, 0.219512195122, 1.0],
                                 [1.0, 0.780487804878, 0.0]],
                   evidence=[('C', 0)],
                   evidence_card=[3])

C1_cpd = TabularCPD(('C', 1), 3, [[0.1, 0.0813953488372, 0.0862068965517],
                                  [0.3, 0.279069767442, 0.241379310345],
                                  [0.6, 0.639534883721, 0.672413793103]],
                    evidence=[('C', 0)],
                    evidence_card=[3])

dbn.add_cpds(C_cpd, A_cpd, B_cpd, C1_cpd)
dbn.check_model()                     
dbn.initialize_initial_state()
dbn_inf = DBNInference(dbn)

But, when I execute the code I obtain this message:

.../DBN/pgmpy/models/MarkovModel.pyc in check_model(self)
225 if cardinalities[variable] != cardinality:
226 raise ValueError(
--> 227 'Cardinality of variable {var} not matching among factors'.format(var=variable))
228 for var1, var2 in itertools.combinations(factor.variables, 2):
229 if var2 not in self.neighbors(var1):

ValueError: Cardinality of variable ('C', 1) not matching among factors.

I obtained the CPD of the variable ('C', 1) using:

cpd_C_1 = MaximumLikelihoodEstimator(inter_model_C, loDBN).estimate_cpd('C_1')
print cpd_C_1
C C(0) C(1) C(2)
C_1(0) 0.1 0.0813953488372 0.0862068965517
C_1(1) 0.3 0.279069767442 0.241379310345
C_1(2) 0.6 0.639534883721 0.672413793103

and the cardinality of this variable is equal:

cpd_C_1.cardinality 
array([3, 3])

Please, can you help me with this error?

Regards.

@ankurankan
Copy link
Member

@Fenix0817 Sorry for the late reply. I just tried to run your code and am also getting the same error. Though I haven't been able to figure out the exact issue yet. I will dig deeper and get back.

Thanks for reporting the issue.

@Fenix0817
Copy link
Author

Fenix0817 commented May 4, 2017 via email

@ankurankan ankurankan added this to Urgent in GSoC 2018 Sep 28, 2017
@lohani2280
Copy link
Contributor

lohani2280 commented Oct 26, 2017

@ankurankan I ran the same code and got the same error.Moreover, if you run the same code repetitively then sometimes the error doesn't appear. After digging deeper into it , i think i found the bug.
The bug is actually here https://github.com/pgmpy/pgmpy/blob/dev/pgmpy/models/DynamicBayesianNetwork.py#L515
When we call initialize_initial_state method, it creates 2 variables parents and evidence_card .
The value of parents is created by calling self.get_parents(temp_var) .

Now if we look into the get_parents method of DirectedGraph then it returns a list of parents of the queried node by calling predecessors method of nx.Digraph over the queried node. This returns a list which is unordered with respect to our need and that's why sometimes we get to see the error.

For example,

  1. Following are the values we get internally when we get no error -
    temp_var :: ('A', 1)
    parents :: [('B', 1), ('C', 1)]
    evidence_card = cpd.cardinality[:0:-1] :: [2 3]

We see evidence_card which is cardinality of evidences(parents here) is [2,3]. Thus, ('B',1) has cardinality 2 and ('C',1) has cardinality 3. That's why check_model doesn't throw any error in this case.

  1. Following are the values we get internally when we get error-
    temp_var :: ('A', 1)
    parents :: [('C', 1), ('B', 1)]
    evidence_card = cpd.cardinality[:0:-1] :: [2 3]

If you agree then i will try to send a PR soon .

@ankurankan
Copy link
Member

@lohani2280 Great, these are the hardest bugs to find. Please go ahead and send a PR.

@lohani2280
Copy link
Contributor

@ankurankan Thank you . I will send the PR ASAP.

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

No branches or pull requests

3 participants