The SMC Procedure

Example 23.2 Stochastic Susceptible-Infected-Recovered Model with a Time-Varying Transmission Rate

Although the stochastic susceptible-infected-recovered (SSIR) model with the constant transmission rate, as shown in the section Stochastic Susceptible-Infected-Recovered Model with a Constant Transmission Rate, is simple and easy to understand, it is not realistic because the transition rate is often time-varying as a result of the intervention, seasonality, and other complex reasons. This example illustrates how to define an SSIR model with a time-varying transmission rate in the SMC procedure and then estimate the parameters using the PMCMC method.

Consider the following SSIR model within the framework of the state space model:

  • Initialization distribution:

    StartLayout 1st Row 1st Column upper I upper D 1 2nd Column equals upper Y 1 2nd Row 1st Column upper I upper U 1 2nd Column tilde uniform left-parenthesis 0.75 StartFraction upper I upper D 1 Over p EndFraction comma 1.75 StartFraction upper I upper D 1 Over p EndFraction right-parenthesis 3rd Row 1st Column upper R upper C 1 2nd Column equals 0 4th Row 1st Column upper S 1 2nd Column equals upper N minus upper I upper D 1 minus upper I upper U 1 5th Row 1st Column ln left-parenthesis beta 1 right-parenthesis 2nd Column tilde uniform left-parenthesis ln left-parenthesis StartFraction 2.75 Over upper D EndFraction right-parenthesis comma ln left-parenthesis StartFraction 3.3 Over upper D EndFraction right-parenthesis right-parenthesis 6th Row 1st Column upper R Subscript e comma 1 2nd Column equals exp left-parenthesis ln left-parenthesis beta 1 right-parenthesis right-parenthesis StartFraction upper S 1 upper D Over upper N EndFraction 7th Row 1st Column xi 1 2nd Column equals exp left-parenthesis ln left-parenthesis beta 1 right-parenthesis right-parenthesis upper S 1 StartFraction upper I upper U 1 plus upper I upper D 1 Over upper N EndFraction EndLayout
  • Transition distribution:

    StartLayout 1st Row 1st Column upper S Subscript t 2nd Column equals upper S Subscript t minus 1 Baseline minus xi Subscript t minus 1 Baseline 2nd Row 1st Column upper R upper C Subscript t 2nd Column equals upper R upper C Subscript t minus 1 Baseline plus StartFraction 1 Over upper D EndFraction left-parenthesis upper I upper D Subscript t minus 1 Baseline plus upper I upper U Subscript t minus 1 Baseline right-parenthesis 3rd Row 1st Column upper I upper D Subscript t 2nd Column equals left-parenthesis 1 minus StartFraction 1 Over upper D EndFraction right-parenthesis upper I upper D Subscript t minus 1 Baseline plus upper Y Subscript t minus 1 Baseline 4th Row 1st Column upper I upper U Subscript t 2nd Column equals left-parenthesis 1 minus StartFraction 1 Over upper D EndFraction right-parenthesis upper I upper U Subscript t minus 1 Baseline plus xi Subscript t minus 1 Baseline minus upper Y Subscript t minus 1 Baseline 5th Row 1st Column ln left-parenthesis beta Subscript t Baseline right-parenthesis 2nd Column tilde normal left-parenthesis u 1 plus u 2 t plus rho ln left-parenthesis beta Subscript t minus 1 Baseline right-parenthesis minus u Baseline 1 minus u Baseline 2 left-parenthesis t minus 1 right-parenthesis comma StartRoot sigma squared left-parenthesis 1 minus rho squared right-parenthesis EndRoot right-parenthesis 6th Row 1st Column upper R Subscript e comma t 2nd Column equals exp left-parenthesis ln left-parenthesis beta Subscript t Baseline right-parenthesis right-parenthesis StartFraction upper S Subscript t Baseline upper D Over upper N EndFraction 7th Row 1st Column xi Subscript t 2nd Column equals exp left-parenthesis ln left-parenthesis beta Subscript t Baseline right-parenthesis right-parenthesis upper S Subscript t Baseline StartFraction upper I upper U Subscript t Baseline plus upper I upper D Subscript t Baseline Over upper N EndFraction EndLayout
  • Measurement distribution:

    upper Y Subscript t Baseline tilde binomial left-parenthesis int left-parenthesis upper I upper U Subscript t Baseline right-parenthesis comma p right-parenthesis

