Create Marginal class as common return type for inference methods#10
Create Marginal class as common return type for inference methods#10jpoeppel wants to merge 9 commits intoSocialCognitiveSystems:masterfrom
Conversation
primo2/inference/marginal.py
Outdated
|
|
||
| returnDict: Boolean, optional (default: False) | ||
| Specifies if the probabilities should be returned as a dictionary | ||
| of the form {variable: probabilities} (if set to true) or as |
There was a problem hiding this comment.
Isn't the returned dictionary of the form {variable: {value: probability}}?
There was a problem hiding this comment.
True, at least for the general case. For the simple case (which was the only one I considered writing this as I see now) where I only have 1 variable, I directly return the inner dictionairy, as the outer one is kind of pointless. But I'll change the docstring to be more accurate on this.
…t error message when using wrong variables
…d. appropriate tests were added or adapted where necessary
…bilities checks to be pyton2 and python3 compatible (still needs thorough testing)
|
It appears that distinguishing list-like objects (lists, sets, tupels...) from strings is not elegantly possible while staying compatible with python2 and 3. The solution I've used now, is rather ugly since it requires both hasattr and isinstance in order to (hopefully) catch most corner cases. I've restructed the code so that this check is only performed at one position within each function. |
…as defaults) and adopted tests accordingly
|
I have not yet touched the dynamic methods, but I think I've changed the return types of all relevant approximate and exact methods to marginals. The tests were modified accordingly. I guess this is ready to be reviewed and tested. |
This is a work in progress. So far I've started creating fundamental tests for the different use cases that we have considered. They still need to be expanded upon with more complex marginals as well as other convenience functions.
The reason I am already opening the PR is to discuss the proposed interface, which is already quite flexible, but I am not too sure about the dictionary return yet.
Currently I handle a request like
m.get_probabilities({"A":["True","False"]}, returnDict=True})for a marginal containing the binary variables A and B like so:{"True": np.array([P(A=True, B=True), P(A=True, B=False)]), "False": np.array([P(A=False, B=True), P(A=False, B=False)])}.A request such as:
m.get_probabilities({"A":["True", "False"], "B": "False"}, returnDict=True})[note that you do not have to insert single instantiations in lists, but can just specify them as values directly] yields:{A: {"True": np.array([P(A=True, B=False)]), "False":np.array(P(A=False,B=False))}, B: {"False": np.array([P(A=True,B=False)])}}since the request desires the probability for this combination. When returnDict=False this method basically behaves as Factor.get_potential with the additional convencience of not having to specify single instantiations in lists as well as allowing things like "get_probabilities("A")".