Esempio n. 1
0
    def sprinkler_test_0(self):
        '''
        Simple network from "An introduction to graphical models" by Kevin P.
        Murphy
        C -> S
        C -> R
        S -> W
        R -> W
        '''
        C = RandVar("Cloudy", ["F", "T"])
        S = RandVar("Sprinkler", ["F", "T"])
        R = RandVar("Rain", ["F", "T"])
        W = RandVar("WetGrass", ["F", "T"])

        Cf = Factor([C], [0.5, 0.5])
        Sf = Factor([S, C], [0.5, 0.5, 0.9, 0.1])
        Rf = Factor([R, C], [0.8, 0.2, 0.2, 0.5])
        Wf = Factor([W, S, R], [1.0, 0.0, 0.1, 0.9, 0.1, 0.9, 0.01, 0.99])

        SprinklerNW = bn.BayesianNetwork([(C, Cf, []), (S, Sf, [C]),
                                          (R, Rf, [C]), (W, Wf, [S, R])])

        cases = [(W, 1, [(S, "T"), (R, "F")], 0.9)]

        for (qvar, qvalue, evidence, expect) in cases:
            result = SprinklerNW.eliminationAsk(qvar, evidence)
            print("qvar: %s\nevidence: %s\nexpect: %s\nresult: %s" %
                  (qvar.name, ",".join(
                      ["%s=%s" % (x[0].name, x[1])
                       for x in evidence]), expect, result.values[qvalue]))
            assert_almost_equal(result.values[qvalue], expect, places=3)
Esempio n. 2
0
def ex1():
    """
    Example of the Channel Capacity algorithm applied to a binary symmetric
    channel. Such channels have an explicit way to have their channel capacity
    computed. Which is:

        C = 1 - H(p),

    where p is the probability of error in the channel::

           p
        0 --- 0
          \ / 1-p
           /
          / \ 1-p
        1 --- 1
           p

    In this example the probability of error is 0.1
    """

    p = 0.9

    Input = RandVar("Input", ["T", "F"])
    Output = RandVar("Output", ["T", "F"])

    Prior = Factor(Input, [0.5, 0.5])
    Channel = Factor([Input, Output], [p, 1 - p, 1 - p, p])

    cc = ChannelCapacity(Input, Output, Prior, Channel)
    explicit = 1 - entropy(Factor(Input, [p, 1 - p]))

    print("Channel Capacity of a binary symmetric channel")
    print("Blahut-Arimoto:", cc)
    print("Explicit:      ", explicit)
Esempio n. 3
0
    def factor_test(self):
        X = RandVar("X", [0, 1])
        Y = RandVar("Y", [0, 1])

        f1 = Factor(X, [0, 1])
        f2 = Factor([X, Y], [0, 1, 2, 3])

        assert(f1.__repr__() == "(X, [0, 1])")
        assert(f2.__repr__() == "([X, Y], [0, 1, 2, 3])")
Esempio n. 4
0
def ex2():
    domain = [str(i) for i in range(2)]
    Input = RandVar("Input", domain)
    Output = RandVar("Output", domain)

    Prior = Factor(Input, [1.0 / 2.0] * 2)
    channel_dist = [random.random() for i in range(4)]
    Channel = Factor([Input, Output], channel_dist).normalize(Input)

    print(ChannelCapacity(Input, Output, Prior, Channel))
Esempio n. 5
0
    def min_test_2(self):
        """
        Minimum with one variable
        """

        for i, domain in enumerate(self.X.domain):
            fac = Factor(self.X, [1, 2])
            fac.values[i] = -10

            assert(fac.min() == -10)
Esempio n. 6
0
    def max_test_0(self):
        """
        Maximum with one variable
        """

        for i, domain in enumerate(self.X.domain):
            fac = Factor(self.X, [1, 2])
            fac.values[i] = 10

            assert(fac.max() == 10)
Esempio n. 7
0
    def max_test_1(self):
        """
        Maximum with two variables
        """

        for i, domainx in enumerate(self.X.domain):
            for j, domainy in enumerate(self.Y.domain):
                fac = Factor([self.X, self.Y], [1, 2, 3, 4])
                fac.values[i + j*2] = 10

                assert(fac.max() == 10)