Here xi Subscript t, a Poisson distributed instance, denotes the number of new infections at time t plus 1; upper S Subscript t denotes the number of susceptible individuals at time t; upper Y Subscript t is the number of new observed infections at time t; upper R upper C Subscript t is the cumulative number of recovered infections until time t; upper I upper D Subscript t is the number of documented active infectious individuals at time t; upper I upper U Subscript t is the number of undocumented active infectious individuals at time t; beta Subscript t is the transmission rate at time t; and upper R Subscript e comma t is the effective reproduction number at time t. Moreover, N denotes the population; p is the diagnosis rate; D denotes the average time to removal after infection; and StartFraction 1 Over upper D EndFraction denotes the recovery rate. The natural logarithm of the transmission rate follows an AR(1) model with coefficients u 1 and u 2, correlation parameter rho, and variance sigma squared left-parenthesis 1 minus rho squared right-parenthesis.

In this SSIR model, there are six parameters: D, u 1, u 2, p, rho, and sigma; and there are seven state variables: S, upper R upper C, upper I upper D, upper I upper U, ln left-parenthesis beta right-parenthesis, upper R Subscript e, and xi. Actually, the model can be represented without upper R Subscript e because no state variables or dependent variables depend on it. However, upper R Subscript e is worth investigating: upper R Subscript e Baseline less-than 1 indicates containment of the disease. Moreover, the equation of xi Subscript t can be included in the equations of other state variables. For example, upper S Subscript t Baseline equals upper S Subscript t minus 1 Baseline minus xi Subscript t minus 1 can be written as follows:

upper S Subscript t Baseline equals upper S Subscript t minus 1 Baseline minus exp left-parenthesis ln left-parenthesis beta Subscript t minus 1 Baseline right-parenthesis right-parenthesis upper S Subscript t minus 1 Baseline StartFraction upper I upper U Subscript t minus 1 Baseline plus upper I upper D Subscript t minus 1 Baseline Over upper N EndFraction

The equation upper I upper U Subscript t Baseline equals left-parenthesis 1 minus StartFraction 1 Over upper D EndFraction right-parenthesis upper I upper U Subscript t minus 1 Baseline plus xi Subscript t minus 1 Baseline minus upper Y Subscript t minus 1 can be written in the same way. The reason that xi is still kept as a state variable is because the estimated number or interval of new infections is also useful for public health organizations in a pandemic.

A scenario with a basic reproduction number that is a decreasing function of the time is considered in the data generating process. The function is defined as

upper R Subscript 0 comma t Baseline equals upper R Subscript 0 comma 0 Baseline exp left-parenthesis minus eta t right-parenthesis plus left-parenthesis 1 minus exp left-parenthesis minus eta t right-parenthesis right-parenthesis upper R overbar Subscript 0

where upper R Subscript 0 comma t denotes the basic reproduction number at time t, eta denotes the decreasing rate, and upper R overbar Subscript 0 denotes the long run value to which upper R Subscript 0 comma t converges when t is large. Note that the preceding function form is unknown to the modeler; the AR(1) process for the natural logarithm of the transmission rate is used to approximate the true unknown function form of upper R Subscript 0 comma t.

The following statements simulate 82 observations in which the first 75 observations are used as a training data set and the remaining 7 observations are used as a test data set:


*macro variables;
%let N=20000000; * 20 million people ;
%let ID_0 = 100;
%let IU_0 = 800;
%let RC_0 = 0;
%let D = 8.7;
%let R_0 = 3.1;
%let eta = 0.045;
%let p = 0.25;
data sir_data;
   t = 1;
   S = &N - &ID_0 - &IU_0;
   RC = &RC_0;
   IU = &IU_0;
   ID = &ID_0;
   R = &R_0;
   beta = R*1/&D;
   logbeta = log(beta);
   R_eff = R*S/&N;
   Y = ID;
   xi = beta*S*(IU + ID)/&N;
   sum = S + IU + ID + RC;
   output;
   call streaminit(1);
   do t = 2 to 82;
      Slag = S;
      S = S - xi;
      RC = RC + 1/&D*(IU + ID);
      IU = (1-1/&D)*IU + xi - Y;
      ID = (1-1/&D)*ID + Y;
      Y = RAND('BINOmial', &p, int(IU));
      R = &R_0*exp(-&eta*t) + 1-exp(-&eta*t);
      beta = R*1/&D;
      logbeta = log(beta);
      R_eff = R*S/&N;
      xi = beta*S*(IU + ID)/&N;
      sum = S + IU + ID + RC;
   output;
   end;
