def fit(self, df, group=None):
        """
        Fits a loose, tight, beta, and p combinations model. If you pass in
        update group it will override the initial parameters with new
        initial parameters based on the df you pass.

        Args:
            df:
            group: (str) passing in the group will update the initialization
                dictionary (not replacing the old one) for this particular fit.

        Returns:

        """
        if group is not None:
            init_dict = self.update_init_model(df=df, group=group)
        else:
            init_dict = deepcopy(self.init_dict)

        for param in ['beta', 'p']:
            for fit_type in ['loose', 'tight']:
                model_arg_dict = deepcopy(
                    getattr(self, f'{param}_model_kwargs'))
                fit_arg_dict = deepcopy(
                    getattr(self, f'{fit_type}_{param}_fit_dict'))
                model = CurveModel(df=df, **model_arg_dict)

                fe_init, re_init = compute_starting_params(
                    init_dict[param][fit_type])

                fit_arg_dict.update(fe_init=fe_init, re_init=re_init)
                model.fit_params(**fit_arg_dict)

                setattr(self, f'{fit_type}_{param}_model', model)
Exemple #2
0
class BasicModel(ModelPipeline):
    def __init__(self, fit_dict, **basic_model_kwargs):
        """
        Generic class for a function to produce predictions from a model
        with the following attributes.

        Args:
            predict_group: (str) which group to make predictions for
            fit_dict: keyword arguments to CurveModel.fit_params()
            **basic_model_kwargs: keyword arguments to CurveModel.__init__()
        """
        super().__init__()
        self.fit_dict = fit_dict
        self.basic_model_kwargs = basic_model_kwargs
        self.mod = None

    def refresh(self):
        self.mod = None

    def fit(self, df):
        self.mod = CurveModel(df=df, **self.basic_model_kwargs)
        self.mod.fit_params(**self.fit_dict)

    def predict(self, times, predict_space, predict_group='all'):
        predictions = self.mod.predict(
            t=times,
            group_name=predict_group,
            prediction_functional_form=predict_space)
        return predictions
class BasicModel(ModelPipeline):
    def __init__(self, fit_dict, basic_model_dict, **pipeline_kwargs):
        """
        Generic class for a function to produce predictions from a model
        with the following attributes.

        Args:
            **pipeline_kwargs: keyword arguments for the base class of ModelPipeline
            predict_group: (str) which group to make predictions for
            fit_dict: keyword arguments to CurveModel.fit_params()
            basic_model_dict: additional keyword arguments to the CurveModel class
                col_obs_se: (str) of observation standard error
                col_covs: List[str] list of names of covariates to put on the parameters
            param_names (list{str}):
                Names of the parameters in the specific functional form.
            link_fun (list{function}):
                List of link functions for each parameter.
            var_link_fun (list{function}):
                List of link functions for the variables including fixed effects
                and random effects.
        """
        super().__init__(**pipeline_kwargs)
        self.fit_dict = fit_dict
        self.basic_model_dict = basic_model_dict
        self.basic_model_dict.update({'col_obs_se': self.col_obs_se})

        generator_kwargs = pipeline_kwargs
        for arg in self.pop_cols:
            generator_kwargs.pop(arg)

        self.basic_model_dict.update(**generator_kwargs)
        self.mod = None

        self.setup_pipeline()

    def refresh(self):
        self.mod = None

    def fit(self, df, group=None):
        self.mod = CurveModel(df=df, **self.basic_model_dict)
        self.mod.fit_params(**self.fit_dict)

    def predict(self, times, predict_space, predict_group):
        predictions = self.mod.predict(
            t=times,
            group_name=predict_group,
            prediction_functional_form=predict_space)
        return predictions
