예제 #1
0
    def test_dep_empirical_distrib_continuous(self):
        bn = BNetwork()
        builder = CategoricalTableBuilder("var1")
        builder.add_row(ValueFactory.create("one"), 0.7)
        builder.add_row(ValueFactory.create("two"), 0.3)
        var1 = ChanceNode("var1", builder.build())
        bn.add_node(var1)

        continuous = ContinuousDistribution("var2",
                                            UniformDensityFunction(-1.0, 3.0))
        continuous2 = ContinuousDistribution(
            "var2", GaussianDensityFunction(3.0, 10.0))

        table = ConditionalTable("var2")
        table.add_distrib(Assignment("var1", "one"), continuous)
        table.add_distrib(Assignment("var1", "two"), continuous2)
        var2 = ChanceNode("var2", table)
        var2.add_input_node(var1)
        bn.add_node(var2)

        inference = InferenceChecks()
        inference.check_cdf(bn, "var2", -1.5, 0.021)
        inference.check_cdf(bn, "var2", 0., 0.22)
        inference.check_cdf(bn, "var2", 2., 0.632)
        inference.check_cdf(bn, "var2", 8., 0.98)
예제 #2
0
    def test_switching(self):
        old_factor = SwitchingAlgorithm.max_branching_factor
        SwitchingAlgorithm.max_branching_factor = 4
        network = NetworkExamples.construct_basic_network2()
        distrib = SwitchingAlgorithm().query_prob(
            network, ["Burglary"], Assignment(["JohnCalls", "MaryCalls"]))

        assert isinstance(distrib, MultivariateTable)

        builder = CategoricalTableBuilder("n1")
        builder.add_row(ValueFactory.create("aha"), 1.0)

        n1 = ChanceNode("n1", builder.build())
        network.add_node(n1)
        builder = CategoricalTableBuilder("n2")
        builder.add_row(ValueFactory.create("oho"), 0.7)

        n2 = ChanceNode("n2", builder.build())
        network.add_node(n2)
        builder = CategoricalTableBuilder("n3")
        builder.add_row(ValueFactory.create("ihi"), 0.7)

        n3 = ChanceNode("n3", builder.build())
        network.add_node(n3)
        network.get_node("Alarm").add_input_node(n1)
        network.get_node("Alarm").add_input_node(n2)
        network.get_node("Alarm").add_input_node(n3)

        distrib = SwitchingAlgorithm().query_prob(
            network, ["Burglary"], Assignment(["JohnCalls", "MaryCalls"]))
        assert distrib.__class__ == EmpiricalDistribution

        network.remove_node(n1.get_id())
        network.remove_node(n2.get_id())

        distrib = SwitchingAlgorithm().query_prob(
            network, ["Burglary"], Assignment(["JohnCalls", "MaryCalls"]))
        assert isinstance(distrib, MultivariateTable)

        n1 = ChanceNode(
            "n1",
            ContinuousDistribution("n1", UniformDensityFunction(-2.0, 2.0)))
        n2 = ChanceNode(
            "n2",
            ContinuousDistribution("n2", GaussianDensityFunction(-1.0, 3.0)))

        network.add_node(n1)
        network.add_node(n2)
        network.get_node("Earthquake").add_input_node(n1)
        network.get_node("Earthquake").add_input_node(n2)

        distrib = SwitchingAlgorithm().query_prob(
            network, ["Burglary"], Assignment(["JohnCalls", "MaryCalls"]))
        assert isinstance(distrib, EmpiricalDistribution)

        SwitchingAlgorithm.max_branching_factor = old_factor
예제 #3
0
    def create_chance_node(node):
        """
        Creates a new chance node corresponding to the XML specification

        :param node: the XML node
        :return: the resulting chance node encoded
        """
        if len(node.attrib) == 0:
            raise ValueError()

        try:
            label = node.attrib['id'].strip()
        except:
            raise ValueError()

        if len(label) == 0:
            raise ValueError()

        builder = CategoricalTableBuilder(label)
        distrib = None

        for child_node in node:
            if child_node.tag == 'value':
                # first case: the chance node is described as a categorical table.
                # extracting the value
                prob = XMLStateReader._get_probability(child_node)
                value = ValueFactory.create(child_node.text.strip())
                builder.add_row(value, prob)
            elif child_node.tag == 'distrib':
                # second case: the chance node is described by a parametric continuous distribution.
                try:
                    distrib_type = child_node.attrib['type'].lower()

                    if distrib_type == 'gaussian':
                        distrib = ContinuousDistribution(
                            label, XMLStateReader._get_gaussian(child_node))
                    elif distrib_type == 'uniform':
                        distrib = ContinuousDistribution(
                            label, XMLStateReader._get_uniform(child_node))
                    elif distrib_type == 'dirichlet':
                        distrib = ContinuousDistribution(
                            label, XMLStateReader._get_dirichlet(child_node))
                except:
                    raise ValueError()

        if distrib is not None:
            return ChanceNode(label, distrib)

        total_prob = builder.get_total_prob()
        # TODO: check eps
        eps = 1e-8
        if total_prob > 1.0 + eps:
            raise ValueError()

        return ChanceNode(label, builder.build())