run;

The following DATA steps load the first 75 observations of the data set sir_data into the data set sir_train and then load that data set into a data table in your CAS session that is associated with the mycas CAS engine libref. The DATA step assumes that your CAS engine libref is named mycas, but you can substitute any appropriately defined CAS engine libref. The last 7 observations are loaded in to the data set sir_test.

data sir_train;
   set sir_data;
   if (t le 75) then output;
run;

data sir_test;
   set sir_data;
   if (t > 75) then output;
run;

data mycas.sir_train;
   set sir_train;
run;

The following statements use PROC SMC to define the preceding SSIR model and then use the PMCMC method to estimate the three parameters for the simulated data set. The posterior medians will be used as the parameters in the smoothing and forecasting process.

proc smc data=mycas.sir_train seed=1234 nthreads=32;
   id time = t;
   var Y;
   statevar S IU ID logBeta RC R_EFF xi;
   smooth nparticle=20480 alg=sir parm=median
      method = fixedlag(20) out(pct=2.5, 97.5)=mycas.sm;
   forecast nparticle=20480 alg=sir lead=7 parm=median
      out(pct=2.5, 97.5)=mycas.fc;
   parm D = 9.3, u1=-1.31, u2=0, p=0.3, rho=0.8, sigma_var=0.16;

   prior D ~ gamma(325.5, 0.0285714286);
   prior sigma_var ~ igamma(11,1);
   prior rho ~ beta(4,1);
   prior p ~ uniform(0.15,0.35);
   prior u1 ~ normal(-1.31, 0.3);
   prior u2 ~ normal(0,1);

   initstate ID ~ degenerate(100);
   initstate IU ~ uniform(0.5*100/p, 1.5*100/p);
   initstate RC ~ degenerate(0);
   initstate S ~ degenerate(&N-ID-IU);
   initstate logBeta ~ uniform(log(2.75*1/D), log(3.3*1/D));
   initstate R_EFF ~ degenerate(exp(logBeta)*S*D/&N);
   initstate xi ~ degenerate(exp(logBeta)*S*(IU + ID)/&N);

   state S ~ degenerate(S.l1 - xi.l1);
   state RC ~ degenerate(RC.l1 + 1/D*(IU.l1+ID.l1));
   state IU ~ degenerate((1-1/D)*IU.l1 + xi.l1 - Y.l1);
   state ID ~ degenerate((1-1/D)*ID.l1 + Y.l1);
   state logBeta ~ normal(u1 + u2*_time + rho*(logBeta.l1-u1-u2*(_time-1)),
      sqrt(sigma_var*(1-rho**2)));
   state R_EFF ~ degenerate(exp(logBeta)*S*D/&N);
   state xi ~ degenerate(exp(logBeta)*S*(IU + ID)/&N);

   model Y ~ normal(p*IU, ifn(IU>1, 2*sqrt(p*(1-p)*IU), 2*sqrt(p*(1-p))));

   learn nparticle=1600 algorithm=sir method=PMCMC(nsample=20000
      nchain=8 nbi=5000 thin=5 seed=1
      outpost=mycas.out samset samsum
      sampler=rwm(ntu=200)
      statistics=all diagnostics=all);
run;

The summary tables of the model information are shown in Output 23.2.1.

Output 23.2.1: Model Information Summary

The SMC Procedure

State Space Model Information
Number of Parameters6
Number of State Variables7
Number of Dependent Variables1
Number of Independent Variables0
Seed Value1234

Number of Observations75
Number of Missing Observations0

Initial Parameters Information
ParameterInitial
Value
Lower
Bound
Upper
Bound
D9.300000Infty
u1-1.31000-InftyInfty
u20-InftyInfty
p0.300000.150000.35000
rho0.8000001.00000
sigma_var0.160000Infty


The summary tables of the posterior samples are shown in Output 23.2.2.

Output 23.2.2: Posterior Summary

MCMC Sampler Settings
MCMC Sampling MethodRWM
Random Seed1
Transformed SamplingFalse
Number of Chains8
Number of Sampling Iterations20000
Number of Burn-in Iterations5000
Thinning Interval5
Number of Tuning Iterations per Tuning Stage200
Number of Tuning Stages24
Target Metropolis Acceptance Rate0.234
Initial RWM Proposal Scale2.38
Tuning Weight0.75
Acceptance Tolerance0.075

