Data sampling (DBN) in Python

# __author__ = 'Bayes Server'
# __version__= '0.1'

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

# TODO change path if necessary
classpath = "C:\\Program Files\\Bayes Server\\Bayes Server 9.5\\API\\Java\\bayesserver-9.5.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.learning.parameters import *
from com.bayesserver.data import *
from com.bayesserver.data.sampling import *
from jpype import java, JImplements, JOverride

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

def nullable_int(x):
    """ Helper function to convert an integer to a java nullable integer (java.lang.Integer) """
    return java.lang.Integer(x)

def value_as_text(variable, time, evidence):

    time_nullable = nullable_int(time)

    if evidence.getEvidenceType(variable, time_nullable) == EvidenceType.NONE:
        return "(null)"

    if variable.getValueType() == VariableValueType.CONTINUOUS:
        return f"{evidence.get(variable, time_nullable)}"
    else:
        return variable.getStates().get(evidence.getState(variable, time_nullable)).getName()

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

# TODO change path to sample network included with Bayes Server if necessary
network.load(r"C:\ProgramData\Bayes Server 9.5\Sample Networks\Tutorial 3 - Time series network.bayes")

x1 = network.getVariables().get("X1", True)
x2 = network.getVariables().get("X2", True)

fixedEvidence = DefaultEvidence(network)

# You can optionally set evidence on 'fixedEvidence' if you wish to fix
# certain variables, as follows
fixedEvidence.set(x2, 3.4, nullable_int(3))

# prepare to sample data from the Bayesian network
sampler = DataSampler(network, fixedEvidence)
options = DataSamplingOptions()

# If you want to simulate missing data, you can use the following line of code...
# options.setMissingDataProbability(0.05)  # set 5% of the data to missing

random = java.util.Random(0)
sample = DefaultEvidence(network)  # acts like a buffer to receive each sample

for i in range(10):
    try:
        print(f"Sample {i}")
        print("Time\tX1\tX2")
        print("------------------------------")

        sequence_length = 5  # This can be varied per sample if required
        options.setSequenceLength(nullable_int(sequence_length))
        sampler.takeSample(sample, random, options)

        for t in range(sequence_length):
            print(f"\t{t}\t{value_as_text(x1, t, sample)}\t{value_as_text(x2, t, sample)}")

    except InconsistentEvidenceException:
        print("Inconsistent evidence exception was raised.")