예제 #4
0
 def construct_basic_network4():
     network = NetworkExamples.construct_basic_network()
     node = ChanceNode(
         "gaussian",
         ContinuousDistribution("gaussian", UniformDensityFunction(-2, 3)))
     network.add_node(node)
     return network
예제 #5
0
    def test_continuous(self):
        distrib = ContinuousDistribution("X",
                                         UniformDensityFunction(-2.0, 4.0))
        assert distrib.get_prob_density(1.0) == pytest.approx(1 / 6.0,
                                                              abs=0.0001)
        assert distrib.get_prob_density(4.0) == pytest.approx(1 / 6.0,
                                                              abs=0.0001)
        assert distrib.get_prob_density(-3.0) == pytest.approx(0.0, abs=0.0001)
        assert distrib.get_prob_density(6.0) == pytest.approx(0.0, abs=0.0001)
        assert distrib.to_discrete().get_prob(0.5) == pytest.approx(0.01,
                                                                    abs=0.01)
        assert distrib.to_discrete().get_prob(4) == pytest.approx(0.01,
                                                                  abs=0.01)

        total_prob = 0.0
        for value in distrib.to_discrete().get_posterior(
                Assignment()).get_values():
            total_prob += distrib.to_discrete().get_prob(value)

        assert total_prob == pytest.approx(1.0, abs=0.03)
예제 #6
0
    def test_empirical_distrib_continuous(self):
        continuous = ContinuousDistribution("var1",
                                            UniformDensityFunction(-1.0, 3.0))

        bn = BNetwork()
        var1 = ChanceNode("var1", continuous)
        bn.add_node(var1)

        sampling = SamplingAlgorithm(2000, 200)

        distrib2 = sampling.query_prob(bn, "var1")
        assert len(distrib2.get_posterior(
            Assignment()).get_values()) == pytest.approx(
                Settings.discretization_buckets, abs=2)
        assert distrib2.to_continuous().get_cumulative_prob(
            -1.1) == pytest.approx(0, abs=0.001)
        assert distrib2.to_continuous().get_cumulative_prob(
            1.0) == pytest.approx(0.5, abs=0.06)
        assert distrib2.to_continuous().get_cumulative_prob(
            3.1) == pytest.approx(1.0, abs=0.00)

        assert continuous.get_prob_density(-2.0) == pytest.approx(
            distrib2.to_continuous().get_prob_density(-2.0), abs=0.1)
        assert continuous.get_prob_density(-0.5) == pytest.approx(
            distrib2.to_continuous().get_prob_density(-0.5), abs=0.1)
        assert continuous.get_prob_density(1.8) == pytest.approx(
            distrib2.to_continuous().get_prob_density(1.8), abs=0.1)
        assert continuous.get_prob_density(3.2) == pytest.approx(
            distrib2.to_continuous().get_prob_density(3.2), abs=0.1)
예제 #7
0
    def test_gaussian_distrib(self):
        continuous2 = ContinuousDistribution("var2",
                                             GaussianDensityFunction(2.0, 3.0))
        assert continuous2.get_prob_density(1.2) == pytest.approx(0.2070,
                                                                  abs=0.001)
        assert continuous2.get_prob_density(2.0) == pytest.approx(0.23033,
                                                                  abs=0.001)
        assert continuous2.get_cumulative_prob(2.0) == pytest.approx(0.5,
                                                                     abs=0.001)
        assert continuous2.get_cumulative_prob(3.0) == pytest.approx(0.7181,
                                                                     abs=0.001)
        assert len(continuous2.to_discrete().get_values()
                   ) > Settings.discretization_buckets / 2
        assert len(continuous2.to_discrete().get_values()
                   ) <= Settings.discretization_buckets
        assert continuous2.to_discrete().get_prob(2) == pytest.approx(0.06205,
                                                                      abs=0.01)

        sum = 0.
        for _ in range(10000):
            sum += continuous2.sample().get_double()

        assert sum / 10000.0 == pytest.approx(2.0, abs=0.1)