The SMC Procedure

Posterior Summaries
ParameterNMeanStandard
Deviation
Percentiles
2.5%25%50%75%97.5%
D320008.62820.35857.95868.37008.62658.88029.3379
u132000-1.35000.2759-1.8878-1.5336-1.3572-1.1745-0.7757
u232000-0.01370.00329-0.0200-0.0158-0.0137-0.0115-0.00701
p320000.15920.008940.15020.15280.15650.16270.1842
rho320000.99420.003180.98590.99280.99500.99640.9982
sigma_var320000.08920.02930.04950.06900.08380.10290.1625

Posterior Intervals
Parameter95% Equal-Tail Interval95% HPD Interval
D7.95869.33797.95289.3274
u1-1.8878-0.7757-1.8925-0.7866
u2-0.0200-0.00701-0.0201-0.00712
p0.15020.18420.15000.1772
rho0.98590.99820.98790.9987
sigma_var0.04950.16250.04340.1465


The correlation and covariance matrices of the parameter samples that are generated by the PMCMC method are shown in Output 23.2.3.

Output 23.2.3: Correlation and Covariance Matrices

Posterior Covariance Matrix
ParameterDu1u2prhosigma_var
D0.1285370.000356-0.00009-0.000590.0000320.000323
u10.0003560.07613-0.00037-0.000060.0000530.000288
u2-0.00009-0.000370.0000114.54E-7-2.2E-6-0.00001
p-0.00059-0.000064.54E-70.000086.981E-85.31E-6
rho0.0000320.000053-2.2E-66.981E-80.000010.000046
sigma_var0.0003230.000288-0.000015.31E-60.0000460.00086

Posterior Correlation Matrix
ParameterDu1u2prhosigma_var
D1.00000.0036-0.0729-0.18480.02850.0307
u10.00361.0000-0.4083-0.02460.06080.0356
u2-0.0729-0.40831.00000.0154-0.2100-0.1172
p-0.1848-0.02460.01541.00000.00250.0203
rho0.02850.0608-0.21000.00251.00000.4941
sigma_var0.03070.0356-0.11720.02030.49411.0000


The following statements load the smoothing estimates for ln left-parenthesis beta right-parenthesis and upper R Subscript e into the Work library and then sort each data set by the time ID:

data smo_s4; set mycas.sm(where=(VariableID=4 and TimeID>=1)); run;
proc sort data=smo_s4; by timeId; run;

data smo_s6; set mycas.sm(where=(VariableID=6 and TimeID>=1)); run;
proc sort data=smo_s6; by timeId; run;

The following statements create a relevant data table, combine_logbeta, in the Work library to record the smoothing estimates and actual values of ln left-parenthesis beta right-parenthesis. Then they draw a plot to compare the smoothing estimates to the actual values at each time step. The plot is shown in Output 23.2.4, where the shadow band indicates the range between the 2.5th and 97.5th percentiles of the smoothing estimates.

data combine_logbeta;
   set smo_s4 (keep=P_1 P_2 Q2);
   set sir_train (keep=t logbeta);
run;

proc sgplot data=combine_logbeta;
   band x=t upper=P_2 lower=P_1 /transparency=.3;
   series x=t y=logbeta /legendlabel='Actual Value' lineattrs=(color=red);
   series x=t y=Q2 /legendlabel='Smoothing Median'
      lineattrs=(color=blue pattern=shortdash);
   yaxis label='logbeta, Smoothing';
   xaxis integer label='Day';
run;

Output 23.2.4: Smoothing Estimates vs. Actual Values, logbeta

Smoothing Estimates vs. Actual Values, logbeta


The following statements create a relevant data table, combine_REFF, in the Work library to record the smoothing estimates and actual values of upper R Subscript e. Then they draw a plot to compare the smoothing estimates to the actual values at each time step. The plot is shown in Output 23.2.5, where the shadow band indicates the range between the 2.5th and 97.5th percentiles of the smoothing estimates.

data combine_REFF;
   set smo_s6 (keep=P_1 P_2 Q2);
   set sir_train (keep=t R_EFF);
run;

proc sgplot data=combine_REFF;
   band x=t upper=P_2 lower=P_1 /transparency=.3;
   series x=t y=R_EFF /legendlabel='Actual Value' lineattrs=(color=red);
   series x=t y=Q2 /legendlabel='Smoothing Median'
      lineattrs=(color=blue pattern=shortdash);
   yaxis label='R_EFF, Smoothing';
   xaxis integer label='Day';
