def buildZ(self, normalize=False): Z = [] self.k_gamma = 0 for ran in self.ran_list: id, dims = ran values = [] if id is None: values = np.ones(self.N) else: values = rutils.repeat(self.covariates[id][0], self.covariates[id][1], self.dimensions) self.k_gamma += np.prod(dims[self.n_grouping_dims:]) Z.append( values.reshape((-1, 1)) * np.tile( rutils.kronecker(dims[self.n_grouping_dims:], self.dimensions, self.n_grouping_dims), (self.n_groups, 1))) if self.k_gamma > 0: self.Z = np.hstack(Z) col_norm = np.linalg.norm(self.Z, axis=0) if normalize: print('normalizing Z ...') print(col_norm) self.Z = self.Z / col_norm return col_norm else: self.Z = np.zeros((self.N, 1)) return 0.0
def test_draw_random_only(self, random_effects): np.random.seed(127) dimensions = [9, 3, 2, 2] N = np.prod(dimensions) Y_true = np.zeros(N) dct = {} for i, effect in enumerate(random_effects): Z = rutils.kronecker(effect, dimensions, 0) u = np.random.randn(np.prod(effect)) Y_true += Z.dot(u) dct['intercept' + str(i)] = ([ effect[j] == dimensions[j] for j in range(len(dimensions)) ], None) delta_true = .005 Y = Y_true + np.random.randn(N) * np.sqrt(delta_true) model = LME(dimensions, 1, Y, {}, {}, {}, False, random_effects=dct) model.optimize(inner_print_level=0) model.postVarRandom() n_draws = 1000 _, u_samples = model.draw(n_draws=n_draws) u1 = np.concatenate( [u[:np.prod(random_effects[0][1:])] for u in model.u_soln]) u1_sample_mean = np.mean(u_samples[0].reshape((-1, n_draws)), axis=1) assert np.linalg.norm(u1 - u1_sample_mean) / np.linalg.norm(u1) < .05 u2 = np.concatenate([ u[np.prod(random_effects[0][1:]):np.prod(random_effects[0][1:]) + np.prod(random_effects[1][1:])] for u in model.u_soln ]) u2_sample_mean = np.mean(u_samples[1].reshape((-1, n_draws)), axis=1) assert np.linalg.norm(u2 - u2_sample_mean) / np.linalg.norm(u2) < .05 model.outputDraws() return
def test_random_effect_with_gaussian_prior(self, random_effect, sd): np.random.seed(127) dimensions = [200, 2, 3, 2] N = np.prod(dimensions) Y_true = np.zeros(N) Z = rutils.kronecker(random_effect, dimensions, 0) u = np.random.randn(np.prod(random_effect)) * .5 dct1 = { 'intercept': ([ random_effect[j] == dimensions[j] for j in range(len(dimensions)) ], None) } dct2 = { 'intercept': ([ random_effect[j] == dimensions[j] for j in range(len(dimensions)) ], sd) } delta_true = 0.005 Y_true += Z.dot(u) Y = Y_true + np.random.randn(N) * np.sqrt(delta_true) model1 = LME(dimensions, 1, Y, {}, {}, {}, False, random_effects=dct1) model1.optimize(inner_print_level=0) gamma1 = model1.gamma_soln u_var1 = np.var(model1.u_soln) model2 = LME(dimensions, 1, Y, {}, {}, {}, False, random_effects=dct2) model2.optimize(inner_print_level=0) gamma2 = model2.gamma_soln u_var2 = np.var(model2.u_soln) assert all(gamma1 > gamma2) assert u_var1 > u_var2
def test_repeat_kron(self, full_dims, dims): values = np.random.randn(np.prod(dims)) Z = rutils.kronecker(dims, full_dims, 0) vals = rutils.repeat(values, dims, full_dims) y = np.random.randn(np.prod(full_dims)) vals2 = rutils.repeatTranspose(y, dims, full_dims) assert (np.linalg.norm(Z.dot(values) - vals) < 1e-10 and np.linalg.norm(np.transpose(Z).dot(y) - vals2) < 1e-10)
def test_draw(self, dimensions, random_effects): np.random.seed(127) #dimensions = [9, 3, 2, 2] N = np.prod(dimensions) X = np.ones((N, 2)) X[:, 1] = np.random.randn(N) beta_true = [1., -0.6] Y_true = X.dot(beta_true) dct = {} for i, effect in enumerate(random_effects): Z = rutils.kronecker(effect, dimensions, 0) u = np.random.randn(np.prod(effect)) Y_true += Z.dot(u) dct['intercept' + str(i)] = ([ effect[j] == dimensions[j] for j in range(len(dimensions)) ], None) delta_true = .005 Y = Y_true + np.random.randn(N) * np.sqrt(delta_true) model = LME(dimensions, 1, Y, {'cov': (X[:, 1], [True] * len(dimensions))}, {}, {'cov': [-float('inf'), float('inf')]}, True, random_effects=dct) model.optimize(inner_print_level=0) model.postVarGlobal() if len(random_effects) > 0: model.postVarRandom() n_draws = 1000 beta_samples, u_samples = model.draw(n_draws=n_draws) beta_sample_mean = np.mean(beta_samples, axis=1) assert np.linalg.norm(beta_sample_mean - model.beta_soln ) / np.linalg.norm(model.beta_soln) < .02 if len(random_effects) > 0: u1 = np.concatenate( [u[:np.prod(random_effects[0][1:])] for u in model.u_soln]) u1_sample_mean = np.mean(u_samples[0].reshape((-1, n_draws)), axis=1) assert np.linalg.norm(u1 - u1_sample_mean) / np.linalg.norm(u1) < .05 u2 = np.concatenate([ u[np.prod(random_effects[0][1:] ):np.prod(random_effects[0][1:]) + np.prod(random_effects[1][1:])] for u in model.u_soln ]) u2_sample_mean = np.mean(u_samples[1].reshape((-1, n_draws)), axis=1) assert np.linalg.norm(u2 - u2_sample_mean) / np.linalg.norm(u2) < .05 model.outputDraws()
def _postVarGlobal(self): """ y_k = X_k beta + Z_k u_k + epsilon, u has var_mat D, epsilon has var_mat R Var(beta) = inv( sum_k X_k' inv(Z_k*D*Z_k' + R) X_k ) """ assert self.k_beta > 0 Z_split = np.split(self.Z, self.n_groups) Z_split = np.split(np.zeros((self.N, self.k_gamma)), self.n_groups) self.var_beta = np.zeros((self.k_beta, self.k_beta)) X = np.zeros((self.N, self.k_beta)) start = 0 if self.global_intercept is True: X[:, start] = np.ones(self.N) start += 1 for i in range(len(self.global_ids)): ind = self.global_ids[i] values, dims = self.covariates[ind] assert values.shape[0] == np.prod(dims) X[:, start] = rutils.repeat(values, dims, self.dimensions) start += 1 for indicator in self.indicators: X[:, start:start + np.prod(indicator)] = rutils.kronecker( indicator, self.dimensions, 0) start += np.prod(indicator) X_split = np.split(X, self.n_groups) S2 = [] if self.S is None: if self.share_obs_std is True: S2 = np.ones(self.N) * self.delta_soln else: S2 = np.repeat(self.delta_soln, self.grouping) else: S2 = self.S**2 S2_split = np.split(S2, self.n_groups) for i in range(self.n_groups): V = Z_split[i].dot(np.diag(self.gamma_soln)).dot(np.transpose(Z_split[i])) \ + S2_split[i]*np.identity(self.grouping[i]) self.var_beta += np.transpose(X_split[i]).dot( np.linalg.inv(V)).dot(X_split[i]) self.var_beta = np.linalg.inv(self.var_beta)
def test_indicators(self, dimensions, indicator): """ Test if indicator matrix is built correctly. """ dct = { 'intercept': [indicator[j] == dimensions[j] for j in range(len(dimensions))] } y = np.random.randn(np.prod(dimensions)) model = LME(dimensions, 0, y, {}, dct, {}, False, {}) Z = rutils.kronecker(indicator, dimensions, 0) x = np.random.randn(np.prod(indicator)) assert (np.linalg.norm(model.X(x) - Z.dot(x)) < 1e-10) and \ (np.linalg.norm(model.XT(y) - np.transpose(Z).dot(y)) < 1e-10)
def test_random_intercept(self, dimensions, random_intercept): """ Test if random intercept matrix is built correctly. """ dct = { 'intercept': ([ random_intercept[j] == dimensions[j] for j in range(len(dimensions)) ], None) } y = np.random.randn(np.prod(dimensions)) model = LME(dimensions, 1, y, {}, {}, {}, True, dct) Z = np.tile(rutils.kronecker(random_intercept[1:], dimensions, 1), (dimensions[0], 1)) model.buildZ() assert np.linalg.norm(Z - model.Z) == 0.0
def test_repeat_covariate(self, dimensions, cov_dim): N = np.prod(dimensions) X = np.ones((N, 2)) # 1st column is intercept cov = np.random.randn(np.prod(cov_dim)) cov_dim_bool = [ cov_dim[i] == dimensions[i] for i in range(len(dimensions)) ] Z = rutils.kronecker(cov_dim, dimensions, 0) X[:, 1] = Z.dot(cov) beta_true = [1., -0.6] # beta_0 for intercept Y = X.dot(beta_true) model = LME(dimensions, 0, Y, {'cov1': (cov, cov_dim_bool)}, {}, {'cov1': [-float('inf'), float('inf')]}, True, {}) beta = np.random.randn(2) assert np.linalg.norm(model.X(beta) - X.dot(beta)) < 1e-10 y = np.random.randn(N) assert np.linalg.norm(model.XT(y) - np.transpose(X).dot(y)) < 1e-10 model._buildX() assert np.linalg.norm(model.Xm - X) < 1e-10
def _buildX(self): X = np.zeros((self.N, self.k_beta)) start = 0 if self.global_intercept is True: X[:, start] = np.ones(self.N) start += 1 for i in range(len(self.global_ids)): ind = self.global_ids[i] values, dims = self.covariates[ind] assert values.shape[0] == np.prod(dims) X[:, start] = rutils.repeat(values, dims, self.dimensions) start += 1 for indicator in self.indicators: X[:, start:start + np.prod(indicator)] = rutils.kronecker( indicator, self.dimensions, 0) start += np.prod(indicator) self.Xm = X