예제 #1
0
def MLE(thetas,
        BaseModel,
        data,
        states,
        parNames,
        checkpoints=None,
        samples=None):
    """
    A function to return the maximum likelihood estimator given a model object and a dataset

    Parameters
    -----------
    BaseModel: model object
        correctly initialised model to be fitted to the dataset
    thetas: np.array
        vector containing estimated parameter values
    thetas: list
        names of parameters to be fitted
    data: list
        list containing dataseries
    states: list
        list containg the names of the model states to be fitted to data

    Returns
    -----------
    MLE : float
        total sum of squared errors

    Notes
    -----------
    An explanation of the difference between SSE and MLE can be found here: https://emcee.readthedocs.io/en/stable/tutorials/line/

    Brief summary: if measurement noise is unbiased, Gaussian and independent than the MLE and SSE are identical.

    Example use
    -----------
    MLE = MLE(model,thetas,data,parNames,positions)
    """

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # assign estimates to correct variable
    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    initN, Nc_home, Nc_work, Nc_schools, Nc_transport, Nc_leisure, Nc_others, Nc_total = polymod.get_interaction_matrices(
    )
    # by defenition, if N is the number of data timeseries then the first N parameters are the estimated variances of these timeseries!
    i = 0
    sigma = []
    for param in parNames:
        if param == 'extraTime':  # don't know if there's a way to make this function more general due to the 'extraTime', can this be abstracted in any way?
            setattr(BaseModel, param, int(round(thetas[i])))
        elif param == 'prevention':
            checkpoints.update({
                'Nc': [
                    thetas[i] *
                    (1.0 * Nc_home + (1 - 0.60) * Nc_work +
                     (1 - 0.70) * Nc_transport + (1 - 0.30) * Nc_others +
                     (1 - 0.80) * Nc_leisure)
                ]
            })
        # The following section is needed to perform a recalibration of beta
        #elif param == 'beta':
        #    estimate_beta = thetas[i]
        #    checkpoints.update(
        #        {'beta':
        #        [
        #        np.random.choice(samples[param]),
        #        thetas[i],
        #        thetas[i],
        #        thetas[i],
        #        thetas[i],
        #        thetas[i],
        #        thetas[i]
        #        ]
        #        })
        else:
            if i < len(data):
                sigma.append(thetas[i])
            else:
                BaseModel.parameters.update({param: thetas[i]})
        i = i + 1

    # ~~~~~~~~~~~~~~
    # Run simulation
    # ~~~~~~~~~~~~~~
    # number of dataseries
    n = len(data)
    # Compute simulation time
    data_length = []
    for i in range(n):
        data_length.append(data[i].size)
    T = max(data_length) + BaseModel.extraTime - 1
    # Use previous samples
    if samples:
        for param in samples:
            if param == 'prevention':
                prevention = np.random.choice(samples[param])
                checkpoints.update({
                    'Nc': [
                        prevention * (1.0 * Nc_home + (1 - 0.60) * Nc_work +
                                      (1 - 0.70) * Nc_transport +
                                      (1 - 0.30) * Nc_others +
                                      (1 - 0.80) * Nc_leisure), prevention *
                        (1.0 * Nc_home + (1 - 0.50) * Nc_work +
                         (1 - 0.60) * Nc_transport + (1 - 0.30) * Nc_others +
                         (1 - 0.70) * Nc_leisure), prevention *
                        (1.0 * Nc_home + (1 - 0.40) * Nc_work +
                         (1 - 0.55) * Nc_transport + (1 - 0.25) * Nc_others +
                         (1 - 0.65) * Nc_leisure), prevention *
                        (1.0 * Nc_home + (1 - 0.30) * Nc_work +
                         (1 - 0.50) * Nc_transport + (1 - 0.20) * Nc_others +
                         (1 - 0.60) * Nc_leisure), prevention *
                        (1.0 * Nc_home + (1 - 0.30) * Nc_work +
                         (1 - 0.45) * Nc_transport + (1 - 0.85) * Nc_schools +
                         (1 - 0.15) * Nc_others + (1 - 0.50) * Nc_leisure),
                        prevention *
                        (1.0 * Nc_home + (1 - 0.25) * Nc_work +
                         (1 - 0.35) * Nc_transport + (1 - 0.35) * Nc_schools +
                         (1 - 0.10) * Nc_others + (1 - 0.30) * Nc_leisure),
                        prevention * (1.0 * Nc_home + (1 - 0.20) * Nc_work +
                                      (1 - 0.15) * Nc_transport +
                                      (1 - 0.00) * Nc_others +
                                      (1 - 0.00) * Nc_leisure)
                    ]
                })
                #checkpoints.update({'Nc':  [prevention*(1.3*Nc_home + (1-0.60)*Nc_work + (1-0.70)*Nc_transport + (1-0.30)*Nc_others + (1-0.80)*Nc_leisure)]})
            else:
                BaseModel.parameters[param] = np.random.choice(samples[param],
                                                               1,
                                                               replace=False)
    # Perform simulation
    out = BaseModel.sim(T, checkpoints=checkpoints)

    # -------------
    # calculate MLE
    # -------------
    ymodel = []
    MLE = 0
    for i in range(n):
        som = 0
        # sum required states
        for j in range(len(states[i])):
            som = som + out[states[i][j]].sum(dim="stratification").values
        ymodel.append(som[BaseModel.extraTime:])
        # calculate simga2 and log-likelihood function
        MLE = MLE - 0.5 * np.sum(
            (data[i] - ymodel[i])**2 / sigma[i]**2 + np.log(sigma[i]**2))
    return abs(MLE)  # must be positive for pso