Esempio n. 8
0
    def min_test_3(self):
        """
        Minimum with two variables
        """

        for i, domainx in enumerate(self.X.domain):
            for j, domainy in enumerate(self.Y.domain):
                fac = Factor([self.X, self.Y], [1, 2, 3, 4])
                fac.values[i + j*2] = -10

                assert(fac.min() == -10)
Esempio n. 9
0
    def argmin_test_6(self):
        """
        Minimum argument with one variable
        """

        for i, domain in enumerate(self.X.domain):
            fac = Factor(self.X, [1, 2])
            fac.values[i] = -10

            event = Event([(self.X, domain)])
            assert(fac.argmin() == event)
Esempio n. 10
0
    def argmin_test_7(self):
        """
        Minimum argument with two variables
        """

        for i, domainx in enumerate(self.X.domain):
            for j, domainy in enumerate(self.Y.domain):
                fac = Factor([self.X, self.Y], [1, 2, 3, 4])
                fac.values[i + j*2] = -10

                event = Event([(self.X, domainx), (self.Y, domainy)])
                assert(fac.argmin() == event)
Esempio n. 11
0
    def student_test_0(self):
        '''
        Student network from "Probabilistic graphical models principles and
        techniques" by Koller and Friedman
        D -> G
        I -> G
        I -> S
        G -> L

        '''
        D = RandVar("Difficulty", ["easy", "hard"])
        I = RandVar("Intelligence", ["low", "high"])
        G = RandVar("Grade", ["a", "b", "c"])
        S = RandVar("SAT", ["low", "high"])
        L = RandVar("Letter", ["weak", "good"])

        Df = Factor([D], [0.6, 0.4])
        If = Factor([I], [0.7, 0.3])
        Gf = Factor([G, D, I], [
            0.30, 0.40, 0.30, 0.05, 0.25, 0.70, 0.90, 0.08, 0.02, 0.50, 0.30,
            0.20
        ])
        Sf = Factor([S, I], [0.95, 0.05, 0.2, 0.8])
        Lf = Factor([L, G], [0.1, 0.9, 0.4, 0.6, 0.99, 0.01])

        StudentNW = bn.BayesianNetwork([(D, Df, []), (I, If, []),
                                        (G, Gf, [D, I]), (S, Sf, [I]),
                                        (L, Lf, [G])])

        cases = [(L, 1, [(I, "low"), (D, "easy")], 0.513),
                 (I, 1, [(L, "weak")], 0.140),
                 (I, 1, [(G, "c"), (S, "high")], 0.578),
                 (L, 1, [(I, "low")], 0.389), (I, 1, [(G, "c")], 0.079)]

        for (qvar, qvalue, evidence, expect) in cases:
            result = StudentNW.eliminationAsk(qvar, evidence)
            print("qvar: %s\nevidence: %s\nexpect: %s\nresult: %s" %
                  (qvar.name, ",".join(
                      ["%s=%s" % (x[0].name, x[1])
                       for x in evidence]), expect, result.values[qvalue]))
            assert_almost_equal(result.values[qvalue], expect, places=3)
Esempio n. 12
0
def kullbackLeiblerDistance(fac1, fac2, base=2):
    """
    Calculates the Kullback-Leibler Distance between fac1 and fac2. The factors
    should represent probability distributions with the same variables, like
    P(X) and Q(X), or P(X, Y) and Q(X, Y)

    :param fac1: First factor in operation
    :param fac2: Second factor in operation
    :param base: Base of logarithms in the operations, defaults to 2
    :returns:    The Kullback-Leibler Distance
    """

    kld = lambda f1, f2: f1 * log(f1 / f2) / log(base)
    return sum(Factor.factorOp(fac1, fac2, kld).values)
Esempio n. 13
0
def kullbackLeiblerDistance(fac1, fac2, base=2):
    """
    Calculates the Kullback-Leibler Distance between fac1 and fac2. The factors
    should represent probability distributions with the same variables, like
    P(X) and Q(X), or P(X, Y) and Q(X, Y)

    :param fac1: First factor in operation
    :param fac2: Second factor in operation
    :param base: Base of logarithms in the operations, defaults to 2
    :returns:    The Kullback-Leibler Distance
    """

    kld = lambda f1, f2: f1 * log(f1 / f2) / log(base)
    return sum(Factor.factorOp(fac1, fac2, kld).values)
