pgmpy/pgmpy_tutorials

Saving bif file discards the state names

Closed this issue · 5 comments

Writing a bif file using writer = BIFWriter(thisBayesNet) does not preserve the state names for any variables. From what I can tell in the source code, this capability is dependent on this get_states function:

def get_states(self):
        variable_states = {}
        cpds = self.model.get_cpds()
        for cpd in cpds:
            variable = cpd.variable
            variable_states[variable] = []
            for state in range(cpd.get_cardinality([variable])[variable]):
                variable_states[variable].append(str(state))
        return variable_states

Although the example provided above that code shows the intended behavior, because the state variable is an index in the range up to the cardinality of the variable, and not the names from the cpd, the variable_states will always be a list of str numerals instead of the original variable states.

Instead, just do this:

def get_states(self):
        variable_states = {}
        cpds = self.model.get_cpds()
        for cpd in cpds:
            variable = cpd.variable
            variable_states[variable] = [cpd.get_state_names(variable,thisIndex) for thisIndex in range(cpd.get_cardinality([variable])[variable])]
        return variable_states

I didn't test whether the list comprehension is faster in this case, but you can convert the main point (preserving the state names) to your append version fairly easily I think.

I changed this in a local depository and it fixed the problem.

@bramson Thanks for reporting this. I am just waiting on pgmpy/pgmpy#1221 before resolving this. But if you would like to open a pull request with your changes, that would be great, and I will incorporate my changes into that.

I am not a proficient user of Github, so I don't really know how to open a pull request, or even why I would want to do that.

Actually, I am building a lot of wrappers around your basic code to improve/streamline the creation and editing of models. For example, when creating a CPT, the information about parents, parents' cardinality, and parents' state names can all be pulled from the model, thus simplifying what is required from the user at input time. Probably some of these are features you will want to fold into your project. So perhaps I should learn how to use this Github tool properly.

@bramson With a pull request, you basically create a request to merge your changes into the main repository. And since you suggested the changes, it would be nice that you get credit for the changes in the repo as well as it would be your commit.

It would be great if you have a more easy to use API which works for most of the users, I would be happy to merge it into the repo.

@ankurankan I looked into setting up the ability to do pull requests properly, and it's not worth the effort for me. I don't need any credit, so please just merge it.

Fixed in release: 0.1.11