Structural learning in Python

This example makes use of the Python code in Data Frame Utils.

# __author__ = 'Bayes Server'
# __version__= '0.2'

import pandas as pd

import jpype    # pip install jpype1    (version 1.2.1 or later)
import jpype.imports
from jpype.types import *

classpath = "C:\\Program Files\\Bayes Server\\Bayes Server 9.4\\API\\Java\\bayesserver-9.4.jar"

# Launch the JVM
jpype.startJVM(classpath=[classpath])

import data_frame_utils as dfu

# import the Java modules
from com.bayesserver import *
from com.bayesserver.inference import *
from com.bayesserver.data import *
from com.bayesserver.learning.structure import *
from jpype import java

# Uncomment the following line and change the license key, if you are using a licensed version
# License.validate("xxx")


def learn_structure():
    """
    This example uses a Pandas DataFrame as the data source for learning the structure of a Bayesian network
    You can also connect to databases using DatabaseDataReaderCommand
    """

    network = create_network_no_links()  # we manually construct the network here, but it could be loaded from a file

    learning = PCStructuralLearning()

    data_reader_command = create_data_reader_command()

    variable_references = []

    for v in network.getVariables():
        variable_references.append(VariableReference(v, ColumnValueType.NAME, v.getName()))

    reader_options = ReaderOptions()  # we do not have a case column in this example

    evidence_reader_command = DefaultEvidenceReaderCommand(
        data_reader_command,
        java.util.Arrays.asList(variable_references),
        reader_options)

    options = PCStructuralLearningOptions()

    output = learning.learn(evidence_reader_command, network.getNodes(), options)

    for linkOutput in output.getLinkOutputs():
        print("Link added from {0} -> {1}".format(linkOutput.getLink().getFrom().getName(), linkOutput.getLink().getTo().getName()))


def create_network_no_links():
    """
    Manually construct a network to keep the example simple.
    """

    network = Network()

    # Instead of manually constructing a network
    # you could also load from a file using
    # network.load("path-to-file");

    for name in ["A", "B", "C"]:

        node = Node(name, ["False", "True"])
        network.getNodes().add(node)

    # We are not adding links here, as we are going to learn them from data.

    return network


def create_data_reader_command():

    """
    Create a data reader command.
    Normally you would read from a database or spreadsheet, but to keep this example simple
    we are hard coding the data.
    """

    d = {
        'A': ['True', 'True', 'True', 'False', 'False', 'False', 'False', 'True', 'True', 'True', 'True', 'False', 'True',
           'True', 'False', 'True', 'False', 'False', 'True', 'False', 'False', 'True', 'False', 'True', 'False',
           'True', 'False', 'False', 'True', 'False', 'True', 'False', 'True', 'True', 'True', 'True', 'True', 'True',
           'False', 'True', 'True', 'False', 'True', 'False', 'False', 'True', 'True', 'True', 'False', 'True', 'True',
           'True', 'True', 'True', 'True', 'True', 'True', 'True', 'False', 'True', 'False', 'False', 'True', 'False',
           'True', 'False', 'False', 'True', 'False', 'False', 'True', 'True', 'False', 'False', 'True', 'True', 'True',
           'False', 'True', 'False', 'True', 'True', 'True', 'True', 'False', 'True', 'True', 'False', 'True', 'True',
           'True', 'False', 'False', 'True', 'True', 'True', 'True', 'False', 'True', 'True'],
        'B': ['False', 'True', 'False', 'False', 'True', 'False', 'True', 'False', 'True', 'False', 'False', 'True',
           'True', 'True', 'False', 'False', 'True', 'False', 'False', 'True', 'False', 'False', 'False', 'True',
           'False', 'False', 'False', 'False', 'True', 'False', 'False', 'False', 'False', 'False', 'False', 'True',
           'True', 'False', 'False', 'False', 'True', 'True', 'False', 'False', 'False', 'False', 'True', 'False',
           'False', 'True', 'True', 'True', 'False', 'False', 'False', 'False', 'False', 'False', 'False', 'False',
           'True', 'False', 'True', 'True', 'True', 'True', 'False', 'True', 'False', 'False', 'True', 'False', 'False',
           'False', 'False', 'False', 'True', 'True', 'False', 'True', 'True', 'True', 'True', 'False', 'True', 'False',
           'False', 'False', 'False', 'False', 'True', 'False', 'True', 'False', 'False', 'True', 'True', 'True',
           'True', 'False'],
        'C': ['True', 'True', 'True', 'False', 'True', 'False', 'True', 'True', 'True', 'True', 'True', 'True', 'True',
           'True', 'False', 'True', 'True', 'False', 'True', 'True', 'False', 'True', 'False', 'True', 'False', 'True',
           'False', 'False', 'True', 'False', 'True', 'False', 'True', 'True', 'True', 'True', 'True', 'True', 'False',
           'True', 'True', 'True', 'True', 'False', 'False', 'True', 'True', 'True', 'False', 'True', 'True', 'True',
           'True', 'True', 'True', 'True', 'True', 'True', 'False', 'True', 'True', 'False', 'True', 'True', 'True',
           'True', 'False', 'True', 'False', 'False', 'True', 'True', 'False', 'False', 'True', 'True', 'True', 'True',
           'True', 'True', 'True', 'True', 'True', 'True', 'True', 'True', 'True', 'False', 'True', 'True', 'True',
           'False', 'True', 'True', 'True', 'True', 'True', 'True', 'True', 'True']
    }

    df = pd.DataFrame(data=d)
    dt = dfu.to_data_table(df)

    return DataTableDataReaderCommand(dt)


learn_structure()