def definition(self, model, X, scale_factor): on = X[self.on].cat.categories self.shape_ = len(on) group, n_groups, self.groups_ = get_group_definition( X, self.pool_cols, self.pool_type ) with model: if self.pool_type == "partial": sigma_k = pm.HalfCauchy(self._param_name("sigma_k"), beta=self.scale) offset_k = pm.Normal( self._param_name("offset_k"), mu=0, sd=1, shape=(n_groups, self.shape_), ) k = pm.Deterministic(self._param_name("k"), offset_k * sigma_k) else: k = pm.Normal( self._param_name("k"), mu=0, sigma=self.scale, shape=(n_groups, self.shape_), ) return k[group, X[self.on].cat.codes]
def definition(self, model, X, scale_factor): t = X["t"].values group, n_groups, self.groups_ = get_group_definition( X, self.pool_cols, self.pool_type) self.p_ = self.period / scale_factor['t'] n_params = self.n * 2 with model: if self.pool_type == 'partial': mu_beta = pm.Normal(self._param_name("mu_beta"), mu=0, sigma=1, shape=n_params) # TODO: add as parameters sigma_beta = pm.HalfNormal(self._param_name("sigma_beta"), 0.1, shape=n_params) offset_beta = pm.Normal(self._param_name("offset_beta"), 0, 1 / self.shrinkage_strength, shape=(n_groups, n_params)) beta = pm.Deterministic(self._param_name("beta"), mu_beta + offset_beta * sigma_beta) else: beta = pm.Normal(self._param_name("beta"), 0, 1, shape=(n_groups, n_params)) seasonality = pm.math.sum(self._X_t(t, self.p_, self.n) * beta[group], axis=1) return seasonality
def definition(self, model, X, scale_factor): group, n_groups, self.groups_ = get_group_definition(X, self.pool_cols, self.pool_type) with model: if self.pool_type == "partial": mu_c = pm.Uniform(self._param_name('mu_c'), lower=self.lower, upper=self.upper) offset_c = pm.Normal(self._param_name('offset_c'), mu=0, sigma=1) c = pm.Deterministic(self._param_name('c'), mu_c + offset_c) else: c = pm.Uniform(self._param_name('c'), lower=self.lower, upper=self.upper, shape=n_groups) return c[group]
def definition(self, model, X, scale_factor): t = X["t"].values group, n_groups, self.groups_ = get_group_definition( X, self.pool_cols, self.pool_type) self.s = np.linspace(0, np.max(t), self.n_changepoints + 2)[1:-1] with model: A = (t[:, None] > self.s) * 1.0 if self.pool_type == "partial": sigma_k = pm.HalfCauchy(self._param_name("sigma_k"), beta=self.growth_prior_scale) offset_k = pm.Normal(self._param_name("offset_k"), mu=0, sd=1, shape=n_groups) k = pm.Deterministic(self._param_name("k"), offset_k * sigma_k) sigma_delta = pm.HalfCauchy(self._param_name("sigma_delta"), beta=self.changepoints_prior_scale) offset_delta = pm.Laplace( self._param_name("offset_delta"), 0, 1, shape=(n_groups, self.n_changepoints), ) delta = pm.Deterministic(self._param_name("delta"), offset_delta * sigma_delta) else: delta = pm.Laplace( self._param_name("delta"), 0, self.changepoints_prior_scale, shape=(n_groups, self.n_changepoints), ) k = pm.Normal(self._param_name("k"), 0, self.growth_prior_scale, shape=n_groups) m = pm.Normal(self._param_name("m"), 0, 5, shape=n_groups) gamma = -self.s * delta[group, :] g = (k[group] + pm.math.sum(A * delta[group], axis=1)) * t + ( m[group] + pm.math.sum(A * gamma, axis=1)) return g
def definition(self, model, X, scale_factor): group, n_groups, self.groups_ = get_group_definition( X, self.pool_cols, self.pool_type) with model: if self.pool_type == "partial": raise ValueError( "Indicator() component doesn't support partial pooling") _ind = pm.Beta(self._param_name('_ind'), alpha=0.5, beta=0.5, shape=n_groups) ind = pm.Deterministic(self._param_name('ind'), _ind * 2 - 1) return ind[group]
def definition(self, model, X, scale_factor): def update_gamma(j, gamma, i, delta, offset, rate, change_point): return T.set_subtensor( gamma[i, j], (change_point[j] - offset[i] - T.sum(gamma[i, :j])) * (1 - (rate[i] + T.sum(delta[i, :j])) / (rate[i] + T.sum(delta[i, :j+1]))) ) def get_gamma(i, gamma_init, delta, m, k, s): gamma, _ = theano.scan( update_gamma, sequences=[ T.arange(gamma_init.shape[1]), ], outputs_info=gamma_init, non_sequences=[i, delta, m, k, s], ) return gamma[-1] t = X["t"].values self.cap_scaled = self._y_scaler_.transform(self.cap) group, n_groups, self.groups_ = get_group_definition(X, self.pool_cols, self.pool_type) self.s = np.linspace(0, np.max(t), self.n_changepoints + 2)[1:-1] with model: A = (t[:, None] > self.s) * 1.0 if self.pool_type == 'partial': sigma_k = pm.HalfCauchy(self._param_name('sigma_k'), beta=self.growth_prior_scale) offset_k = pm.Normal(self._param_name('offset_k'), mu=0, sd=1, shape=n_groups) k = pm.Deterministic(self._param_name("k"), offset_k * sigma_k) sigma_delta = pm.HalfCauchy( self._param_name('sigma_delta'), beta=self.changepoints_prior_scale ) offset_delta = pm.Laplace( self._param_name('offset_delta'), 0, 1, shape=(n_groups, self.n_changepoints) ) delta = pm.Deterministic(self._param_name("delta"), offset_delta * sigma_delta) else: delta = pm.Laplace(self._param_name("delta"), 0, self.changepoints_prior_scale, shape=(n_groups, self.n_changepoints)) k = pm.Normal(self._param_name("k"), 0, self.growth_prior_scale, shape=n_groups, testval=np.ones(n_groups)) m = pm.Normal(self._param_name("m"), 0, 5, shape=n_groups) gamma_init = T.zeros_like(delta) gamma, _ = theano.scan( get_gamma, sequences=[T.arange(gamma_init.shape[0])], outputs_info=gamma_init, non_sequences=[delta, m, k, self.s], ) gamma = gamma[-1] growth = ( (k[group] + pm.math.sum(A * delta[group], axis=1)) * (t - (m[group] + pm.math.sum(A * gamma[group], axis=1))) ) growth = self.cap_scaled / (1 + pm.math.exp(-growth)) return growth