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

Feature/dbn #174

Draft
wants to merge 14 commits into
base: develop
Choose a base branch
from
Draft

Feature/dbn #174

wants to merge 14 commits into from

Conversation

liam-adams
Copy link
Contributor

Motivation and Context

Why was this PR created?
This PR is created to add a DynamicStructureNode, DynamicStructureModel and DynamicBayesianNetwork for prediction and inference with DYNOTEARS

How has this been tested?

What testing strategies have you used?
Test driven development

Checklist

  • Read the contributing guidelines
  • Opened this PR as a 'Draft Pull Request' if it is work-in-progress
  • Updated the documentation to reflect the code changes
  • Added a description of this change and added my name to the list of supporting contributions in the RELEASE.md file
  • Added tests to cover my changes
  • Assigned myself to the PR

Notice

  • I acknowledge and agree that, by checking this box and clicking "Submit Pull Request":

  • I submit this contribution under the Apache 2.0 license and represent that I am entitled to do so on behalf of myself, my employer, or relevant third parties, as applicable.

  • I certify that (a) this contribution is my original creation and / or (b) to the extent it is not my original creation, I am authorised to submit this contribution on behalf of the original creator(s) or their licensees.

  • I certify that the use of this contribution as authorised by the Apache 2.0 license does not violate the intellectual property rights of anyone else.

Copy link
Contributor

@GabrielAzevedoFerreiraQB GabrielAzevedoFerreiraQB left a comment

Choose a reason for hiding this comment

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

We're in the right direction, but there I'd say the still some good amount of things to focus on before it gets merged.

Let me know if you need time to chat/PS about it. Thanks!

Comment on lines 743 to 757
Base class for Dynamic Bayesian Network (DBN), a probabilistic weighted DAG where nodes represent variables,
edges represent the causal relationships between variables.

``DynamicBayesianNetwork`` stores nodes with their possible states, edges and
conditional probability distributions (CPDs) of each node.

``DynamicBayesianNetwork`` is built on top of the ``StructureModel``, which is an extension of ``networkx.DiGraph``
(see :func:`causalnex.structure.structuremodel.StructureModel`).

In order to define the ``DynamicBayesianNetwork``, users should provide a relevant ``StructureModel``.
Once ``DynamicBayesianNetwork`` is initialised, no changes to the ``StructureModel`` can be made
and CPDs can be learned from the data.

The learned CPDs can be then used for likelihood estimation and predictions.

Copy link
Contributor

Choose a reason for hiding this comment

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

looks good.
I think the text should be a bit different from the one in the BN class though. It's ok to keep the similar points, but I would rather say that a DBN is a BN with the time domain taken into account, and it does X and Y that a normal BN doesn't do

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes i think i need a PS here :)

Raises:
ValueError: If the structure is not a connected DAG.
"""
super().__init__(structure)
Copy link
Contributor

Choose a reason for hiding this comment

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

Just wanted to know if you're clear on the changes that will need to come here. If not let's have a PS anytime :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes i think i need a PS here :)

causalnex/structure/dynotears.py Show resolved Hide resolved
Comment on lines 359 to 361
def checkargs(function):
def _f(*arguments, **attr):
for index, argument in enumerate(inspect.getfullargspec(function)[0]):
Copy link
Contributor

Choose a reason for hiding this comment

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

This is really great and helpful!

Could you add docs - I try to add docs every time a function does something non-obvious

Also:

  • will it work for in case the user provides attr isntead of arguments?
  • I usally use (*args, **kw_args), but not sure if it is the de-facto standard. what do you 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.

I believe if a dictionary is passed as an arg it is absorbed intoattr. I should test if someone calls the function like add_node(dnode=node), i'm not sure if that would be a member of argmuments or attr.

Comment on lines 368 to 370
if len(arg) == 3:
if not all(isinstance(n, DynamicStructureNode) for n in arg[:-1]):
raise TypeError("{} is not of type {}".format(arguments[index], function.__annotations__[argument]))
Copy link
Contributor

Choose a reason for hiding this comment

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

I think with docstrings it will be clearer, but would love to understand the checks themselves better.

I wonder why len(arg) == 3 - I'm sure there is a reason, just couldn't get it yet

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its for add_weighted_edges_from when the third element of the tuple is a number

Comment on lines +452 to +454
"""
Get the subgraph with the specified node.

Copy link
Contributor

Choose a reason for hiding this comment

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

I also see that some functions are pretty similar to the StructureNode counterpart. Maybe we can reuse them/avoid repeating code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here i think after calling
node_name = node.get_node_name()
I could call
super.get_target_subgraph(node_name)

)
sm.add_weighted_edges_from(
[
(
_format_name_from_pandas(idx_col, u),
_format_name_from_pandas(idx_col, v),
DynamicStructureNode(idx_col[int(u[0])], u[-1]), # _format_name_from_pandas(idx_col, u), idx_col[int(u[0])]
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we delete the comment, please? :)

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.

None yet

2 participants