Esempio n. 14
0
    def factor_test(self):
        X = RandVar("X", [0, 1])
        Y = RandVar("Y", [0, 1])

        f1 = Factor(X, [0, 1])
        f2 = Factor([X, Y], [0, 1, 2, 3])

        assert (f1.__repr__() == "(X, [0, 1])")
        assert (f2.__repr__() == "([X, Y], [0, 1, 2, 3])")
Esempio n. 15
0
    def __init__(self):
        TestBase.__init__(self)

        # factors for information theory testing
        self.fX1 = Factor(self.X, [0.5, 0.5])
        self.fX2 = Factor(self.X, [0.0, 1.0])
        self.fX3 = Factor(self.X, [1.0, 0.0])

        self.fXY1 = Factor([self.X, self.Y], [0.25, 0.25, 0.25, 0.25])
        self.fXY2 = Factor([self.X, self.Y], [0.1, 0.2, 0.3, 0.4])
        self.fXY3 = Factor([self.X, self.Y], [0.4, 0.3, 0.2, 0.1])
Esempio n. 16
0
    def rejectionSample(self, query_var, observed, samples_num):
        """
        Implementation of the rejection sample algorithm. This algorithms
        estimates a distribution P(X | e), where X is a query variable and e
        are observations made in the network.

        :param query_var:   Random variable of type RandVar
        :param observed:    List of observations. Each element of the list
                            should be a tuple, which first element is a RandVar
                            and second element is the observed value for that
                            variable
        :param samples_num: Number of samples the algorithm is going to take to
                            calculate the estimative
        """

        # List of counts for each value of the domain. Initialized with 0
        count = {i: 0 for i in query_var.domain}

        # The samples_num of samples
        for i in range(samples_num):
            # Take a sample
            sample = self.sample()

            # Check if it should be rejected
            rejected = False
            for j in observed:
                for k in sample:
                    # If the value of the sampled variable is different from
                    # the value of the observed one, rejected
                    if j[0].name == k[0].name and j[1] != k[1]:
                        rejected = True
                        break

                # If the sample was already rejected, get out of the cycle
                if rejected:
                    break

            # If the sample is not rejected, increment the counts
            if not rejected:
                for j in sample:
                    if j[0].name == query_var.name:
                        count[j[1]] += 1

        # Make resulting factor
        values = [count[i] for i in query_var.domain]
        return Factor([query_var], values).normalize(query_var)
Esempio n. 17
0
    def gibbsAsk(self, query_var, observed, samples_num):
        # Result is a list of counts for each value in the domain of the query
        # variable. Initialized with 0
        res = {i: 0 for i in query_var.domain}

        # Assure the observed argument is an Event
        if type(observed) != Event:
            observed = Event(observed)

        # Create non evidence variable list, which are all the variables not
        # present in the observations
        non_evidence_vars = [i for i in self.network
                             if not observed.varInEvent(i.node)]

        # Get markov blankets for each non evidence variable
        mbs = dict()
        for i in non_evidence_vars:
            mbs[i.node.name] = self.markovBlanket(i)

        # Make an initial sample
        sample = self.sample(observed)

        # Execute for samples_num samples
        for i in range(samples_num):
            for j in non_evidence_vars:
                # Get distribution P(j | mb(j))
                dist = j.factor
                for k in mbs[j.node.name]:
                    dist *= k.factor

                # Instantiate with previous sample, except for current j
                # variable
                sample.removeVar(j.node)
                dist = dist.instVar(sample)

                # Set new random value of current variable in sample
                rvalue = self.pickRandomValue(dist.rand_vars[0].domain,
                                              dist.values, random.random())
                sample.setValue(j.node, rvalue)

                # Increment count
                res[rvalue] += 1

        # Return the count list normalized
        values = [res[i] for i in query_var.domain]
        return Factor(query_var, values).normalize(query_var)
