def _generate_model(self, opts={}): """opts has a optional key 'dim' that defaults to 6 and specifies the dimension of the model that you want to have.""" if 'dim' not in opts: dim = 6 else: dim = opts['dim'] ncat = math.floor(dim/2) nnum = dim - ncat self.fields = [] # numeric for idx in range(ncat): field = md.Field(name="dim" + str(idx), domain=dm.NumericDomain(), extent=dm.NumericDomain(-5, 5)) self.fields.append(field) # categorical for idx in range(ncat): field = md.Field(name="dim" + str(idx+nnum), domain=dm.DiscreteDomain(), extent=dm.DiscreteDomain(list("ABCDEFG"))) self.fields.append(field) self.mode = 'model' return self._unbound_updater,
def _set_model_params(self, p, mu, S, cats, nums): """Sets the model parameters to given values. """ if self.opts['normalized']: logger.warning("cannot use normalized model with explicit model parameters. I disable the normalization.") self.opts['normalized'] = False fields = [] # categorical fields can be derived coords = p.coords for cat in cats: extent = coords[cat].values.tolist() field = md.Field(cat, dm.DiscreteDomain(), dm.DiscreteDomain(extent), dtype='string') fields.append(field) # set numerical fields of abstract model class num_extents = cgwm.numeric_extents_from_params(S, mu, nums) for extent, num in zip(num_extents, nums): field = md.Field(num, dm.NumericDomain(), dm.NumericDomain(extent), dtype='numerical') fields.append(field) self.fields = fields # set model params self._p = p self._mu = mu self._S = S self._categoricals = cats self._numericals = nums self._marginalized_mask = xr.DataArray(data=[False] * len(self._categoricals), dims='name', coords=[self._categoricals]) return self._unbound_updater,
def get_numerical_fields(df, colnames): """Returns numerical fields constructed from the columns in colname of dataframe df. This assumes colnames only contains names of numerical columns of df. Also, since fields are constructed from a data frame the variables are assumes to be 'observed' and not latent.""" fields = [] for colname in colnames: column = df[colname] mi, ma = column.min(), column.max() d = (ma - mi) * 0.1 field = Field(colname, dm.NumericDomain(), dm.NumericDomain(mi - d, ma + d), False, 'numerical', 'observed') fields.append(field) return fields
def _generate_model(self, opts): """Generates a gaussian model according to options. This does not assign any data to the model. It also sets the 'mode' of this model to 'model'. Note that this method is solely called by Model.generate_model. Options must have a key 'mode' of value 'custom' or 'normal': If mode is 'custom': option must have keys 'sigma' and 'mu'. which are a suitable numpy matrix and row vector, resp. The domain of each field is set to (-10,10). if mode is 'normal' option must have a key 'dim'. its value is the dimension of the model. The model will have the identity matrix as its sigma and the zero vector as its mean. """ mode = opts['mode'] if mode == 'custom': mu = opts['mu'] sigma = opts['sigma'] if not isinstance(mu, matrix) or not isinstance(sigma, matrix) or mu.shape[1] != 1: raise ValueError("invalid arguments") self._S = sigma self._mu = mu self.fields = [md.Field(name="dim" + str(idx), domain=dm.NumericDomain(), extent=dm.NumericDomain(mu[idx].item() - 2, mu[idx].item() + 2)) for idx in range(sigma.shape[0])] self.mode = 'model' return self._unbound_updater, if mode == 'normal': dim = opts['dim'] sigma = matrix(np.eye(dim)) mu = matrix(np.zeros(dim)).T opts = {'mode': 'custom', 'sigma': sigma, 'mu': mu} return self._generate_model(opts=opts) else: raise ValueError('invalid mode: ' + str(mode))
def adopt_all_extents(model, how=field_to_auto_extent): for field in model.fields: if field['dtype'] != 'string': try: extent = how(model.copy(), field['name']) except: logger.warning( 'failed to automatically determine extent of field "{}".'. format(field['name'])) else: field['extent'] = dm.NumericDomain(extent) # modifies model! return model