def test_sir(self): from numpy import real from scipy.special import lambertw ## Verification test # Test parameters I0 = 1 S0 = 99 R0 = 0 beta = 0.5 gamma = 0.2 # Asymptotic solution parameters N = I0 + S0 + R0 R_0 = beta / gamma s_0 = S0 / N r_0 = R0 / N # Asymptotic solution S_inf = real(-(1 / R_0) * lambertw(-s_0 * R_0 * np.exp(-R_0 * (1 - r_0))) * N) ## Base tolerance md_sir = models.make_sir() df_inf = gr.eval_df( md_sir, gr.df_make( t=1e6, # Approximation of t -> +\infty I0=I0, N=N, beta=beta, gamma=gamma, )) S_inf_comp = df_inf.S.values[-1] # Check relative tolerance self.assertTrue(abs(S_inf - S_inf_comp) / S_inf < 1e-3) self.assertTrue(abs(S_inf - S_inf_comp) / S_inf > 1e-5) ## Refined tolerance md_sir = models.make_sir(rtol=1e-6) df_inf = gr.eval_df( md_sir, gr.df_make( t=1e6, # Approximation of t -> +\infty I0=I0, N=N, beta=beta, gamma=gamma, )) S_inf_comp = df_inf.S.values[-1] # Check relative tolerance self.assertTrue(abs(S_inf - S_inf_comp) / S_inf < 1e-5)
def test_rf(self): ## Fit routine creates usable model md_fit = fit.fit_rf( self.df_tree, md=self.md_tree, max_depth=1, # True tree is a stump seed=101, ) df_res = gr.eval_df(md_fit, self.df_tree[self.md_tree.var]) ## RF can approximately recover a tree; check ends only self.assertTrue( gr.df_equal( df_res[["y_mean", "z_mean"]].iloc[[0, 1, -2, -1]], self.df_tree[["y", "z"]].iloc[[0, 1, -2, -1]] >> gr.tf_rename( y_mean="y", z_mean="z"), close=True, precision=1, )) ## Fit copies model data self.assertTrue(set(md_fit.var) == set(self.md_tree.var)) self.assertTrue( set(md_fit.out) == set(map(lambda s: s + "_mean", self.md_tree.out)))
def test_gp(self): ## Fit routine creates usable model md_fit = fit.fit_gp(self.df_smooth, md=self.md_smooth) df_res = gr.eval_df(md_fit, self.df_smooth[self.md_smooth.var]) ## GP provides std estimates self.assertTrue("y_sd" in df_res.columns) ## GP is an interpolation self.assertTrue( gr.df_equal( df_res[["x", "y_mean", "z_mean"]].rename({ "y_mean": "y", "z_mean": "z" }, axis=1), self.df_smooth, close=True, )) ## Fit copies model data self.assertTrue(set(md_fit.var) == set(self.md_smooth.var)) self.assertTrue( set(md_fit.out) == set( map(lambda s: s + "_mean", self.md_smooth.out)).union( set(map(lambda s: s + "_sd", self.md_smooth.out))))
def test_lolo(self): ## Fit routine creates usable model md_fit = fit.fit_lolo( self.df_tree, md=self.md_tree, max_depth=1, # True tree is a stump seed=102, ) df_res = gr.eval_df(md_fit, self.df_tree[self.md_tree.var]) ## lolo seems to interpolate middle values; check ends only # self.assertTrue( # gr.df_equal( # df_res[["y", "z"]].iloc[[0, 1, -2, -1]], # self.df_tree[["y", "z"]].iloc[[0, 1, -2, -1]], # close=True, # precision=1, # ) # ) ## Fit copies model data, plus predictive sd self.assertTrue(set(md_fit.var) == set(self.md_tree.var)) self.assertTrue( set(md_fit.out) == set( list(map(lambda s: s + "_mean", self.md_tree.out)) + list(map(lambda s: s + "_sd", self.md_tree.out))))
def test_ev_df(self): """Check ev_df() """ df_res = gr.eval_df(self.model_default, df=self.df_test) self.assertTrue( gr.df_equal(df_res, self.model_default >> gr.ev_df(df=self.df_test)))
def test_tran_md(self): md = models.make_test() ## Check for identical responses df = gr.df_make(x0=1, x1=1, x2=1) df_ev = gr.eval_df(md, df=df) df_tf = gr.tran_md(df, md=md) self.assertTrue(gr.df_equal(df_ev, df_tf))
def test_gp(self): ## Fit routine creates usable model md_fit = fit.fit_gp(self.df_smooth, md=self.md_smooth) df_res = gr.eval_df(md_fit, self.df_smooth[self.md_smooth.var]) ## GP provides std estimates # self.assertTrue("y_std" in df_res.columns) ## GP is an interpolation self.assertTrue(gr.df_equal(df_res, self.df_smooth, close=True)) ## Fit copies model data self.assertTrue(set(md_fit.var) == set(self.md_smooth.var)) self.assertTrue(set(md_fit.out) == set(self.md_smooth.out))
def test_comp_model(self): """Test model composition""" md_inner = ( gr.Model("inner") >> gr.cp_function(fun=lambda x: x[0] + x[1], var=2, out=1) >> gr.cp_marginals(x0=dict(dist="norm", loc=0, scale=1)) >> gr.cp_copula_independence() ) ## Deterministic composition md_det = gr.Model("outer_det") >> gr.cp_md_det(md=md_inner) self.assertTrue(set(md_det.var) == {"x0", "x1"}) self.assertTrue(md_det.out == ["y0"]) gr.eval_df(md_det, df=gr.df_make(x0=0, x1=0)) ## Deterministic composition md_sample = gr.Model("outer_det") >> gr.cp_md_sample( md=md_inner, param=dict(x0=("loc", "scale")) ) self.assertTrue(set(md_sample.var) == {"x0_loc", "x0_scale", "x1"}) self.assertTrue(set(md_sample.out) == {"y0"}) gr.eval_df(md_sample, df=gr.df_make(x0_loc=0, x0_scale=1, x1=0))
def test_kmeans(self): ## Fit routine creates usable model var = ["x", "y"] md_fit = fit.fit_kmeans(self.df_cluster, var=var, n_clusters=2) df_res = gr.eval_df(md_fit, self.df_cluster[var]) ## Check correctness # Match clusters by min(x) id_true = (self.df_cluster >> gr.tf_filter(X.x == gr.colmin(X.x))).c[0] id_res = (df_res >> gr.tf_filter(X.x == gr.colmin(X.x))).cluster_id[0] df_res1 = (self.df_cluster >> gr.tf_filter(X.c == id_true) >> gr.tf_select(X.x, X.y)) df_res2 = (df_res >> gr.tf_filter(X.cluster_id == id_res) >> gr.tf_select(X.x, X.y)) self.assertTrue(gr.df_equal(df_res1, df_res2))
def test_fit_polyridge(self): """Test the functionality and correctness of ft_polyridge() """ df_test = (gr.df_make(x=range(10)) >> gr.tf_outer( gr.df_make(y=range(10))) >> gr.tf_outer(gr.df_make(z=range(10))) >> gr.tf_mutate(f=DF.x - DF.y)) md = gr.fit_polyridge(df_test, out="f", n_degree=1, n_dim=1) df1 = gr.eval_df(md, df=gr.df_make(x=[2, 1], y=[1], z=[0])) df2 = gr.df_make(x=[2, 1], y=[1], z=[0], f_mean=[1, 0]) self.assertTrue(gr.df_equal( df1, df2, close=True, ))
def test_lm(self): ## Fit routine creates usable model md_fit = fit.fit_lm( self.df_smooth, md=self.md_smooth, ) df_res = gr.eval_df(md_fit, self.df_smooth[self.md_smooth.var]) ## LM can recover a linear model self.assertTrue( gr.df_equal( df_res, self.df_smooth >> gr.tf_rename(y_mean="y", z_mean="z"), close=True, precision=1, )) ## Fit copies model data self.assertTrue(set(md_fit.var) == set(self.md_smooth.var)) self.assertTrue( set(md_fit.out) == set( map(lambda s: s + "_mean", self.md_smooth.out)))