run;

Output 23.2.5: Smoothing Estimates vs. Actual Values, Reff

Smoothing Estimates vs. Actual Values, Reff


The following statements load the forecasting estimates for upper R Subscript e, xi, and Y into the Work library and then sort each data set by the time ID:

data fc_6; set mycas.fc(where=(VariableID=6)); run;
proc sort data=fc_6; by _t; run;

data fc_7; set mycas.fc(where=(VariableID=7)); run;
proc sort data=fc_7; by _t; run;

data fc_8; set mycas.fc(where=(VariableID=8)); run;
proc sort data=fc_8; by _t; run;

The following statements create a relevant data table, combine_REFF_forecast, in the Work library to record the forecasting estimates and actual values of upper R Subscript e. Then they draw a plot to compare the forecasting estimates to the actual values at each time step. The plot is shown in Output 23.2.6, where the shadow band indicates the range between the 2.5th and 97.5th percentiles of the forecasting estimates.

data combine_REFF_forecast;
   set fc_6 (keep=P_1 P_2 Q2);
   set sir_test (keep=t R_EFF);
run;

proc sgplot data=combine_REFF_forecast;
   band x=t upper=P_2 lower=P_1 /transparency=.3;
   scatter x=t y=R_EFF /legendlabel='Actual Value'
      markerattrs=(color=red size=6 symbol=circlefilled);
   series x=t y=Q2 /legendlabel='Forecasting Median'
      markers markerattrs=(color=blue size=6 symbol=triangle)
      lineattrs=(color=blue pattern=solid);
   yaxis label='R_EFF, Forecasting';
   xaxis integer label='Day';
run;

Output 23.2.6: Forecasting Estimates vs. Actual Values, Reff

Forecasting Estimates vs. Actual Values, Reff


The following statements create a relevant data table, combine_xi_forecast, in the Work library to record the forecasting estimates and actual values of xi. Then they draw a plot to compare the forecasting estimates to the actual values at each time step. The plot is shown in Output 23.2.7, where the shadow band indicates the range between the 2.5th and 97.5th percentiles of the forecasting estimates.

data combine_xi_forecast;
   set fc_7 (keep=P_1 P_2 Q2);
   set sir_test (keep=t xi);
run;

proc sgplot data=combine_xi_forecast;
   band x=t upper=P_2 lower=P_1 /transparency=.3;
   scatter x=t y=xi /legendlabel='Actual Value'
      markerattrs=(color=red size=6 symbol=circlefilled);
   series x=t y=Q2 /legendlabel='Forecasting Median'
      markers markerattrs=(color=blue size=6 symbol=triangle)
      lineattrs=(color=blue pattern=solid);
   yaxis label='xi, Forecasting';
   xaxis integer label='Day';
run;

Output 23.2.7: Forecasting Estimates vs. Actual Values, xi

Forecasting Estimates vs. Actual Values, xi


The following statements create a relevant data table, combine_Y_forecast, in the Work library to record the forecasting estimates and actual values of Y. Then they draw a plot to compare the forecasting estimates to the actual values at each time step. The plot is shown in Output 23.2.8, where the shadow band indicates the range between the 2.5th and 97.5th percentiles of the forecasting estimates.

data combine_Y_forecast;
   set fc_8 (keep=P_1 P_2 Q2);
   set sir_test (keep=t Y);
run;

proc sgplot data=combine_Y_forecast;
   band x=t upper=P_2 lower=P_1 /transparency=.3;
   scatter x=t y=Y /legendlabel='Actual Value'
      markerattrs=(color=red size=6 symbol=circlefilled);
   series x=t y=Q2 /legendlabel='Forecasting Median'
      markers markerattrs=(color=blue size=6 symbol=triangle)
      lineattrs=(color=blue pattern=solid);
   yaxis label='Y, Forecasting';
   xaxis integer label='Day';
run;

Output 23.2.8: Forecasting Estimates vs. Actual Values, Y

Forecasting Estimates vs. Actual Values, Y


As shown in this example, by introducing the AR(1) process for the transition rate, this simple and powerful model successfully captures the dynamics in the epidemic spread, even when the true DGP follows a different stochastic process. This model is applied to the real-data example in the section Estimating the Effective Reproduction Number of COVID-19 Cases in Pennsylvania.

Last updated: September 15, 2022