Exemple #4
0
class TightLooseBetaPModel(ModelPipeline):
    def __init__(self,
                 loose_beta_fit_dict,
                 tight_beta_fit_dict,
                 loose_p_fit_dict,
                 tight_p_fit_dict,
                 beta_model_extras=None,
                 p_model_extras=None,
                 blend_start_t=2,
                 blend_end_t=30,
                 **basic_model_kwargs):
        """
        Produces two tight-loose models as a convex combination between the two of them,
        and then averages

        Args:
            loose_beta_fit_dict: dictionary of keyword arguments to CurveModel.fit_params() for the loose beta model
            tight_beta_fit_dict: dictionary of keyword arguments to CurveModel.fit_params() fro the tight beta model
            loose_p_fit_dict: dictionary of keyword arguments to CurveModel.fit_params() for the loose p model
            tight_p_fit_dict: dictionary of keyword arguments to CurveModel.fit_params() fro the tight p model
            beta_model_extras: (optional) dictionary of keyword arguments to
                override the basic_model_kwargs for the beta model
            p_model_extras: (optional) dictionary of keyword arguments to
                override the basic_model_kwargs for the p model
            blend_start_t: (int) the time to start blending tight and loose
            blend_end_t: (int) the time to stop blending tight and loose

            predict_group: (str) which group to make predictions for
            **basic_model_kwargs: keyword arguments to the basic model
        """
        super().__init__()
        self.beta_model_kwargs = basic_model_kwargs
        self.p_model_kwargs = basic_model_kwargs

        if beta_model_extras is not None:
            self.beta_model_kwargs = self.beta_model_kwargs.update(
                beta_model_extras)

        if p_model_extras is not None:
            self.p_model_kwargs = self.p_model_kwargs.update(p_model_extras)

        self.loose_beta_fit_dict = loose_beta_fit_dict
        self.tight_beta_fit_dict = tight_beta_fit_dict
        self.loose_p_fit_dict = loose_p_fit_dict
        self.tight_p_fit_dict = tight_p_fit_dict

        self.blend_start_t = blend_start_t
        self.blend_end_t = blend_end_t

        self.loose_beta_model = None
        self.tight_beta_model = None
        self.loose_p_model = None
        self.tight_p_model = None

    def refresh(self):
        self.loose_beta_model = None
        self.tight_beta_model = None
        self.loose_p_model = None
        self.tight_p_model = None

    def fit(self, df):
        self.loose_beta_model = CurveModel(df=df, **self.beta_model_kwargs)
        self.tight_beta_model = CurveModel(df=df, **self.beta_model_kwargs)
        self.loose_p_model = CurveModel(df=df, **self.p_model_kwargs)
        self.tight_p_model = CurveModel(df=df, **self.p_model_kwargs)

        self.loose_beta_model.fit_params(**self.loose_beta_fit_dict)
        self.tight_beta_model.fit_params(**self.tight_beta_fit_dict)
        self.loose_p_model.fit_params(**self.loose_p_fit_dict)
        self.tight_p_model.fit_params(**self.tight_p_fit_dict)

    def predict(self, times, predict_space, predict_group='all'):
        loose_beta_predictions = self.loose_beta_model.predict(
            t=times,
            group_name=predict_group,
            prediction_functional_form=predict_space)
        tight_beta_predictions = self.tight_beta_model.predict(
            t=times,
            group_name=predict_group,
            prediction_functional_form=predict_space)
        loose_p_predictions = self.loose_p_model.predict(
            t=times,
            group_name=predict_group,
            prediction_functional_form=predict_space)
        tight_p_predictions = self.tight_p_model.predict(
            t=times,
            group_name=predict_group,
            prediction_functional_form=predict_space)
        beta_predictions = convex_combination(t=times,
                                              pred1=tight_beta_predictions,
                                              pred2=loose_beta_predictions,
                                              pred_fun=predict_space,
                                              start_day=self.blend_start_t,
                                              end_day=self.blend_end_t)
        p_predictions = convex_combination(t=times,
                                           pred1=tight_p_predictions,
                                           pred2=loose_p_predictions,
                                           pred_fun=predict_space,
                                           start_day=self.blend_start_t,
                                           end_day=self.blend_end_t)
        averaged_predictions = model_average(pred1=beta_predictions,
                                             pred2=p_predictions,
                                             w1=0.5,
                                             w2=0.5,
                                             pred_fun=predict_space)
        return averaged_predictions