Esempio n. 18
0
    def __init__(self):
        TestBase.__init__(self)

        # factors for information theory testing
        self.fX1 = Factor(self.X, [0.5, 0.5])
        self.fX2 = Factor(self.X, [0.0, 1.0])
        self.fX3 = Factor(self.X, [1.0, 0.0])

        self.fXY1 = Factor([self.X, self.Y], [0.25, 0.25, 0.25, 0.25])
        self.fXY2 = Factor([self.X, self.Y], [0.1, 0.2, 0.3, 0.4])
        self.fXY3 = Factor([self.X, self.Y], [0.4, 0.3, 0.2, 0.1])

        self.P1 = Factor([self.X], [0.5, 0.5])
        self.Q1 = Factor([self.X], [0.9, 0.1])

        self.P2 = Factor([self.X, self.Y], [0.25, 0.25, 0.25, 0.25])
        self.Q2 = Factor([self.X, self.Y], [0.8, 0.05, 0.05, 0.8])
Esempio n. 19
0
    def inf_theory_test_7(self):
        """
        I(X ; Y)
        """

        joint = Factor([self.X, self.Y], [0.8, 0.05, 0.05, 0.8])
        fac1 = self.fXY1.marginal(self.X)
        fac2 = self.fXY1.marginal(self.Y)

        res = [
            mutualInformation(joint, fac1, fac2),
            mutualInformation(joint, fac1, fac2, 10),
            mutualInformation(joint, fac1, fac2, math.e)
        ]

        assert_almost_equal(res[0], 2.4527, places=4)
        assert_almost_equal(res[1], 0.73834, places=5)
        assert_almost_equal(res[2], 1.7001, places=5)
Esempio n. 20
0
    def beliefProp(self):
        """
        Belief propagation algorithm, also known as sum-product algorithm. The
        result of the algorithm is stored in the *marginal* attribute of every
        variable node which is part of the network. This implementation only
        works with tree networks.
        """

        # Select any root node
        root_node = self.nodes[next(iter(self.nodes))]

        # Get messages to this node
        res = self.factorToVar(root_node.neighbors[0], root_node)
        root_node.messages[0] = res

        for i, neighbor in enumerate(root_node.neighbors[1:]):
            msg = self.factorToVar(neighbor, root_node)
            root_node.messages[i+1] = msg
            res *= msg

        for i in root_node.obs_factors:
            res *= i

        # Store the calculated marginal
        root_node.setMarginal(res)

        # Propagate this message to other nodes
        for i, neighbor in enumerate(root_node.neighbors):
            new_msg = Factor(root_node.var, [1, 1])

            for j in range(len(root_node.neighbors)):
                if i != j:
                    new_msg *= root_node.messages[j]

            for j in root_node.obs_factors:
                new_msg *= j

            self.progMsgVarToFactor(neighbor, root_node, new_msg)
Esempio n. 21
0
sys.path.insert(0, path.join("..", "ProbPy"))

# Import ProbPy modules
from ProbPy import RandVar, Factor, Event
from ProbPy import bn

if __name__ == "__main__":
    # Variables for this example
    cloudy = RandVar("cloudy", ["True", "False"])
    sprinkler = RandVar("sprinkler", ["True", "False"])
    rain = RandVar("rain", ["True", "False"])
    wet_grass = RandVar("wet_grass", ["True", "False"])

    # Factors representing the conditional distributions of this network
    factor_cloudy = Factor(cloudy, [0.5, 0.5])
    factor_sprinkler = Factor([sprinkler, cloudy], [0.1, 0.9, 0.5, 0.5])
    factor_rain = Factor([rain, cloudy], [0.8, 0.2, 0.2, 0.8])
    factor_wet_grass = Factor([wet_grass, rain, sprinkler],
                              [0.99, 0.01, 0.9, 0.1, 0.9, 0.1, 0.0, 1.0])

    # Actual network representation
    network = [(cloudy, factor_cloudy), (sprinkler, factor_sprinkler),
               (rain, factor_rain), (wet_grass, factor_wet_grass)]

    # Create a Bayesian Network
    BN = bn.BayesianNetwork(network)

    # Set one observation
    observed = Event(var=sprinkler, val="True")
