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
base: dev
Are you sure you want to change the base?
Conversation
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 |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
>>> 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
pgmpy/pgmpy/models/DynamicBayesianNetwork.py
Line 512 in 0f62927
evidence_card = cpd.cardinality[:0:-1] |
parents_card = []
for parent in parents:
parents_card.append(self.get_cardinality(parent))
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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.
33fe43a
to
59e80ba
Compare
@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 |
There was a problem hiding this comment.
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], |
There was a problem hiding this comment.
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): |
There was a problem hiding this comment.
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(): |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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
.
@khalibartan Yes, you are right. I mentioned that only in the last comment. |
@ankurankan @khalibartan Thanks for the review. I will make the suggested changes and synchronise soon :) |
59e80ba
to
fe4b10f
Compare
Codecov Report
@@ 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
Continue to review full report at Codecov.
|
@ankurankan I have updated the PR with the suggested changes. Please have a look! |
""" | ||
Returns the cardinality of the node.If node=None returns all the cardinalities. | ||
|
||
Parameter |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
fe4b10f
to
a3be71f
Compare
a3be71f
to
2ac86b0
Compare
@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. |
@lohani2280 Can you rebase your branch to latest dev? |
2ac86b0
to
a95e7f5
Compare
@khalibartan @ankurankan I have rebased my branch to latest dev. Please have a look at it. |
There was a problem hiding this 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 |
There was a problem hiding this comment.
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]
There was a problem hiding this comment.
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.
closes #921
Your checklist for this pull request
馃毃Please review the guidelines for contributing to this repository.
Fixes #921
Changes
Added
get_cardinality
method inDynamicBayesianNetwork
class and the corresponding test cases.馃挃Thank you!