def test_manual_size(self): pgm = daft.PGM(shape=[1, 1], origin=[0, 0]) pgm = daft.PGM() pgm.add_node("node1", x=0.0, y=0.0) pgm.add_node("node2", x=1.0, y=0.0) pgm.add_edge("node1", "node2") pgm.render()
def daft_pooled(): # create the PGM pgm = daft.PGM(shape=[4, 2.5], origin=[0, 0], grid_unit=4, label_params={'fontsize': 18}) # priors pgm.add_node(daft.Node("beta", r"$\beta$", 1, 2, scale=2)) # Latent variable. pgm.add_node(daft.Node("mu", r"$\beta X_{n}$", 1, 1, scale=2)) # noise pgm.add_node(daft.Node("epsilon", r"$\epsilon$", 3, 1, scale=2)) # observed data pgm.add_node(daft.Node("y", r"$y_n$", 2, 1, scale=2, observed=True)) # edges pgm.add_edge("beta", "mu") pgm.add_edge("mu", "y") pgm.add_edge("epsilon", "y") # plate pgm.add_plate( daft.Plate([0.5, 0.6, 2, 0.9], label=r"$n \in 1:N$", shift=-0.1)) pgm.render() plt.show()
def weakLensing(): pgm = daft.PGM([4.7, 2.35], origin=[-1.35, 2.2]) pgm.add_node(daft.Node("Omega", r"$\Omega$", -1, 4)) pgm.add_node(daft.Node("rho", r"$\rho$", 0, 4)) pgm.add_node( daft.Node("obs", r"$\epsilon^{\mathrm{obs}}_n$", 1, 4, observed=True)) pgm.add_node(daft.Node("alpha", r"$\alpha$", 3, 4)) pgm.add_node(daft.Node("true", r"$\epsilon^{\mathrm{true}}_n$", 2, 4)) pgm.add_node(daft.Node("sigma", r"$\sigma_n$", 1, 3)) pgm.add_node(daft.Node("Sigma", r"$\Sigma$", 0, 3)) pgm.add_node(daft.Node("x", r"$x_n$", 2, 3, observed=True)) pgm.add_plate(daft.Plate([0.5, 2.25, 2, 2.25], label=r"galaxies $n$")) pgm.add_edge("Omega", "rho") pgm.add_edge("rho", "obs") pgm.add_edge("alpha", "true") pgm.add_edge("true", "obs") pgm.add_edge("x", "obs") pgm.add_edge("Sigma", "sigma") pgm.add_edge("sigma", "obs") pgm.render() pgm.figure.savefig("weaklensing.pdf")
def plot(self, layout=None, show_observed=False): layout = layout or Layout() layout.compute_dag(self.dag) from matplotlib import rc rc("font", family="serif", size=12) rc("text", usetex=True) import daft pgm = daft.PGM([layout.Lx, layout.Ly], origin=[0, 0]) nodes = nx.topological_sort(self.dag) n_nodes = len(nodes) id_obs = 0 for l_node, node in enumerate(nodes): x = layout.dag.node[node]["x"] y = layout.dag.node[node]["y"] fixed = isinstance(node, Factor) or isinstance(node, PlaceHolder) pgm.add_node(daft.Node( l_node, node.math(), x, y, fixed=fixed )) if isinstance(node, Likelihood): l_obs = n_nodes + id_obs pgm.add_node(daft.Node( l_obs, node.y_name, x + layout.dx, y, observed=True )) pgm.add_edge(l_node, l_obs) id_obs += 1 for source, target in self.dag.edges(): l_source = nodes.index(source) l_target = nodes.index(target) pgm.add_edge(l_source, l_target) pgm.render()
def test_add_text(): with daft.PGM() as pgm: pgm.add_text(x=0, y=0, label="text1") plate = pgm._plates[0] assert plate.rect == [0, 0, 0, 0] assert plate.label == "text1"
def make_normal_model_graph(): arrow_params = {"linewidth": 2, "head_width": 0.25} mu_node = daft.Node("mu", r"$\mu$", 1, 2.5, scale=2) x_node = daft.Node("x", "x", 3.5, 2.5, scale=2, observed=True) x_plate = daft.Plate([2.5, 1.5, 2, 2], label=r"$N$", position="bottom right") normal_model_graph = daft.PGM([5, 5], line_width=2, label_params={"fontsize": 32}) normal_model_graph.add_node(mu_node) normal_model_graph.add_node(x_node) normal_model_graph.add_edge("mu", "x", **arrow_params) normal_model_graph.add_plate(x_plate) # Avoid fill with blue in newer versions of matplotlib normal_model_graph._plates[0].bbox["fc"] = "white" normal_model_graph.render() return normal_model_graph
def pgm_cepheids(): # Instantiate a PGM. pgm = daft.PGM([2.9, 2.7], origin=[0.3, 0.3], grid_unit=2.6, node_unit=1.3, observed_style="inner") # Model parameters: pgm.add_node(daft.Node("a", r"$a$", 1.0, 2.6)) pgm.add_node(daft.Node("b", r"$b$", 2.0, 2.6)) # Latent variable - intrinsic magnitude: pgm.add_node(daft.Node("m", r"$m_k$", 1.5, 1.4, fixed=True, offset=(0,-20))) # Data - observed magnitude: pgm.add_node(daft.Node("mobs", r"$m^{\rm obs}_k$", 2.5, 1.4, observed=True)) # Constants - magnitude errors and log Periods: pgm.add_node(daft.Node("logP", r"$\log_{10} P_k$", 0.9, 1.4, fixed=True, offset=(-3,1))) pgm.add_node(daft.Node("merr", r"$\sigma_k$", 1.9, 0.9, fixed=True, offset=(-3,2))) # Add in the edges. pgm.add_edge("a", "m") pgm.add_edge("b", "m") pgm.add_edge("logP", "m") pgm.add_edge("merr", "mobs") pgm.add_edge("m", "mobs") # And a plate for the pixels pgm.add_plate(daft.Plate([0.5, 0.7, 2.5, 1.4], label=r"cepheids $k$", shift=-0.1)) # Render and save. pgm.render() pgm.figure.savefig("pgms_cepheids.png", dpi=300) return
def test_huey_p_newton(): pgm = daft.PGM() kx, ky = 1.5, 1.0 nx, ny = kx + 3.0, ky + 0.0 hx, hy, dhx = kx - 0.5, ky + 1.0, 1.0 pgm.add_node("dyn", r"$\theta_{{dyn}}$", hx + 0.0 * dhx, hy + 0.0) pgm.add_node("ic", r"$\theta_{{I.C.}}$", hx + 1.0 * dhx, hy + 0.0) pgm.add_node("sun", r"$\theta_{\odot}$", hx + 2.0 * dhx, hy + 0.0) pgm.add_node("bg", r"$\theta_{{bg}}$", hx + 3.0 * dhx, hy + 0.0) pgm.add_node("Sigma", r"$\Sigma^2$", hx + 4.0 * dhx, hy + 0.0) pgm.add_plate([kx - 0.5, ky - 0.6, 2.0, 1.1], label=r"model points $k$") pgm.add_node("xk", r"$x_k$", kx + 0.0, ky + 0.0) pgm.add_edge("dyn", "xk") pgm.add_edge("ic", "xk") pgm.add_node("yk", r"$y_k$", kx + 1.0, ky + 0.0) pgm.add_edge("sun", "yk") pgm.add_edge("xk", "yk") pgm.add_plate([nx - 0.5, ny - 0.6, 2.0, 1.1], label=r"data points $n$") pgm.add_node("sigman", r"$\sigma^2_n$", nx + 1.0, ny + 0.0, observed=True) pgm.add_node("Yn", r"$Y_n$", nx + 0.0, ny + 0.0, observed=True) pgm.add_edge("bg", "Yn") pgm.add_edge("Sigma", "Yn") pgm.add_edge("Sigma", "Yn") pgm.add_edge("yk", "Yn") pgm.add_edge("sigman", "Yn") # Render and save. pgm.render()
def draw_network(self): pgm = daft.PGM([2.3, 2.05], origin=[0.3, 0.3]) for layer in self.layers: self.draw_layer(pgm, layer)
def test_overlap_nodes(): with daft.PGM() as pgm: pgm.add_node("node1", x=0, y=0) pgm.add_node("node2", x=0, y=0) pgm.add_edge("node1", "node2") with pytest.raises(daft.SameLocationError): pgm.render()
def make_bivariate_graph(param, obs, observed=False, plate=False, scale=2): arrow_params = {"linewidth": 2, "head_width": 0.25} if param == "sigma": param_string = r"$\sigma$" elif param == "mu": param_string = r"$\mu$" else: param_string = param param_node = daft.Node("param", param_string, 1, 2.5, scale=scale) obs_node = daft.Node("obs", obs, 3.5, 2.5, scale=scale, observed=observed) obs_plate = daft.Plate([2.5, 1.5, 2, 2], label=r"$N$", position="bottom right") bivariate_model_graph = daft.PGM([5, 5], line_width=2, label_params={"fontsize": 32}) bivariate_model_graph.add_node(param_node) bivariate_model_graph.add_node(obs_node) bivariate_model_graph.add_edge("param", "obs", **arrow_params) if plate: bivariate_model_graph.add_plate(obs_plate) # Avoid fill with blue in newer versions of matplotlib bivariate_model_graph._plates[0].bbox["fc"] = "white" bivariate_model_graph.render() return bivariate_model_graph
def make_parameters_graph(observed=True, plate=False): arrow_params = {"linewidth": 2, "head_width": 0.25} in_nodes = [ daft.Node(f"theta_{ii}", f"$\\beta_{ii}$", 1, 4 - 1.5 * ii, scale=2, observed=observed) for ii in range(3) ] x_node = daft.Node("x", "x", 3.5, 2.5, scale=2, observed=False) parameters_graph = daft.PGM([5, 5], line_width=2, label_params={"fontsize": 32}) [parameters_graph.add_node(node) for node in in_nodes] parameters_graph.add_node(x_node) [ parameters_graph.add_edge(f"theta_{ii}", "x", **arrow_params) for ii in range(3) ] parameters_graph.render() return parameters_graph
def display_mdma_model(): s, asp = 3, 1.25 dose_node = daft.Node("dose", "MDMA\nDose", 1, 3, scale=s, aspect=asp) social_node = daft.Node("social_setting", "Social\nSetting", 1, 1, scale=s, aspect=asp) esteem_node = daft.Node("esteem", "Self\nEsteem", 5, 3, scale=s, aspect=asp) mood_node = daft.Node("mood", "Mood", 5, 1, scale=s, aspect=asp) mdma_model = daft.PGM([7, 4], line_width=4, label_params={ "fontsize": 16, "fontweight": "bold" }) nodes = [dose_node, social_node, esteem_node, mood_node] edges = [("dose", "esteem"), ("dose", "mood"), ("social_setting", "esteem"), ("social_setting", "mood")] [mdma_model.add_node(node) for node in nodes] [mdma_model.add_edge(*edge) for edge in edges] mdma_model.render()
def test_add_text(self): pgm = daft.PGM() pgm.add_text(x=0, y=0, label="text1") plate = pgm._plates[0] assert plate.rect == [0, 0, 0, 0] assert plate.label == "text1"
def test_mrf(): pgm = daft.PGM(node_unit=0.4, grid_unit=1, directed=False) for i, (xi, yi) in enumerate(itertools.product(range(1, 5), range(1, 5))): pgm.add_node(str(i), "", xi, yi) for e in [ (4, 9), (6, 7), (3, 7), (10, 11), (10, 9), (10, 14), (10, 6), (10, 7), (1, 2), (1, 5), (1, 0), (1, 6), (8, 12), (12, 13), (13, 14), (15, 11), ]: pgm.add_edge(str(e[0]), str(e[1])) pgm.render()
def show_model(self): """Render the model as a Bayes net using daft.""" import daft gray = ".3" pgm = daft.PGM((3.5, 4), node_ec=gray) scale = 1.5 pgm.add_node(daft.Node("k", r"$k$", 1.5, 3.5, scale)) pgm.add_node(daft.Node("vim1", r"$v_{i-1}$", .5, 2.5, scale)) pgm.add_node(daft.Node("vi", r"$v_i$", 2.5, 2.5, scale)) pgm.add_node(daft.Node("pim1", r"$p_{i-1}$", 1, 1.5, scale)) pgm.add_node(daft.Node("pi", r"$p_i$", 3, 1.5, scale)) pgm.add_node( daft.Node("yim1", r"$y_{i-1}$", 1, .5, scale, observed=True)) pgm.add_node(daft.Node("yi", r"$y_i$", 3, .5, scale, observed=True)) pgm.add_edge("k", "vim1") pgm.add_edge("k", "vi") pgm.add_edge("vim1", "pim1") pgm.add_edge("vi", "pi") pgm.add_edge("vim1", "vi") pgm.add_edge("pim1", "pi") pgm.add_edge("pim1", "yim1") pgm.add_edge("pi", "yi") pgm.render() return pgm
def test_fixed(): pgm = daft.PGM(aspect=1.5, node_unit=1.75) pgm.add_node("unobs", r"Unobserved!", 1, 4) pgm.add_node("obs", r"Observed!", 1, 3, observed=True) pgm.add_node("alt", r"Alternate!", 1, 2, alternate=True) pgm.add_node( "fixed", r"Fixed!", 1, 1, fixed=True, aspect=1.0, offset=[0, 5] ) pgm.render()
def test_bca(): pgm = daft.PGM() pgm.add_node("a", r"$a$", 1, 5) pgm.add_node("b", r"$b$", 1, 4) pgm.add_node("c", r"$c_n$", 1, 3, observed=True) pgm.add_plate([0.5, 2.25, 1, 1.25], label=r"data $n$") pgm.add_edge("a", "b") pgm.add_edge("b", "c") pgm.render()
def test_add_edge(): with daft.PGM() as pgm: pgm.add_node("node1") pgm.add_node("node2") pgm.add_edge(name1="node1", name2="node2") edge = pgm._edges[0] assert edge.node1 == pgm._nodes["node1"] assert edge.node2 == pgm._nodes["node2"]
def test_add_edge(self): pgm = daft.PGM() pgm.add_node("node1") pgm.add_node("node2") pgm.add_edge(name1="node1", name2="node2") edge = pgm._edges[0] assert edge.node1 == pgm._nodes["node1"] assert edge.node2 == pgm._nodes["node2"]
def display_huth_model(): s, asp = 3, 1.25 empty_params = {"linewidth": 0} semantic_node = daft.Node("semantic", "Semantic\nContent", 1, 3, scale=s, aspect=asp) voxel1_node = daft.Node("voxel1", "voxel1", 5, 5, scale=s, aspect=asp) empty1_node = daft.Node("empty1", "", 5, 4, scale=s, aspect=asp, plot_params=empty_params) ellipsis = daft.Node("ellipsis", "...", 5, 3, scale=s, aspect=asp, plot_params=empty_params) emptyN_node = daft.Node("emptyN", "", 5, 2, scale=s, aspect=asp, plot_params=empty_params) voxelN_node = daft.Node("voxelN", "voxelN", 5, 1, scale=s, aspect=asp) huth_model = daft.PGM([7, 6], line_width=4, label_params={ "fontsize": 16, "fontweight": "bold" }) nodes = [ voxel1_node, voxelN_node, semantic_node, ellipsis, empty1_node, emptyN_node ] edges = [("semantic", "voxel1"), ("semantic", "empty1"), ("semantic", "ellipsis"), ("semantic", "emptyN"), ("semantic", "voxelN")] [huth_model.add_node(node) for node in nodes] [huth_model.add_edge(*edge) for edge in edges] huth_model.render()
def test_logo(): pgm = daft.PGM() pgm.add_node("d", r"$D$", 0.5, 0.5) pgm.add_node("a", r"$a$", 1.5, 0.5, observed=True) pgm.add_node("f", r"$f$", 2.5, 0.5) pgm.add_node("t", r"$t$", 3.5, 0.5) pgm.add_edge("d", "a") pgm.add_edge("a", "f") pgm.add_edge("f", "t") pgm.render()
def show(self): self.dag = self.create_dag() for node_key, node_items in self.nodes.items(): self.dag.nodes.add(node_key) for e in node_items['edges']: self.dag.edges.add((node_key, e)) self.dag.coordinates[node_key] = (node_items['coordinate']) self.dag.gm = CausalGraphicalModel(nodes=self.dag.nodes, edges=self.dag.edges) self.dag.pgm = daft.PGM() pgm = daft.PGM() for node in self.dag.gm.dag.nodes: pgm.add_node(node, node, *self.dag.coordinates[node]) for edge in self.dag.gm.dag.edges: pgm.add_edge(*edge) pgm.render() plt.gca() #.invert_yaxis()
def make_figure_8p13(): """Create a graph like figure 8.13.""" pgm = daft.PGM([3, 2], origin=[-0.3, -0.3]) pgm.add_node(daft.Node("x1", r"$x_1$", 0.2, 1.3, observed=True)) pgm.add_node(daft.Node("xm", r"$x_M$", 1.8, 1.3, observed=True)) pgm.add_node(daft.Node("y", r"$y$", 1.0, 0.3, observed=True)) pgm.add_edge("x1", "xm", directed=False, ls=":") pgm.add_edge("x1", "y") pgm.add_edge("xm", "y") pgm.render() pgm.figure.savefig("figures/fig_8p13.pdf")
def make_figure_8p1(): """Make the intro graph.""" pgm = daft.PGM([2.5, 2.5], origin=[-0.3, -0.3]) pgm.add_node(daft.Node("a", r"a", 1., 1.8, observed=True)) pgm.add_node(daft.Node("b", r"b", 0.2, 0.2, observed=True)) pgm.add_node(daft.Node("c", r"c", 1.8, 0.2, observed=True)) pgm.add_edge("a", "b") pgm.add_edge("b", "c") pgm.add_edge("a", "c") pgm.render() pgm.figure.savefig("figures/fig_8p1.pdf")
def test_no_circles(): pgm = daft.PGM(node_ec="none") pgm.add_node("cloudy", r"cloudy", 3, 3) pgm.add_node("rain", r"rain", 2, 2) pgm.add_node("sprinkler", r"sprinkler", 4, 2) pgm.add_node("wet", r"grass wet", 3, 1) pgm.add_edge("cloudy", "rain") pgm.add_edge("cloudy", "sprinkler") pgm.add_edge("rain", "wet") pgm.add_edge("sprinkler", "wet") pgm.render()
def plot_gmm_plate(filename="gmm.png", dpi=100): pgm = daft.PGM([3.0, 2.5], origin=(0, 0)) pgm.add_node(daft.Node("theta", r"$\mathbf{\theta}$", 1, 2, fixed=True)) pgm.add_node(daft.Node("ti", r"$\mathbf{t}_i$", 1, 1)) pgm.add_node(daft.Node("xi", r"$\mathbf{x}_i$", 2, 1, observed=True)) pgm.add_edge("theta", "ti") pgm.add_edge("theta", "xi") pgm.add_edge("ti", "xi") pgm.add_plate(daft.Plate([0.4, 0.5, 2.2, 1.0], label=r"$N$")) ax = pgm.render() ax.text(0.8, 0.5, 'Gaussian mixture model') pgm.savefig(filename, dpi=dpi)
def daft_hier(): # create the PGM pgm = daft.PGM(shape=[7, 2.5], origin=[0, 0], grid_unit=4, label_params={'fontsize': 18}) # priors pgm.add_node(daft.Node("beta_parent_mu", r"$\mu_{parent}$", 1, 1, scale=2)) pgm.add_node( daft.Node("beta_parent_sd", r"$\sigma_{parent}$", 2, 2.2, scale=2)) pgm.add_node(daft.Node("beta_mfr_mu", r"$\mu_{mfr}$", 2, 1, scale=2)) pgm.add_node(daft.Node("beta_mfr_sd", r"$\sigma_{mfr}$", 3, 2.2, scale=2)) pgm.add_node(daft.Node("beta_mfr", r"$\beta_{mfr}$", 3, 1, scale=2)) pgm.add_node(daft.Node("beta", r"$\beta$", 4, 2.2, scale=2)) # latent variable. pgm.add_node(daft.Node("mu", r"$\beta X_{n}$", 4, 1, scale=2)) # noise pgm.add_node(daft.Node("epsilon", r"$\epsilon$", 6.2, 1, scale=2)) # observed data pgm.add_node(daft.Node("y", r"$y_n$", 5, 1, scale=2, observed=True)) # edges pgm.add_edge("beta_parent_mu", "beta_mfr_mu") pgm.add_edge("beta_parent_sd", "beta_mfr_mu") pgm.add_edge("beta_mfr_mu", "beta_mfr") pgm.add_edge("beta_mfr_sd", "beta_mfr") pgm.add_edge("beta_mfr", "mu") pgm.add_edge("beta", "mu") pgm.add_edge("mu", "y") pgm.add_edge("epsilon", "y") # plates pgm.add_plate( daft.Plate([3.5, 0.6, 2, 0.9], label=r"$n \in 1:N$", shift=-0.1)) pgm.add_plate( daft.Plate([2.5, 0.5, 3.1, 1.1], label=r"$mfr \in 1:N_{mfr}$", shift=-0.1)) pgm.add_plate( daft.Plate([1.5, 0.4, 4.2, 1.3], label=r"$parent \in 1:N_{parent}$", shift=-0.1)) pgm.render() plt.show()
def test_recursive(): def recurse(pgm, nodename, level, c): if level > 4: return nodename r = c // 2 r1nodename = "r{0:02d}{1:04d}".format(level, r) if 2 * r == c: # print("adding {0}".format(r1nodename)) pgm.add_node( r1nodename, r"reduce", 2**level * (r + 0.5) - 0.5, 3 - 0.7 * level, aspect=1.9, ) pgm.add_edge(nodename, r1nodename) if 2 * r == c: return recurse(pgm, r1nodename, level + 1, r) pgm = daft.PGM() pgm.add_node( "query", r'"kittens?"', 3, 6.0, aspect=3.0, plot_params={"ec": "none"}, ) pgm.add_node("input", r"input", 7.5, 6.0, aspect=3.0) pgm.add_edge("query", "input") for c in range(16): nodename = "map {0:02d}".format(c) pgm.add_node(nodename, str(nodename), c, 3.0, aspect=1.9) pgm.add_edge("input", nodename) level = 1 recurse(pgm, nodename, level, c) pgm.add_node("output", r"output", 7.5, -1.0, aspect=3.0) pgm.add_edge("r040000", "output") pgm.add_node( "answer", r'"http://dwh.gg/"', 12.0, -1.0, aspect=4.5, plot_params={"ec": "none"}, ) pgm.add_edge("output", "answer") pgm.render()
def make_figure_8p9(): """Create a pair of graphs like figure 8.9.""" pgm = daft.PGM([3, 2], origin=[-0.3, -0.3]) pgm.add_node( daft.Node("x11", r"$\boldsymbol{x}_1$", 0.2, 1.3, observed=True)) pgm.add_node( daft.Node("x21", r"$\boldsymbol{x}_2$", 1.8, 1.3, observed=True)) pgm.add_node( daft.Node("x12", r"$\boldsymbol{x}_1$", 0.2, 0.3, observed=True)) pgm.add_node( daft.Node("x22", r"$\boldsymbol{x}_2$", 1.8, 0.3, observed=True)) pgm.add_edge("x11", "x21") pgm.render() pgm.figure.savefig("figures/fig_8p9.pdf")