Esempio n. 1
0
def get_sequential_cid() -> CID:
    """
    This CID is a subtle case of sufficient recall, as the decision rule for D1 influences
    the expected utility of D2, but D2 can still be chosen without knowing D1, since
    D1 does not influence any utility nodes descending from D2.
    """
    cid = CID(
        [
            ("S1", "D1"),
            ("D1", "U1"),
            ("S1", "U1"),
            ("D1", "S2"),
            ("S2", "D2"),
            ("D2", "U2"),
            ("S2", "U2"),
        ],
        decisions=["D1", "D2"],
        utilities=["U1", "U2"],
    )

    cid.add_cpds(
        UniformRandomCPD("S1", [0, 1]),
        DecisionDomain("D1", [0, 1]),
        FunctionCPD("U1", lambda s1, d1: int(s1 == d1)),  # type: ignore
        FunctionCPD("S2", lambda d1: d1),  # type: ignore
        DecisionDomain("D2", [0, 1]),
        FunctionCPD("U2", lambda s2, d2: int(s2 == d2)),  # type: ignore
    )
    return cid
Esempio n. 2
0
def get_introduced_bias() -> CID:

    cid = CID(
        [
            ("A", "X"),  # defining the graph's nodes and edges
            ("Z", "X"),
            ("Z", "Y"),
            ("X", "D"),
            ("X", "Y"),
            ("D", "U"),
            ("Y", "U"),
        ],
        decisions=["D"],
        utilities=["U"],
    )

    cpd_a = UniformRandomCPD("A", [0, 1])
    cpd_z = UniformRandomCPD("Z", [0, 1])
    cpd_x = FunctionCPD("X", lambda a, z: a * z)  # type: ignore
    cpd_d = DecisionDomain("D", [0, 1])
    cpd_y = FunctionCPD("Y", lambda x, z: x + z)  # type: ignore
    cpd_u = FunctionCPD("U", lambda d, y: -((d - y) ** 2))  # type: ignore

    cid.add_cpds(cpd_a, cpd_d, cpd_z, cpd_x, cpd_y, cpd_u)
    return cid
Esempio n. 3
0
def get_sequential_cid() -> CID:
    """
    This CID is a subtle case of sufficient recall, as the decision rule for D1 influences
    the expected utility of D2, but D2 can still be chosen without knowing D1, since
    D1 does not influence any utility nodes descending from D2.
    """
    cid = CID(
        [
            ("S1", "D1"),
            ("D1", "U1"),
            ("S1", "U1"),
            ("D1", "S2"),
            ("S2", "D2"),
            ("D2", "U2"),
            ("S2", "U2"),
        ],
        decisions=["D1", "D2"],
        utilities=["U1", "U2"],
    )

    cid.add_cpds(
        S1=discrete_uniform([0, 1]),
        D1=[0, 1],
        U1=lambda s1, d1: int(s1 == d1),
        S2=lambda d1: d1,
        D2=[0, 1],
        U2=lambda s2, d2: int(s2 == d2),
    )
    return cid
Esempio n. 4
0
def get_introduced_bias() -> CID:

    cid = CID(
        [
            ("A", "X"),  # defining the graph's nodes and edges
            ("Z", "X"),
            ("Z", "Y"),
            ("X", "D"),
            ("X", "Y"),
            ("D", "U"),
            ("Y", "U"),
        ],
        decisions=["D"],
        utilities=["U"],
    )

    cid.add_cpds(
        A=discrete_uniform([0, 1]),
        Z=discrete_uniform([0, 1]),
        X=lambda a, z: a * z,
        D=[0, 1],
        Y=lambda x, z: x + z,
        U=lambda d, y: -((d - y)**2),
    )
    return cid
Esempio n. 5
0
def get_grade_predictor() -> CID:
    cid = CID(
        [("R", "HS"), ("HS", "E"), ("HS", "P"), ("E", "Gr"), ("Gr", "Ac"), ("Ge", "P"), ("P", "Ac")],
        decisions=["P"],
        utilities=["Ac"],
    )

    return cid
Esempio n. 6
0
def get_insufficient_recall_cid() -> CID:
    cid = CID([("A", "U"), ("B", "U")], decisions=["A", "B"], utilities=["U"])
    cid.add_cpds(
        DecisionDomain("A", [0, 1]),
        DecisionDomain("B", [0, 1]),
        FunctionCPD("U", lambda a, b: a * b),  # type: ignore
    )
    return cid
Esempio n. 7
0
def get_modified_content_recommender() -> CID:
    cid = CID(
        [("O", "I"), ("O", "M"), ("M", "P"), ("P", "I"), ("P", "C"), ("M", "C")],
        decisions=["P"],
        utilities=["C"],
    )

    return cid