Esempio n. 22
0
    def __init__(self):
        # Scalars
        self.scalar = 10
        self.scalarf = Factor([], [10])

        # Binary variables
        self.X = RandVar("X", ["T", "F"])
        self.Y = RandVar("Y", ["T", "F"])
        self.Z = RandVar("Z", ["T", "F"])
        self.W = RandVar("W", ["T", "F"])
        self.K = RandVar("K", ["T", "F"])
        self.T = RandVar("T", ["T", "F"])

        # Domains
        self.X_domain = list(range(1, 3))
        self.Y_domain = list(range(3, 5))
        self.Z_domain = list(range(5, 7))

        self.XY_domain = list(range(1, 5))
        self.XZ_domain = list(range(5, 9))
        self.ZW_domain = list(range(9, 13))

        self.XYZ_domain = list(range(1, 9))
        self.XYW_domain = list(range(9, 17))
        self.XKW_domain = list(range(17, 25))
        self.TKW_domain = list(range(25, 33))

        # Factors
        self.X_factor = Factor(self.X, self.X_domain)
        self.Y_factor = Factor(self.Y, self.Y_domain)
        self.Z_factor = Factor(self.Z, self.Z_domain)

        self.XY_factor = Factor([self.X, self.Y], self.XY_domain)
        self.XZ_factor = Factor([self.X, self.Z], self.XZ_domain)
        self.ZW_factor = Factor([self.Z, self.W], self.ZW_domain)

        self.XYZ_factor = Factor([self.X, self.Y, self.Z], self.XYZ_domain)
        self.XYW_factor = Factor([self.X, self.Y, self.W], self.XYW_domain)
        self.XKW_factor = Factor([self.X, self.K, self.W], self.XKW_domain)
        self.TKW_factor = Factor([self.T, self.K, self.W], self.TKW_domain)

        # Factors for normalization
        self.X_factor_n = Factor(self.X, [1, 2])
        self.XY_factor_n = Factor([self.X, self.Y], [1, 1, 2, 2])
        self.XYZ_factor_n = Factor([self.X, self.Y, self.Z],
                                   [1, 1, 2, 2, 3, 3, 4, 4])

        # Distributions for expected value
        self.X_dist = Factor(self.X, [0.8, 0.2])
        self.Y_dist = Factor(self.Y, [0.1, 0.9])
        self.XY_dist = Factor([self.X, self.Y], [0.1, 0.2, 0.3, 0.4])

        # Function for expected values f(X)
        self.x_ev = Factor(self.X, [10, 20])
        self.y_ev = Factor(self.Y, [15, 25])
        self.xy_ev = Factor([self.X, self.Y], [25, 35, 35, 45])
Esempio n. 23
0
from ProbPy import RandVar, Factor, Event
from ProbPy import bn