Exemple #5
0
class TightLooseBetaPModel(ModelPipeline):
    def __init__(self,
                 loose_beta_fit_dict,
                 tight_beta_fit_dict,
                 loose_p_fit_dict,
                 tight_p_fit_dict,
                 basic_model_dict,
                 beta_model_extras=None,
                 p_model_extras=None,
                 blend_start_t=2,
                 blend_end_t=30,
                 **pipeline_kwargs):
        """
        Produces two tight-loose models as a convex combination between the two of them,
        and then averages

        Args:
            **pipeline_kwargs: keyword arguments for the base class of ModelPipeline

            loose_beta_fit_dict: dictionary of keyword arguments to CurveModel.fit_params() for the loose beta model
            tight_beta_fit_dict: dictionary of keyword arguments to CurveModel.fit_params() fro the tight beta model
            loose_p_fit_dict: dictionary of keyword arguments to CurveModel.fit_params() for the loose p model
            tight_p_fit_dict: dictionary of keyword arguments to CurveModel.fit_params() fro the tight p model

            basic_model_dict: additional keyword arguments to the CurveModel class
                col_obs_se: (str) of observation standard error
                col_covs: List[str] list of names of covariates to put on the parameters
            param_names (list{str}):
                Names of the parameters in the specific functional form.
            link_fun (list{function}):
                List of link functions for each parameter.
            var_link_fun (list{function}):
                List of link functions for the variables including fixed effects
                and random effects.
            beta_model_extras: (optional) dictionary of keyword arguments to
                override the basic_model_kwargs for the beta model
            p_model_extras: (optional) dictionary of keyword arguments to
                override the basic_model_kwargs for the p model
            blend_start_t: (int) the time to start blending tight and loose
            blend_end_t: (int) the time to stop blending tight and loose
        """
        super().__init__(**pipeline_kwargs)
        generator_kwargs = pipeline_kwargs
        for arg in self.pop_cols:
            generator_kwargs.pop(arg)

        self.basic_model_dict = basic_model_dict
        self.basic_model_dict.update(**generator_kwargs)
        self.basic_model_dict.update({'col_obs_se': self.col_obs_se})

        self.beta_model_kwargs = self.basic_model_dict
        self.p_model_kwargs = self.basic_model_dict

        if beta_model_extras is not None:
            self.beta_model_kwargs = self.beta_model_kwargs.update(
                beta_model_extras)

        if p_model_extras is not None:
            self.p_model_kwargs = self.p_model_kwargs.update(p_model_extras)

        self.loose_beta_fit_dict = loose_beta_fit_dict
        self.tight_beta_fit_dict = tight_beta_fit_dict
        self.loose_p_fit_dict = loose_p_fit_dict
        self.tight_p_fit_dict = tight_p_fit_dict

        self.blend_start_t = blend_start_t
        self.blend_end_t = blend_end_t

        self.loose_beta_model = None
        self.tight_beta_model = None
        self.loose_p_model = None
        self.tight_p_model = None

        self.setup_pipeline()

    def refresh(self):
        self.loose_beta_model = None
        self.tight_beta_model = None
        self.loose_p_model = None
        self.tight_p_model = None

    def fit(self, df):
        self.loose_beta_model = CurveModel(df=df, **self.beta_model_kwargs)
        self.tight_beta_model = CurveModel(df=df, **self.beta_model_kwargs)
        self.loose_p_model = CurveModel(df=df, **self.p_model_kwargs)
        self.tight_p_model = CurveModel(df=df, **self.p_model_kwargs)

        self.loose_beta_model.fit_params(**self.loose_beta_fit_dict)
        self.tight_beta_model.fit_params(**self.tight_beta_fit_dict)
        self.loose_p_model.fit_params(**self.loose_p_fit_dict)
        self.tight_p_model.fit_params(**self.tight_p_fit_dict)

    def predict(self, times, predict_space, predict_group):
        loose_beta_predictions = self.loose_beta_model.predict(
            t=times,
            group_name=predict_group,
            prediction_functional_form=predict_space)
        tight_beta_predictions = self.tight_beta_model.predict(
            t=times,
            group_name=predict_group,
            prediction_functional_form=predict_space)
        loose_p_predictions = self.loose_p_model.predict(
            t=times,
            group_name=predict_group,
            prediction_functional_form=predict_space)
        tight_p_predictions = self.tight_p_model.predict(
            t=times,
            group_name=predict_group,
            prediction_functional_form=predict_space)
        beta_predictions = convex_combination(t=times,
                                              pred1=tight_beta_predictions,
                                              pred2=loose_beta_predictions,
                                              pred_fun=predict_space,
                                              start_day=self.blend_start_t,
                                              end_day=self.blend_end_t)
        p_predictions = convex_combination(t=times,
                                           pred1=tight_p_predictions,
                                           pred2=loose_p_predictions,
                                           pred_fun=predict_space,
                                           start_day=self.blend_start_t,
                                           end_day=self.blend_end_t)
        averaged_predictions = model_average(pred1=beta_predictions,
                                             pred2=p_predictions,
                                             w1=0.5,
                                             w2=0.5,
                                             pred_fun=predict_space)
        return averaged_predictions