Esempio n. 8
0
def get_3node_cid() -> CID:
    cid = CID([("S", "D"), ("S", "U"), ("D", "U")],
              decisions=["D"],
              utilities=["U"])
    cpd_s = UniformRandomCPD("S", [-1, 1])
    cpd_u = FunctionCPD("U", lambda s, d: s * d)  # type: ignore
    cpd_d = DecisionDomain("D", [-1, 1])
    cid.add_cpds(cpd_d, cpd_s, cpd_u)
    return cid
Esempio n. 9
0
def get_quantitative_voi_cid() -> CID:
    cid = CID([("S", "X"), ("X", "D"), ("D", "U"), ("S", "U")],
              decisions=["D"],
              utilities=["U"])
    cid.add_cpds(
        S=discrete_uniform([-1, 1]),
        X=lambda s: noisy_copy(s, probability=0.8, domain=[-1, 1]),
        D=[-1, 0, 1],
        U=lambda s, d: int(s) * int(d),
    )
    return cid
Esempio n. 10
0
def get_quantitative_voi_cid() -> CID:
    cid = CID([("S", "X"), ("X", "D"), ("D", "U"), ("S", "U")],
              decisions=["D"],
              utilities=["U"])
    cpd_s = UniformRandomCPD("S", [-1, 1])
    # X takes the value of S with probability 0.8
    cpd_x = StochasticFunctionCPD("X", lambda s: {s: 0.8}, domain=[-1, 1])
    cpd_d = DecisionDomain("D", [-1, 0, 1])
    cpd_u = FunctionCPD("U", lambda s, d: int(s) * int(d))  # type: ignore
    cid.add_cpds(cpd_s, cpd_x, cpd_d, cpd_u)
    return cid
Esempio n. 11
0
def get_5node_cid_with_scaled_utility() -> CID:
    cid = CID(
        [("S1", "D"), ("S1", "U1"), ("S2", "D"), ("S2", "U2"), ("D", "U1"),
         ("D", "U2")],
        decisions=["D"],
        utilities=["U1", "U2"],
    )
    cpd_s1 = UniformRandomCPD("S1", [0, 1])
    cpd_s2 = UniformRandomCPD("S2", [0, 1])
    cpd_u1 = FunctionCPD("U1", lambda s1, d: 10 * int(s1 == d))  # type: ignore
    cpd_u2 = FunctionCPD("U2", lambda s2, d: 2 * int(s2 == d))  # type: ignore
    cpd_d = DecisionDomain("D", [0, 1])
    cid.add_cpds(cpd_d, cpd_s1, cpd_s2, cpd_u1, cpd_u2)
    return cid
Esempio n. 12
0
def get_2dec_cid() -> CID:
    cid = CID(
        [("S1", "S2"), ("S1", "D1"), ("D1", "S2"), ("S2", "U"), ("S2", "D2"),
         ("D2", "U")],
        decisions=["D1", "D2"],
        utilities=["U"],
    )
    cpd_s1 = UniformRandomCPD("S1", [0, 1])
    cpd_d1 = DecisionDomain("D1", [0, 1])
    cpd_d2 = DecisionDomain("D2", [0, 1])
    cpd_s2 = FunctionCPD("S2", lambda s1, d1: int(s1 == d1))  # type: ignore
    cpd_u = FunctionCPD("U", lambda s2, d2: int(s2 == d2))  # type: ignore
    cid.add_cpds(cpd_s1, cpd_d1, cpd_s2, cpd_d2, cpd_u)
    return cid
Esempio n. 13
0
def get_5node_cid_with_scaled_utility() -> CID:
    cid = CID(
        [("S1", "D"), ("S1", "U1"), ("S2", "D"), ("S2", "U2"), ("D", "U1"),
         ("D", "U2")],
        decisions=["D"],
        utilities=["U1", "U2"],
    )
    cid.add_cpds(
        S1=discrete_uniform([0, 1]),
        S2=discrete_uniform([0, 1]),
        U1=lambda s1, d: 10 * int(s1 == d),
        U2=lambda s2, d: 2 * int(s2 == d),
        D=[0, 1],
    )
    return cid
Esempio n. 14
0
def get_2dec_cid() -> CID:
    cid = CID(
        [("S1", "S2"), ("S1", "D1"), ("D1", "S2"), ("S2", "U"), ("S2", "D2"),
         ("D2", "U")],
        decisions=["D1", "D2"],
        utilities=["U"],
    )
    cid.add_cpds(
        S1=discrete_uniform([0, 1]),
        D1=[0, 1],
        D2=[0, 1],
        S2=lambda s1, d1: int(s1 == d1),
        U=lambda s2, d2: int(s2 == d2),
    )
    return cid
Esempio n. 15
0
def get_car_accident_predictor() -> CID:
    cid = CID(
        [
            ("B", "N"),
            ("N", "AP"),
            ("N", "P"),
            ("P", "Race"),
            ("Age", "Adt"),
            ("Adt", "Race"),
            ("Race", "Accu"),
            ("M", "AP"),
            ("AP", "Accu"),
        ],
        decisions=["AP"],
        utilities=["Accu"],
    )

    return cid