if __name__ == "__main__":
    # These are the variables in the network. The first argument is the actual
    # name of the variable and the second is the domain of it
    burglary = RandVar("burglary", ["True", "False"])
    earthq = RandVar("earthq", ["True", "False"])
    alarm = RandVar("alarm", ["True", "False"])
    john = RandVar("john", ["True", "False"])
    mary = RandVar("mary", ["True", "False"])

    # These are the distributions. First argument are the variables, second is
    # the values in the distribution
    factor_burglary = Factor([burglary], [0.001, 0.999])
    factor_earthq = Factor([earthq], [0.002, 0.998])
    factor_alarm = Factor([alarm, earthq, burglary], [
        0.95, 0.05, 0.94, 0.06, 0.29, 0.71, 0.001, 0.999
    ])
    factor_john = Factor([john, alarm], [0.90, 0.10, 0.05, 0.95])
    factor_mary = Factor([mary, alarm], [0.70, 0.30, 0.01, 0.99])

    # This array has the nodes of the network. Each element is a tuple. In each
    # tuple, the first argument is the variable of that node, the second is the
    # distribution. Note that the nodes were place in the list at random
    network = [
        (earthq,   factor_earthq),
        (alarm,    factor_alarm),
        (john,     factor_john),
        (burglary, factor_burglary),
Esempio n. 24
0
# Import ProbPy modules
from ProbPy import RandVar, Factor

if __name__ == "__main__":
    """
    Supposing the following example
    P(X | Y) P(Y) 1/P(X) = P(Y | X)
    """

    # Random Variables
    X = RandVar("X", ["T", "F"])
    Y = RandVar("Y", ["T", "F"])

    # Prior distribution, P(Y)
    fy = Factor(Y, [0.2, 0.8])

    # Conditional distribution, P(X | Y)
    fx_y = Factor([X, Y], [0.1, 0.9, 0.5, 0.5])

    # Bayes theorem to get P(Y | X)
    fy_x = (fx_y * fy).normalize(Y)

    print("P(X | Y) P(Y) 1/P(X) = P(Y | X)")
    print(fy_x.values)

    # Alternative way of getting P(Y | X) without using the normalize() method
    fxy = fx_y * fy
    fx = fxy.marginal(X)
    fx_y = fxy / fx
Esempio n. 25
0
class TestInfTheoryValue(TestBase):
    def __init__(self):
        TestBase.__init__(self)

        # factors for information theory testing
        self.fX1 = Factor(self.X, [0.5, 0.5])
        self.fX2 = Factor(self.X, [0.0, 1.0])
        self.fX3 = Factor(self.X, [1.0, 0.0])

        self.fXY1 = Factor([self.X, self.Y], [0.25, 0.25, 0.25, 0.25])
        self.fXY2 = Factor([self.X, self.Y], [0.1, 0.2, 0.3, 0.4])
        self.fXY3 = Factor([self.X, self.Y], [0.4, 0.3, 0.2, 0.1])

        self.P1 = Factor([self.X], [0.5, 0.5])
        self.Q1 = Factor([self.X], [0.9, 0.1])

        self.P2 = Factor([self.X, self.Y], [0.25, 0.25, 0.25, 0.25])
        self.Q2 = Factor([self.X, self.Y], [0.8, 0.05, 0.05, 0.8])

    def inf_theory_test_0(self):
        """
        H(X)
        """

        assert_almost_equal(entropy(self.fX1), 1.0, places=1)
        assert_almost_equal(entropy(self.fX1, 10), 0.30103, places=5)
        assert_almost_equal(entropy(self.fX1, math.e), 0.69315, places=5)

        assert_almost_equal(entropy(self.fX2), 0.0, places=1)
        assert_almost_equal(entropy(self.fX2, 10), 0.0, places=1)
        assert_almost_equal(entropy(self.fX2, math.e), 0.0, places=1)

        assert_almost_equal(entropy(self.fX3), 0.0, places=1)
        assert_almost_equal(entropy(self.fX3, 10), 0.0, places=1)
        assert_almost_equal(entropy(self.fX3, math.e), 0.0, places=1)

    def inf_theory_test_1(self):
        """
        H(X, Y)
        """

        assert_almost_equal(entropy(self.fXY1), 2.0, places=1)
        assert_almost_equal(entropy(self.fXY1, 10), 0.60206, places=5)
        assert_almost_equal(entropy(self.fXY1, math.e), 1.3863, places=4)

        assert_almost_equal(entropy(self.fXY2), 1.8464, places=4)
        assert_almost_equal(entropy(self.fXY2, 10), 0.55583, places=5)
        assert_almost_equal(entropy(self.fXY2, math.e), 1.2799, places=4)

        assert_almost_equal(entropy(self.fXY3), 1.8464, places=4)
        assert_almost_equal(entropy(self.fXY3, 10), 0.55583, places=5)
        assert_almost_equal(entropy(self.fXY3, math.e), 1.2799, places=4)

    def inf_theory_test_2(self):
        """
        KLD(P1 | Q1)
        """

        res = [
            kullbackLeiblerDistance(self.P1, self.Q1),
            kullbackLeiblerDistance(self.P1, self.Q1, 10),
            kullbackLeiblerDistance(self.P1, self.Q1, math.e)
        ]

        assert_almost_equal(res[0], 0.73697, places=4)
        assert_almost_equal(res[1], 0.22185, places=4)
        assert_almost_equal(res[2], 0.51083, places=4)

    def inf_theory_test_3(self):
        """
        KLD(P2 | Q2)
        """

        res = [
            kullbackLeiblerDistance(self.P2, self.Q2),
            kullbackLeiblerDistance(self.P2, self.Q2, 10),
            kullbackLeiblerDistance(self.P2, self.Q2, math.e)
        ]

        assert_almost_equal(res[0], 0.32193, places=4)
        assert_almost_equal(res[1], 0.09691, places=4)
        assert_almost_equal(res[2], 0.22314, places=4)

    def inf_theory_test_4(self):
        """
        KLD(Q1 | P1)
        """

        res = [
            kullbackLeiblerDistance(self.Q1, self.P1),
            kullbackLeiblerDistance(self.Q1, self.P1, 10),
            kullbackLeiblerDistance(self.Q1, self.P1, math.e)
        ]

        assert_almost_equal(res[0], 0.53100, places=5)
        assert_almost_equal(res[1], 0.15985, places=5)
        assert_almost_equal(res[2], 0.36806, places=5)

    def inf_theory_test_5(self):
        """
        KLD(Q2 | P2)
        """

        res = [
            kullbackLeiblerDistance(self.Q2, self.P2),
            kullbackLeiblerDistance(self.Q2, self.P2, 10),
            kullbackLeiblerDistance(self.Q2, self.P2, math.e)
        ]

        assert_almost_equal(res[0], 2.4527, places=4)
        assert_almost_equal(res[1], 0.73834, places=5)
        assert_almost_equal(res[2], 1.7001, places=4)

    def inf_theory_test_6(self):
        """
        I(X ; Y)
        """

        fac1 = self.fXY1.marginal(self.X)
        fac2 = self.fXY1.marginal(self.Y)

        res = [
            mutualInformation(self.fXY1, fac1, fac2),
            mutualInformation(self.fXY1, fac1, fac2, 10),
            mutualInformation(self.fXY1, fac1, fac2, math.e)
        ]

        assert_almost_equal(res[0], 0.0, places=1)
        assert_almost_equal(res[1], 0.0, places=1)
        assert_almost_equal(res[2], 0.0, places=1)

    def inf_theory_test_7(self):
        """
        I(X ; Y)
        """

        joint = Factor([self.X, self.Y], [0.8, 0.05, 0.05, 0.8])
        fac1 = self.fXY1.marginal(self.X)
        fac2 = self.fXY1.marginal(self.Y)

        res = [
            mutualInformation(joint, fac1, fac2),
            mutualInformation(joint, fac1, fac2, 10),
            mutualInformation(joint, fac1, fac2, math.e)
        ]

        assert_almost_equal(res[0], 2.4527, places=4)
        assert_almost_equal(res[1], 0.73834, places=5)
        assert_almost_equal(res[2], 1.7001, places=5)
Esempio n. 26
0
class TestInfTheoryValue(TestBase):
    def __init__(self):
        TestBase.__init__(self)

        # factors for information theory testing
        self.fX1 = Factor(self.X, [0.5, 0.5])
        self.fX2 = Factor(self.X, [0.0, 1.0])
        self.fX3 = Factor(self.X, [1.0, 0.0])

        self.fXY1 = Factor([self.X, self.Y], [0.25, 0.25, 0.25, 0.25])
        self.fXY2 = Factor([self.X, self.Y], [0.1, 0.2, 0.3, 0.4])
        self.fXY3 = Factor([self.X, self.Y], [0.4, 0.3, 0.2, 0.1])

        self.P1 = Factor([self.X], [0.5, 0.5])
        self.Q1 = Factor([self.X], [0.9, 0.1])

        self.P2 = Factor([self.X, self.Y], [0.25, 0.25, 0.25, 0.25])
        self.Q2 = Factor([self.X, self.Y], [0.8, 0.05, 0.05, 0.8])

    def inf_theory_test_0(self):
        """
        H(X)
        """

        assert_almost_equal(entropy(self.fX1), 1.0, places=1)
        assert_almost_equal(entropy(self.fX1, 10), 0.30103, places=5)
        assert_almost_equal(entropy(self.fX1, math.e), 0.69315, places=5)

        assert_almost_equal(entropy(self.fX2), 0.0, places=1)
        assert_almost_equal(entropy(self.fX2, 10), 0.0, places=1)
        assert_almost_equal(entropy(self.fX2, math.e), 0.0, places=1)

        assert_almost_equal(entropy(self.fX3), 0.0, places=1)
        assert_almost_equal(entropy(self.fX3, 10), 0.0, places=1)
        assert_almost_equal(entropy(self.fX3, math.e), 0.0, places=1)

    def inf_theory_test_1(self):
        """
        H(X, Y)
        """

        assert_almost_equal(entropy(self.fXY1), 2.0, places=1)
        assert_almost_equal(entropy(self.fXY1, 10), 0.60206, places=5)
        assert_almost_equal(entropy(self.fXY1, math.e), 1.3863, places=4)

        assert_almost_equal(entropy(self.fXY2), 1.8464, places=4)
        assert_almost_equal(entropy(self.fXY2, 10), 0.55583, places=5)
        assert_almost_equal(entropy(self.fXY2, math.e), 1.2799, places=4)

        assert_almost_equal(entropy(self.fXY3), 1.8464, places=4)
        assert_almost_equal(entropy(self.fXY3, 10), 0.55583, places=5)
        assert_almost_equal(entropy(self.fXY3, math.e), 1.2799, places=4)

    def inf_theory_test_2(self):
        """
        KLD(P1 | Q1)
        """

        res = [kullbackLeiblerDistance(self.P1, self.Q1),
               kullbackLeiblerDistance(self.P1, self.Q1, 10),
               kullbackLeiblerDistance(self.P1, self.Q1, math.e)]

        assert_almost_equal(res[0], 0.73697, places=4)
        assert_almost_equal(res[1], 0.22185, places=4)
        assert_almost_equal(res[2], 0.51083, places=4)

    def inf_theory_test_3(self):
        """
        KLD(P2 | Q2)
        """

        res = [kullbackLeiblerDistance(self.P2, self.Q2),
               kullbackLeiblerDistance(self.P2, self.Q2, 10),
               kullbackLeiblerDistance(self.P2, self.Q2, math.e)]

        assert_almost_equal(res[0], 0.32193, places=4)
        assert_almost_equal(res[1], 0.09691, places=4)
        assert_almost_equal(res[2], 0.22314, places=4)

    def inf_theory_test_4(self):
        """
        KLD(Q1 | P1)
        """

        res = [kullbackLeiblerDistance(self.Q1, self.P1),
               kullbackLeiblerDistance(self.Q1, self.P1, 10),
               kullbackLeiblerDistance(self.Q1, self.P1, math.e)]

        assert_almost_equal(res[0], 0.53100, places=5)
        assert_almost_equal(res[1], 0.15985, places=5)
        assert_almost_equal(res[2], 0.36806, places=5)

    def inf_theory_test_5(self):
        """
        KLD(Q2 | P2)
        """

        res = [kullbackLeiblerDistance(self.Q2, self.P2),
               kullbackLeiblerDistance(self.Q2, self.P2, 10),
               kullbackLeiblerDistance(self.Q2, self.P2, math.e)]

        assert_almost_equal(res[0], 2.4527, places=4)
        assert_almost_equal(res[1], 0.73834, places=5)
        assert_almost_equal(res[2], 1.7001, places=4)

    def inf_theory_test_6(self):
        """
        I(X ; Y)
        """

        fac1 = self.fXY1.marginal(self.X)
        fac2 = self.fXY1.marginal(self.Y)

        res = [mutualInformation(self.fXY1, fac1, fac2),
               mutualInformation(self.fXY1, fac1, fac2, 10),
               mutualInformation(self.fXY1, fac1, fac2, math.e)]

        assert_almost_equal(res[0], 0.0, places=1)
        assert_almost_equal(res[1], 0.0, places=1)
        assert_almost_equal(res[2], 0.0, places=1)

    def inf_theory_test_7(self):
        """
        I(X ; Y)
        """

        joint = Factor([self.X, self.Y], [0.8, 0.05, 0.05, 0.8])
        fac1 = self.fXY1.marginal(self.X)
        fac2 = self.fXY1.marginal(self.Y)

        res = [mutualInformation(joint, fac1, fac2),
               mutualInformation(joint, fac1, fac2, 10),
               mutualInformation(joint, fac1, fac2, math.e)]

        assert_almost_equal(res[0], 2.4527, places=4)
        assert_almost_equal(res[1], 0.73834, places=5)
        assert_almost_equal(res[2], 1.7001, places=5)