예제 #8
0
    def create_continuous(self, head_variable):
        """
        Creates a continuous with the defined head variable given the samples

        :param head_variable: the variable for which to create the distribution
        :return: the resulting continuous distribution
        """
        values = []
        for assignment in self._samples:
            value = assignment.get_value(head_variable)
            if isinstance(value, ArrayVal):
                values.append(value.get_array())
            elif isinstance(value, DoubleVal):
                values.append([value.get_double()])
        values = np.array(values)

        return ContinuousDistribution(head_variable,
                                      KernelDensityFunction(values))
예제 #9
0
    def test_uniform_distrib(self):
        continuous2 = ContinuousDistribution("var2",
                                             UniformDensityFunction(-2.0, 3.0))
        assert continuous2.get_prob_density(1.2) == pytest.approx(1 / 5.0,
                                                                  abs=0.001)
        # assert continuous2.get_cumulative_prob(Assignment("var2", # 2)), 4 / 5.0 == 0.001
        assert len(continuous2.to_discrete().get_values()
                   ) == Settings.discretization_buckets
        assert continuous2.get_prob(ValueFactory.create(1.2)) == pytest.approx(
            0.01, abs=0.01)

        sum = 0.
        for _ in range(10000):
            sum += continuous2.sample().get_double()

        assert sum / 10000.0 == pytest.approx(0.5, abs=0.1)
        assert continuous2.get_function().get_mean()[0] == pytest.approx(
            0.5, abs=0.01)
        assert continuous2.get_function().get_variance()[0] == pytest.approx(
            2.08, abs=0.01)
예제 #10
0
    def test_kernel_distrib2(self):
        mkds = KernelDensityFunction(
            np.array([[0.1], [-1.5], [0.6], [1.3], [1.3]]))

        continuous2 = ContinuousDistribution("var2", mkds)

        assert continuous2.get_prob_density(np.array([-2.0])) == pytest.approx(
            0.086, abs=0.003)
        assert continuous2.get_prob_density(np.array([0.6])) == pytest.approx(
            0.32, abs=0.02)
        assert continuous2.get_prob_density(np.array([1.3])) == pytest.approx(
            0.30, abs=0.02)

        sum = 0.
        for _ in range(10000):
            sum += continuous2.sample().get_double()

        assert sum / 10000.0 == pytest.approx(0.424, abs=0.15)
        assert continuous2.to_discrete().get_prob(-1.5) == pytest.approx(
            0.2, abs=0.1)
예제 #11
0
    def to_continuous(self):
        """
        Returns the continuous probability distribution equivalent to the current table

        :return: the continuous equivalent for the distribution could not be converted
        """
        if self._is_continuous():
            points = dict()

            for v in self.get_values():
                if isinstance(v, ArrayVal):
                    points[v.get_array()] = self.get_prob(v)
                elif isinstance(v, DoubleVal):
                    points[(v.get_double(), )] = self.get_prob(v)

            discrete_density_func = DiscreteDensityFunction(points)

            from bn.distribs.continuous_distribution import ContinuousDistribution
            return ContinuousDistribution(self._variable,
                                          discrete_density_func)

        raise ValueError()
예제 #12
0
    def test_dirichlet(self):
        old_discretisation_settings = Settings.discretization_buckets
        Settings.discretization_buckets = 250

        alphas = list()
        alphas.append(40.0)
        alphas.append(80.0)
        alphas = np.array(alphas)

        dirichlet = DirichletDensityFunction(alphas)
        distrib = ContinuousDistribution("x", dirichlet)
        assert isinstance(distrib.sample(), ArrayVal)

        assert 2 == len(distrib.sample())
        assert distrib.sample().get_array()[0] == pytest.approx(0.33, abs=0.15)

        ##############################################
        # dirichlet distribution 자바 코드에 버그가 있음.
        ##############################################
        # assert distrib.get_prob_density(ArrayVal([1./3, 2./3])) == pytest.approx(8.0, abs=0.5)

        n = ChanceNode("x", distrib)
        network = BNetwork()
        network.add_node(n)

        table = VariableElimination().query_prob(network, "x")

        sum = 0.
        for value in table.get_values():
            if value.get_array()[0] < 0.33333:
                sum += table.get_prob(value)

        assert sum == pytest.approx(0.5, abs=0.1)

        conversion1 = VariableElimination().query_prob(network, "x")

        assert abs(
            len(conversion1.get_posterior(Assignment()).get_values()) -
            Settings.discretization_buckets) < 10
        assert conversion1.get_posterior(Assignment()).get_prob(
            ValueFactory.create("[0.3333,0.6666]")) == pytest.approx(0.02,
                                                                     abs=0.05)

        conversion3 = SamplingAlgorithm(4000, 1000).query_prob(network, "x")

        # DistributionViewer(conversion3)
        # Thread.sleep(3000000)

        # TODO: 아래 테스트 케이스 문제 없는지 확인 필요.
        # assert conversion3.to_continuous().get_prob_density(ValueFactory.create("[0.3333,0.6666]")) == pytest.approx(9.0, abs=1.5)

        assert distrib.get_function().get_mean()[0] == pytest.approx(0.333333,
                                                                     abs=0.01)
        assert distrib.get_function().get_variance()[0] == pytest.approx(
            0.002, abs=0.01)

        assert conversion3.to_continuous().get_function().get_mean(
        )[0] == pytest.approx(0.333333, abs=0.05)
        assert conversion3.to_continuous().get_function().get_variance(
        )[0] == pytest.approx(0.002, abs=0.05)

        Settings.discretization_buckets = old_discretisation_settings