Esempio n. 16
0
def get_fitness_tracker() -> CID:
    cid = CID(
        [
            ("TD", "TF"),
            ("TF", "SC"),
            ("TF", "C"),
            ("EF", "EWD"),
            ("EWD", "C"),
            ("C", "F"),
            ("P", "D"),
            ("P", "SC"),
            ("P", "F"),
            ("SC", "C"),
            ("SC", "EWD"),
        ],
        decisions=["C"],
        utilities=["F"],
    )

    return cid
Esempio n. 17
0
def get_trim_example_cid() -> CID:
    cid = CID(
        [
            ("Y1", "D1"),
            ("Y1", "Y2"),
            ("Y1", "D2"),
            ("Y2", "D2"),
            ("Y2", "U"),
            ("D1", "Y2"),
            ("D1", "D2"),
            ("Z1", "D1"),
            ("Z1", "D2"),
            ("Z1", "Z2"),
            ("Z2", "D2"),
            ("D2", "U"),
        ],
        decisions=["D1", "D2"],
        utilities=["U"],
    )
    return cid
Esempio n. 18
0
def get_minimal_cid() -> CID:
    cid = CID([("A", "B")], decisions=["A"], utilities=["B"])
    cpd_a = DecisionDomain("A", [0, 1])
    cpd_b = FunctionCPD("B", lambda a: a)  # type: ignore
    cid.add_cpds(cpd_a, cpd_b)
    return cid
Esempio n. 19
0
def get_minimal_cid() -> CID:
    cid = CID([("A", "B")], decisions=["A"], utilities=["B"])
    cid.add_cpds(A=[0, 1], B=lambda a: a)
    return cid
Esempio n. 20
0
def get_insufficient_recall_cid() -> CID:
    cid = CID([("A", "U"), ("B", "U")], decisions=["A", "B"], utilities=["U"])
    cid.add_cpds(A=[0, 1], B=[0, 1], U=lambda a, b: a * b)
    return cid
Esempio n. 21
0
def random_cid(
    number_of_nodes: int = 8,
    number_of_decisions: int = 1,
    number_of_utilities: int = 1,
    add_cpds: bool = True,
    sufficient_recall: bool = False,
    edge_density: float = 0.4,
    max_in_degree: int = 4,
    max_resampling_attempts: int = 100,
) -> CID:
    """
    Generate a random CID.

    Parameters:
    -----------
    number_of nodes: The total number of nodes in the CID.

    number_of_decisions: The number of decisions in the CID.

    number_of_utilities: The number of utilities in the CID.

    add_cpds: True if we should pararemeterise the CID as a model.
    This adds [0,1] domains to every decision node and RandomCPDs to every utility and chance node in the CID.

    sufficient_recall: True the agent should have sufficient recall of all of its previous decisions.
    An Agent has sufficient recall in a CID if the relevance graph is acyclic.

    edge_density: The density of edges in the CID's DAG as a proportion of the maximum possible number of nodes
    in the DAG - n*(n-1)/2

    max_in_degree: The maximal number of edges incident to a node in the CID's DAG.

    max_resampling_attempts: The maxmimum number of resampling of random DAGs attempts in order to try
    to satisfy all constraints.

    Returns
    -------
    A CID that satisfies the given constraints or a ValueError if it was unable to meet the constraints in the
    specified number of attempts.

    """
    mb = random_macidbase(
        number_of_nodes=number_of_nodes,
        agent_decisions_num=(number_of_decisions,),
        agent_utilities_num=(number_of_utilities,),
        add_cpds=False,
        sufficient_recall=sufficient_recall,
        edge_density=edge_density,
        max_in_degree=max_in_degree,
        max_resampling_attempts=max_resampling_attempts,
    )

    dag = DAG(mb.edges)
    decision_nodes = mb.decisions
    utility_nodes = mb.utilities

    # change the naming style of decision and utility nodes
    dec_name_change = {old_dec_name: "D" + str(i) for i, old_dec_name in enumerate(decision_nodes)}
    util_name_change = {old_util_name: "U" + str(i) for i, old_util_name in enumerate(utility_nodes)}
    node_name_change_map = {**dec_name_change, **util_name_change}
    dag = nx.relabel_nodes(dag, node_name_change_map)

    cid = CID(dag.edges, decisions=list(dec_name_change.values()), utilities=list(util_name_change.values()))

    if add_cpds:
        add_random_cpds(cid)
    return cid
Esempio n. 22
0
def get_3node_cid() -> CID:
    cid = CID([("S", "D"), ("S", "U"), ("D", "U")],
              decisions=["D"],
              utilities=["U"])
    cid.add_cpds(S=discrete_uniform([-1, 1]), U=lambda s, d: s * d, D=[-1, 1])
    return cid