Esempio n. 1
0
    def test_from_scope_variables_with_fn(self):
        """"""
        A = NumCatRVariable(
            "A",
            input_data={"outcome-values": [True, False]},
            marginal_distribution=lambda x: 0.6 if x else 0.4,
        )
        B = NumCatRVariable(
            "B",
            input_data={"outcome-values": [True, False]},
            marginal_distribution=lambda x: 0.62 if x else 0.38,
        )

        def phi_ab(scope_product):
            ss = set(scope_product)
            if ss == set([("A", True), ("B", True)]):
                return 0.9
            elif ss == set([("A", True), ("B", False)]):
                return 0.1
            elif ss == set([("A", False), ("B", True)]):
                return 0.2
            elif ss == set([("A", False), ("B", False)]):
                return 0.8
            else:
                raise ValueError("unknown argument")

        f = Factor.from_scope_variables_with_fn(svars=set([A, B]), fn=phi_ab)
        query = set([("A", True), ("B", True)])
        ff = f.phi(query)
        self.assertEqual(round(ff, 2), 0.9)
Esempio n. 2
0
    def setUp(self):
        """"""
        idata = {
            "rain": {
                "outcome-values": [True, False]
            },
            "sprink": {
                "outcome-values": [True, False]
            },
            "wet": {
                "outcome-values": [True, False]
            },
            "road": {
                "outcome-values": [True, False]
            },
            "winter": {
                "outcome-values": [True, False]
            },
            "earthquake": {
                "outcome-values": [True, False]
            },
            "burglary": {
                "outcome-values": [True, False]
            },
            "alarm": {
                "outcome-values": [True, False]
            },
        }
        self.rain = NumCatRVariable(
            input_data=idata["rain"],
            node_id="rain",
            marginal_distribution=lambda x: 0.2 if x is True else 0.8,
        )
        self.sprink = NumCatRVariable(
            node_id="sprink",
            input_data=idata["sprink"],
            marginal_distribution=lambda x: 0.6 if x is True else 0.4,
        )
        self.wet = NumCatRVariable(
            node_id="wet",
            input_data=idata["wet"],
            marginal_distribution=lambda x: 0.7 if x is True else 0.3,
        )
        self.rain_wet = Edge(
            edge_id="rain_wet",
            start_node=self.rain,
            end_node=self.wet,
            edge_type=EdgeType.DIRECTED,
        )
        self.rain_sprink = Edge(
            edge_id="rain_sprink",
            start_node=self.rain,
            end_node=self.sprink,
            edge_type=EdgeType.DIRECTED,
        )
        self.sprink_wet = Edge(
            edge_id="sprink_wet",
            start_node=self.sprink,
            end_node=self.wet,
            edge_type=EdgeType.DIRECTED,
        )

        def sprink_rain_factor(scope_product):
            """"""
            sfs = set(scope_product)
            if sfs == set([("rain", True), ("sprink", True)]):
                return 0.01
            elif sfs == set([("rain", True), ("sprink", False)]):
                return 0.99
            elif sfs == set([("rain", False), ("sprink", True)]):
                return 0.4
            elif sfs == set([("rain", False), ("sprink", False)]):
                return 0.6
            else:
                raise ValueError("unknown product")

        self.rain_sprink_f = Factor.from_scope_variables_with_fn(
            svars=set([self.rain, self.sprink]), fn=sprink_rain_factor)

        def grass_wet_factor(scope_product):
            """"""
            sfs = set(scope_product)
            if sfs == set([("rain", False), ("sprink", False), ("wet", True)]):
                return 0.0
            elif sfs == set([("rain", False), ("sprink", False),
                             ("wet", False)]):
                return 1.0
            elif sfs == set([("rain", False), ("sprink", True),
                             ("wet", True)]):
                return 0.8
            elif sfs == set([("rain", False), ("sprink", True),
                             ("wet", False)]):
                return 0.2
            elif sfs == set([("rain", True), ("sprink", False),
                             ("wet", True)]):
                return 0.9
            elif sfs == set([("rain", True), ("sprink", False),
                             ("wet", False)]):
                return 0.1
            elif sfs == set([("rain", True), ("sprink", True), ("wet", True)]):
                return 0.99
            elif sfs == set([("rain", True), ("sprink", True),
                             ("wet", False)]):
                return 0.01
            else:
                raise ValueError("unknown product")

        self.grass_wet_f = Factor.from_scope_variables_with_fn(
            svars=set([self.rain, self.sprink, self.wet]), fn=grass_wet_factor)

        self.bayes = BayesianNetwork(
            gid="b",
            nodes=set([self.rain, self.sprink, self.wet]),
            edges=set([self.rain_wet, self.rain_sprink, self.sprink_wet]),
            factors=set([self.grass_wet_f, self.rain_sprink_f]),
        )
        #
        # Darwiche 2009, p. 30
        #
        #  Earthquake  Burglary
        #         \    /
        #          \  /
        #         Alarm
        #
        self.EarthquakeN = NumCatRVariable(
            input_data=idata["earthquake"],
            node_id="EarthquakeN",
            marginal_distribution=lambda x: 0.1 if x is True else 0.9,
        )
        self.BurglaryN = NumCatRVariable(
            input_data=idata["burglary"],
            node_id="BurglaryN",
            marginal_distribution=lambda x: 0.2 if x is True else 0.8,
        )
        self.AlarmN = NumCatRVariable(
            input_data=idata["alarm"],
            node_id="AlarmN",
            marginal_distribution=lambda x: 0.2442 if x is True else 0.7558,
        )
        self.burglar_alarm = Edge(
            edge_id="burglar_alarm",
            start_node=self.BurglaryN,
            end_node=self.AlarmN,
            edge_type=EdgeType.DIRECTED,
        )
        self.earthquake_alarm = Edge(
            edge_id="earthquake_alarm",
            start_node=self.EarthquakeN,
            end_node=self.AlarmN,
            edge_type=EdgeType.DIRECTED,
        )

        idata = {"outcome-values": [True, False]}

        self.C = NumCatRVariable(node_id="C",
                                 input_data=idata,
                                 marginal_distribution=lambda x: 0.5)
        self.E = NumCatRVariable(node_id="E",
                                 input_data=idata,
                                 marginal_distribution=lambda x: 0.5)
        self.F = NumCatRVariable(node_id="F",
                                 input_data=idata,
                                 marginal_distribution=lambda x: 0.5)
        self.D = NumCatRVariable(node_id="D",
                                 input_data=idata,
                                 marginal_distribution=lambda x: 0.5)
        self.CE = Edge(
            edge_id="CE",
            start_node=self.C,
            end_node=self.E,
            edge_type=EdgeType.DIRECTED,
        )
        self.ED = Edge(
            edge_id="ED",
            start_node=self.E,
            end_node=self.D,
            edge_type=EdgeType.DIRECTED,
        )
        self.EF = Edge(
            edge_id="EF",
            start_node=self.E,
            end_node=self.F,
            edge_type=EdgeType.DIRECTED,
        )

        def phi_c(scope_product):
            ss = set(scope_product)
            if ss == set([("C", True)]):
                return 0.8
            elif ss == set([("C", False)]):
                return 0.2
            else:
                raise ValueError("scope product unknown")

        def phi_ec(scope_product):
            ss = set(scope_product)
            if ss == set([("C", True), ("E", True)]):
                return 0.9
            elif ss == set([("C", True), ("E", False)]):
                return 0.1
            elif ss == set([("C", False), ("E", True)]):
                return 0.7
            elif ss == set([("C", False), ("E", False)]):
                return 0.3
            else:
                raise ValueError("scope product unknown")

        def phi_fe(scope_product):
            ss = set(scope_product)
            if ss == set([("E", True), ("F", True)]):
                return 0.9
            elif ss == set([("E", True), ("F", False)]):
                return 0.1
            elif ss == set([("E", False), ("F", True)]):
                return 0.5
            elif ss == set([("E", False), ("F", False)]):
                return 0.5
            else:
                raise ValueError("scope product unknown")

        def phi_de(scope_product):
            ss = set(scope_product)
            if ss == set([("E", True), ("D", True)]):
                return 0.7
            elif ss == set([("E", True), ("D", False)]):
                return 0.3
            elif ss == set([("E", False), ("D", True)]):
                return 0.4
            elif ss == set([("E", False), ("D", False)]):
                return 0.6
            else:
                raise ValueError("scope product unknown")

        self.CE_f = Factor(gid="CE_f",
                           scope_vars=set([self.C, self.E]),
                           factor_fn=phi_ec)
        self.C_f = Factor(gid="C_f", scope_vars=set([self.C]), factor_fn=phi_c)
        self.FE_f = Factor(gid="FE_f",
                           scope_vars=set([self.F, self.E]),
                           factor_fn=phi_fe)
        self.DE_f = Factor(gid="DE_f",
                           scope_vars=set([self.D, self.E]),
                           factor_fn=phi_de)
        self.bayes_n = BayesianNetwork(
            gid="ba",
            nodes=set([self.C, self.E, self.D, self.F]),
            edges=set([self.EF, self.CE, self.ED]),
            factors=set([self.C_f, self.DE_f, self.CE_f, self.FE_f]),
        )