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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

DynamicBayesianNetwork.py: Added get_cardinality method #924

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from

Conversation

lohani2280
Copy link
Contributor

@lohani2280 lohani2280 commented Oct 27, 2017

closes #921

Your checklist for this pull request

馃毃Please review the guidelines for contributing to this repository.

  • Make sure you are requesting to pull a topic/feature/bugfix branch (right side). Don't request your master!
  • Make sure you are making a pull request against the dev branch (left side). Also you should start your branch off our dev.
  • Check the commit's or even all commits' message styles matches our requested structure.
  • Check your code additions will fail neither code linting checks nor unit test.

Fixes #921

Changes

Added get_cardinality method in DynamicBayesianNetwork class and the corresponding test cases.

馃挃Thank you!

if node not in super(DynamicBayesianNetwork, self).nodes():
raise ValueError('Node not present in the model.')
else:
temp_node = (node[0], 1 - node[1]) if node[1] else node
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lohani2280 I am unable to understand why you are using 1 - node[1]. Could you please explain a bit ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ankurankan

        >>> from pgmpy.models import DynamicBayesianNetwork as DBN
        >>> from pgmpy.factors.discrete import TabularCPD
        >>> dbn = DBN()
        >>> dbn.add_edges_from([(('D',0),('G',0)),(('I',0),('G',0)),(('D',0),('D',1)),(('I',0),('I',1))])
        >>> grade_cpd =  TabularCPD(('G',0), 3, [[0.3,0.05,0.9,0.5],
        ...                                      [0.4,0.25,0.8,0.03],
        ...                                      [0.3,0.7,0.02,0.2]], [('I', 0),('D', 0)],[2,2])
        >>> dbn.add_cpds(grade_cpd)

In DBN the cardinality of the node will be same at every time slice. Now, If the node queried using get_cardinality is in time slice = 0 then temp_node = node. However, if the queried node is not in time slice 0 then using 1-node[1] ,i brought it to time slice 0 and then proceed to output the cardinality of the queired node at time slice =0.

For example -
If dbn.get_cardinality(('D',1)) is called then -
node = ('D',1)
node[1] = 1
therefore, temp_node = (node[0],1 - node[1]) = ('D',0)

Similarly if dbn.get_cardinality(('D',0)) is called then -
node = ('D',0)
node[1] = 0
therefore, temp_node = node = ('D',0).

Actually , with this i am thinking to replace

evidence_card = cpd.cardinality[:0:-1]
with following piece of code to solve issue #877

            parents_card = []
            for parent in parents:
                parents_card.append(self.get_cardinality(parent))

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lohani2280 But what if someone queries in let's say time slice 5, with the node ('D', 5). This would fail in that case. Right ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ankurankan Ohh!! sorry my bad. I went out with the flow of the example in the docstring.

@khalibartan
Copy link
Member

@ankurankan @lohani2280 If I remember correctly it is not necessary for a node to be present in time slice 0 always.

if node not in super(DynamicBayesianNetwork, self).nodes():
raise ValueError('Node not present in the model.')
else:
temp_node = (node[0],0) if node[1] else node
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lohani2280 PEP8. Space after ,.

>>> from pgmpy.factors.discrete import TabularCPD
>>> dbn = DBN()
>>> dbn.add_edges_from([(('D',0),('G',0)),(('I',0),('G',0)),(('D',0),('D',1)),(('I',0),('I',1))])
>>> grade_cpd = TabularCPD(('G',0), 3, [[0.3,0.05,0.9,0.5],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always use keyword argument in docstrings. Makes things clearer for the user.

self.assertDictEqual(self.network.get_cardinality(),
{('D', 0): 2, ('D', 1): 2, ('G', 0): 3, ('I', 0): 2, ('I', 1): 2})

def test_get_cardinality_with_node(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lohani2280 Could you also add tests for the case when the time slice is not 0 or 1.

defaultdict(int, {('D', 0): 2, ('D', 1): 2, ('G', 0): 3, ('I', 0): 2, ('I', 1): 2})
"""
if node:
if node not in super(DynamicBayesianNetwork, self).nodes():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will work only when the time slice is 0 or 1. Also add tests for testing when this method will throw this error.

@@ -440,6 +440,51 @@ def remove_cpds(self, *cpds):
cpd = self.get_cpds(cpd)
self.cpds.remove(cpd)

def get_cardinality(self, node=None):
"""
Returns the cardinality of the node.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should also mention here that it returns all the cardinalities if node=None.

@ankurankan
Copy link
Member

@khalibartan Yes, you are right. I mentioned that only in the last comment.

@lohani2280
Copy link
Contributor Author

@ankurankan @khalibartan Thanks for the review. I will make the suggested changes and synchronise soon :)

@codecov
Copy link

codecov bot commented Dec 13, 2017

Codecov Report

Merging #924 into dev will increase coverage by <.01%.
The diff coverage is 95.45%.

Impacted file tree graph

@@            Coverage Diff             @@
##              dev     #924      +/-   ##
==========================================
+ Coverage   94.77%   94.77%   +<.01%     
==========================================
  Files         116      116              
  Lines       11314    11336      +22     
==========================================
+ Hits        10723    10744      +21     
- Misses        591      592       +1
Impacted Files Coverage 螖
...y/tests/test_models/test_DynamicBayesianNetwork.py 100% <100%> (酶) 猬嗭笍
pgmpy/models/DynamicBayesianNetwork.py 91.66% <90%> (-0.14%) 猬囷笍

Continue to review full report at Codecov.

Legend - Click here to learn more
螖 = absolute <relative> (impact), 酶 = not affected, ? = missing data
Powered by Codecov. Last update e45f746...a95e7f5. Read the comment docs.

@lohani2280
Copy link
Contributor Author

@ankurankan I have updated the PR with the suggested changes. Please have a look!

@lohani2280 lohani2280 closed this Dec 13, 2017
@lohani2280 lohani2280 reopened this Dec 13, 2017
"""
Returns the cardinality of the node.If node=None returns all the cardinalities.

Parameter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lohani2280 Use Parameters, the doc generator parses that only I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ankurankan Yeah sure, i'll update it.

@lohani2280
Copy link
Contributor Author

@ankurankan I think this PR is ready for merge. I have rebased it. If you are free at sometime , please have a look over it.

@khalibartan
Copy link
Member

@lohani2280 Can you rebase your branch to latest dev?

@lohani2280
Copy link
Contributor Author

@khalibartan @ankurankan I have rebased my branch to latest dev. Please have a look at it.

@khalibartan khalibartan dismissed ankurankan鈥檚 stale review March 13, 2018 09:15

Ayush has updated the PR

Copy link
Member

@khalibartan khalibartan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lohani2280 Could you please add test cases of error that is being raised.

if node not in super(DynamicBayesianNetwork, self).nodes():
raise ValueError('Node not present in the model.')
else:
temp_node = (node[0], 0) if node[1] else node
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lohani2280 I don't think we need this line. You can directly write something like this
return self.get_cpds((node[0], 0)).cardinality[0]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@khalibartan Sorry, for the late reply. I'll update the PR very soon.

@ankurankan ankurankan self-assigned this Mar 19, 2018
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 this pull request may close these issues.

Adding get_cardinality method for DynamicBayesianNetwork
3 participants