예제 #13
0
    def test_kernel_distrib(self):
        kds = KernelDensityFunction(
            np.array([[0.1], [-1.5], [0.6], [1.3], [1.3]]))

        continuous2 = ContinuousDistribution("var2", kds)
        assert continuous2.get_prob_density(-2.0) == pytest.approx(0.086,
                                                                   abs=0.01)
        assert continuous2.get_prob_density(0.6) == pytest.approx(0.32,
                                                                  abs=0.1)
        assert continuous2.get_prob_density(1.3) == pytest.approx(0.30,
                                                                  abs=0.1)
        assert continuous2.get_cumulative_prob(
            ValueFactory.create(-1.6)) == pytest.approx(0.0, abs=0.01)
        assert continuous2.get_cumulative_prob(
            ValueFactory.create(-1.4)) == pytest.approx(0.2, abs=0.01)
        assert continuous2.get_cumulative_prob(
            ValueFactory.create(1.29)) == pytest.approx(0.6, abs=0.01)
        assert continuous2.get_cumulative_prob(
            ValueFactory.create(1.3)) == pytest.approx(1.0, abs=0.01)
        assert continuous2.get_cumulative_prob(
            ValueFactory.create(1.31)) == pytest.approx(1.0, abs=0.01)

        sum = 0.
        for _ in range(20000):
            sum += continuous2.sample().get_double()

        assert sum / 20000.0 == pytest.approx(0.424, abs=0.1)
        # DistributionViewer.showDistributionViewer(continuous2)
        # Thread.sleep(300000000)
        assert continuous2.to_discrete().get_prob(-1.5) == pytest.approx(
            0.2, abs=0.05)

        assert continuous2.get_function().get_mean()[0] == pytest.approx(
            0.36, abs=0.01)
        assert continuous2.get_function().get_variance()[0] == pytest.approx(
            1.07, abs=0.01)
예제 #14
0
    def test_gaussian(self):
        distrib = ContinuousDistribution("X",
                                         GaussianDensityFunction(1.0, 3.0))
        assert distrib.get_prob_density(1.0) == pytest.approx(0.23032,
                                                              abs=0.001)
        assert distrib.get_prob_density(-3.0) == pytest.approx(0.016, abs=0.01)
        assert distrib.get_prob_density(6.0) == pytest.approx(0.00357,
                                                              abs=0.01)
        assert distrib.to_discrete().get_prob(1.0) == pytest.approx(0.06290,
                                                                    abs=0.01)
        assert distrib.to_discrete().get_prob(0.5) == pytest.approx(0.060615,
                                                                    abs=0.01)
        assert distrib.to_discrete().get_prob(4) == pytest.approx(0.014486,
                                                                  abs=0.01)

        total_prob = 0.0
        for value in distrib.to_discrete().get_posterior(
                Assignment()).get_values():
            total_prob += distrib.to_discrete().get_prob(value)

        assert total_prob == pytest.approx(1.0, abs=0.05)
        assert distrib.get_function().get_mean()[0] == pytest.approx(1.0,
                                                                     abs=0.01)
        assert distrib.get_function().get_variance()[0] == pytest.approx(
            3.0, abs=0.01)

        samples = list()
        for _ in range(20000):
            val = [distrib.sample().get_double()]
            samples.append(val)
        samples = np.array(samples)

        estimated = GaussianDensityFunction(samples)
        assert estimated.get_mean()[0] == pytest.approx(
            distrib.get_function().get_mean()[0], abs=0.05)
        assert estimated.get_variance()[0] == pytest.approx(
            distrib.get_function().get_variance()[0], abs=0.1)