Exemple #6
0
class BasicModelWithInit(BasicModel):
    def __init__(self, smart_init_options=None, **kwargs):
        if smart_init_options is None:
            smart_init_options = {}
        self.smart_init_options = smart_init_options

        super().__init__(**kwargs)

        if self.fit_dict['options']:
            self.smart_init_options = {
                **self.fit_dict['options'],
                **self.smart_init_options
            }

        self.init_dict = None
        self.mod = None

    def run_init_model(self):
        self.init_dict = self.get_init_dict(df=self.all_data,
                                            groups=self.groups)

    def update_init_model(self, df, group):
        """
        Update the initial model with a re-fit model
        from the specified group. Returns a new copy of the init dict

        Args:
            df: (pd.DataFrame) data used to update the init model
            group: (str) the group to update

        Returns:

        """
        new_init_dict = deepcopy(self.init_dict)
        new_init_dict.update(self.get_init_dict(df=df, groups=[group]))
        return new_init_dict

    def get_init_dict(self, df, groups):
        """
        Run the init model for each location.

        Args:
            df: (pd.DataFrame) data frame to fit the model that will
                be subset by group
            groups: (str) groups to get in the dict

        Returns:
            (dict) dictionary of fixed effects keyed by group
        """
        model = CurveModel(df=df, **self.basic_model_dict)

        init_fit_dict = deepcopy(self.fit_dict)
        init_fit_dict.update(options=self.smart_init_options)

        init_dict = get_initial_params(groups=groups,
                                       model=model,
                                       fit_arg_dict=init_fit_dict)
        return init_dict

    def fit(self, df, group=None):
        """
        Fits a loose, tight, beta, and p combinations model. If you pass in
        update group it will override the initial parameters with new
        initial parameters based on the df you pass.

        Args:
            df:
            group: (str) passing in the group will update the initialization
                dictionary (not replacing the old one) for this particular fit.

        Returns:

        """
        if group is not None:
            init_dict = self.update_init_model(df=df, group=group)
        else:
            init_dict = deepcopy(self.init_dict)

        fit_dict = deepcopy(self.fit_dict)
        fe_init, re_init = compute_starting_params(init_dict)
        fit_dict.update(fe_init=fe_init, re_init=re_init)

        self.mod = CurveModel(df=df, **self.basic_model_dict)
        self.mod.fit_params(**fit_dict)

    def refresh(self):
        self.mod = None