예제 #2
0
def get_COVID19_SEIRD_parameters(stratified=True):
    """
    Extracts and returns the parameters for the age-stratified deterministic model

    This function returns all parameters needed to run the age-stratified model.
    This function was created to group all parameters in one centralised location.

    Parameters
    ----------
    stratified : boolean
        If True: returns parameters stratified by age, for agestructured model
        If False: returns parameters for non-agestructured model

    Returns
    -----------
    A dictionary with following keys and values:

    Nc: np.array
        9x9 social interaction matrix; by default, the total interaction
        matrix Nc_total from the Polymod study is assigned to the parameters dictionary
    h : np.array
        fraction of the cases that require hospitalisation (-)
    icu: np.array
        fraction of the hospitalized in ICU
    c: np.array
        fraction of the hospitalized in Cohort, calculated as (c = 1 - icu) (-)
    m0: np.array
        fraction of the patients in ICU who die (-)
    a: np.array
        fraction of asymptomatic cases (-)
    m: np.array
        fraction of (mild) symptomatic cases (-)
    da: float64
        length of infectiousness in case of asymptomatic infection (days)
    dm: float64
        length of infectiousness in case of mild symptomatic infection (days)
    dc: float64
        length of stay in Cohort when symptoms don't worsen (days)
    dICU: float64
        length of stay in ICU (days)
    dICUrec: float64
        length of recovery stay in Cohort after stay in ICU (days)
    dhospital: float64
        time between first symptom and hospitalization (days)
    beta: float64
        chance of transmission when coming into contact with an infectious person (-)
    sigma: float64
        length of latent period (days)
    omega: float64
        length of pre-symptomatic infectious period (days)
    dq: float64
        length of quarantine when patient does not develop symptoms (days)

    Example use
    -----------
    parameters = get_COVID19_SEIRD_parameters()
    """

    abs_dir = os.path.dirname(__file__)
    par_path = os.path.join(abs_dir, "../../../data/raw/model_parameters/")

    # Initialize parameters dictionary
    pars_dict = {}

    if stratified == True:

        # Assign Nc_total from the Polymod study to the parameters dictionary
        Nc_total = polymod.get_interaction_matrices()[-1]
        pars_dict['Nc'] = Nc_total

        # Verity_etal
        df = pd.read_csv(os.path.join(par_path, "verity_etal.csv"),
                         sep=',',
                         header='infer')
        pars_dict['h'] = np.array(
            df.loc[:, 'symptomatic_hospitalized'].astype(float).tolist()) / 100
        pars_dict['icu'] = np.array(
            df.loc[:, 'hospitalized_ICU'].astype(float).tolist()) / 100

        # Molenberghs_etal
        df = pd.read_csv(os.path.join(par_path, "molenberghs_etal.csv"),
                         sep=',',
                         header='infer')
        pars_dict['m0'] = np.array(df.loc[:, 'IFR_general_population'].astype(
            float).tolist()) / 100 / pars_dict['h']

        # Wu_etal
        df_asymp = pd.read_csv(os.path.join(par_path, "wu_etal.csv"),
                               sep=',',
                               header='infer')
        pars_dict['a'] = np.array(
            df_asymp.loc[:, 'fraction asymptomatic'].astype(float).tolist())

    else:
        pars_dict['Nc'] = np.array([11.2])

        non_strat = pd.read_csv(os.path.join(par_path, "non_stratified.csv"),
                                sep=',',
                                header='infer')
        pars_dict.update({
            key: np.array(value)
            for key, value in non_strat.to_dict(orient='list').items()
        })

    # deduced parameters
    pars_dict['c'] = 1 - pars_dict['icu']
    pars_dict['m'] = 1 - pars_dict['a']

    # Other parameters
    df_other_pars = pd.read_csv(os.path.join(par_path, "others.csv"),
                                sep=',',
                                header='infer')
    pars_dict.update(df_other_pars.T.to_dict()[0])

    # Fitted parameters
    pars_dict['beta'] = 0.03492

    return pars_dict
예제 #3
0
import math
import xarray as xr
import emcee
import json
import corner

from covid19model.optimization import objective_fcns
from covid19model.optimization import MCMC
from covid19model.models import models
from covid19model.data import google
from covid19model.data import sciensano
from covid19model.data import polymod
from covid19model.data import model_parameters
from covid19model.visualization.optimization import traceplot

initN, Nc_home, Nc_work, Nc_schools, Nc_transport, Nc_leisure, Nc_others, Nc_total = polymod.get_interaction_matrices(
)


def full_calibration(model,
                     timeseries,
                     spatial_unit,
                     start_date,
                     end_beta,
                     end_ramp,
                     fig_path,
                     samples_path,
                     maxiter=50,
                     popsize=50,
                     steps_mcmc=10000):
    """
    model : object