Chapter 5 Descriptive Modeling
The previous chapter presented several descriptive plots of raw data. What I’d like to do in this chapter is show some simple modeling methods. By no means is any of the modeling presented here considered breakthrough modeling. I call this descriptive modeling because all I do is describe the patterns using statistical methods. In the next chapter I’ll give some examples of models that attempt to capture mechanism and underlying process.
The difference between descriptive models and explanatory models is that the former are summaries of the data and can be used to forecast, but they do not provide understanding of the underling mechanisms. Descriptive models do not give insight into what will happen if a change is imposed on the system. Descriptive models don’t tell us the effect social distancing may have, for example, on the future rate of covid-19. They are fine for describing what has happened in the past but can be limited in helping us understand how the future will play out under various scenarios including interventions. I sometimes refer to descriptive modeling as “models of data.” Process models are about modeling underlying mechanism. They also use data to estimate parameters and test predictions, but the focus of process models is the underlying mechanism.
I’ll try to use the minimum R features necessary to make the points I want to highlight. There are more complicated approaches using time series packages that format the data differently (e.g., they use special time series objects in R). There are benefits of doing this because there are automatic plotting and estimation routines that can take time series objects and do relevant computations. But I believe that as you are learning this material it makes more sense to learn how to do some of the programming. This will put you in a better position to learn more advanced approaches like those for time series data, which use even more complex programming capabilities. It is best to learn how to program with simpler problems and then gradually add complexity rather than jump immediately to complex cases. So I’ll start with standard R objects and slowly introduce some elements unique to time series data.
For more general treatments on working with time series data see Hyndman & Athanasopoulos; Holmes, Scheuerell & Ward and the classic Box & Jenkins, with additional authors in newer editions of the book.
5.1 Regression on US State Percentages: Linear Mixed Models on Logs
In the chapter Descriptive Plots I showed that on the log scale the curves look like they can be approximated by straight lines by state for the count/population variable.
These data are a natural candidate for a random effects linear regression. Each state should have its own intercept and slope on the log scale. We could use standard regression (ordinary least squares) to create a complicated interaction between day and state, so that we have a state factor with 50 levels (so 49 effect or contrast codes), giving us 49 intercepts and slopes but that is overkill. The random effects approach to regression makes more sense. Each state is modeled as a random draw from a multivariate normal distribution such that we draw 50 pairs of slopes and intercepts from that multivariate distribution of intercept and slope. Once we have those 50 slope and intercept pairs, then we compute the predicted scores for each state. The algorithm finds the mean and covariance matrix of that multivariate distribution to minimize the discrepancy (i.e., squared residuals) between the observed and the predicted data. As shown in the previous chapter, the log of the percentage of the state population follows an approximate line, though there was some evidence of curvature in the descriptive plots suggesting a deviation from a simple exponential curve.
In the following analyses, the variable day is entered into the model as a linear time variable (1, 2, 3, etc). Our previous plots suggest that on the log scale we may be fine with linear time as a predictor. In subsequent analyses we will consider more complicated treatments of the day variable to allow for additional nonlinearity.
5.1.1 Examine distributional assumptions
It is good to check the distribution of the log percent variable to make sure there aren’t major issues with symmetry. The log of the percent of the state population that tests positive will be the dependent variable in the regressions we will conduct.
There is evidence of skewness in this variable, which raises concern about the distributional assumptions. We will address this in subsequent analyses but for now let’s plug along with the simpleminded idea that these data are an exponential function of day.
5.1.2 Linear mixed model
Here are the results of this simple linear mixed model on the log scale.
percent.log10 | |||||
---|---|---|---|---|---|
Predictors | Estimates | std. Error | CI | Statistic | p |
(Intercept) | -2.41 | 0.05 | -2.50 – -2.31 | -50.75 | <0.001 |
day.numeric | 0.02 | 0.00 | 0.02 – 0.03 | 39.69 | <0.001 |
Random Effects | |||||
σ^{2} | 0.24 | ||||
τ_{00} _{state.abb} | 0.10 | ||||
τ_{11} _{state.abb.day.numeric} | 0.00 | ||||
ρ_{01} _{state.abb} | -0.41 | ||||
ICC | 0.32 | ||||
N _{state.abb} | 50 | ||||
Observations | 5346 | ||||
Marginal R^{2} / Conditional R^{2} | 0.625 / 0.743 |
The estimates, se(est), CI, t and pvalue for the fixed effects are printed first, then the parameters of the random effect part are printed in the second part of the table. The random effect parameters, in order, are the variance of the residuals, the variance of the random effect intercept, the variance of the random effect slope, the correlation between the random intercept and the random slope, the adjusted ICC, number of states, number of observations (recall 0s have been removed from this data file so the N refers to the number of days by state for which there was a nonzero number of positive covid-19 cases), and the R\(^2\) values.
5.1.3 Diagnostics
Now let’s examine plots of residuals to diagnose potential issues with this model. The plot of the residuals against the fitted values should look like a random point cloud in the ideal case and the QQ plot should show a relatively straight line. For a discussion of using residuals to diagnose model assumptions, see my lecture notes.
The residuals against the fitted values suggest a nonlinear pattern remains in the data. This suggests that we may not have completely linearized the data with the log transformation. The qqplot suggests some deviation from a typical normal distribution; that is, the residuals appear to have longer tails than expected by a normal distribution. Both of these plots suggest there are issues that have to be addressed. We probably don’t want to jump right into doing another transformation right way as that may create new issues with interpretation. We selected the log transformation because we are checking for exponential growth and on the log scale the exponential growth should become linear. So maybe the exponential growth model may not be appropriate here, or there may be other issues with the data that are contaminating the exponential growth pattern. Without additional modeling we cannot adjudicate between these possibilities just from this present regression alone.
Even though the residual plots raise concern about this model, let’s examine the state-level slopes and intercepts more directly: first with a table of each state and then with some plots. Light gray points have confidence intervals that overlap 0 so those parameter estimates are not significantly different from zero. We did not perform a correction like Bonferroni or Scheffe to address the 100 tests we just did (50 states on each of slope and intercept). This would just require a small modification to the code to adjust the level of the CI to correspond, say, to the Bonferroni corrected levels.
## (Intercept) day.numeric
## Alabama -2.43 0.0249
## Alaska -2.51 0.0177
## Arizona -2.80 0.0288
## Arkansas -2.54 0.0244
## California -2.44 0.0238
## Colorado -2.10 0.0222
## Connecticut -2.06 0.0270
## Delaware -2.23 0.0275
## Florida -2.48 0.0247
## Georgia -2.32 0.0251
## Hawaii -2.58 0.0169
## Idaho -2.36 0.0205
## Illinois -2.31 0.0283
## Indiana -2.52 0.0281
## Iowa -2.63 0.0296
## Kansas -2.76 0.0284
## Kentucky -2.71 0.0258
## Louisiana -1.74 0.0217
## Maine -2.37 0.0201
## Maryland -2.46 0.0297
## Massachusetts -1.90 0.0259
## Michigan -2.07 0.0239
## Minnesota -2.84 0.0297
## Mississippi -2.35 0.0257
## Missouri -2.77 0.0273
## Montana -2.39 0.0146
## Nebraska -2.71 0.0310
## Nevada -2.33 0.0230
## New Hampshire -2.40 0.0240
## New Jersey -1.80 0.0263
## New Mexico -2.51 0.0258
## New York -1.39 0.0216
## North Carolina -2.77 0.0277
## North Dakota -2.58 0.0259
## Ohio -2.65 0.0267
## Oklahoma -2.79 0.0259
## Oregon -2.50 0.0197
## Pennsylvania -2.36 0.0270
## Rhode Island -2.13 0.0284
## South Carolina -2.57 0.0251
## South Dakota -2.41 0.0268
## Tennessee -2.45 0.0252
## Texas -2.78 0.0271
## Utah -2.53 0.0258
## Vermont -2.18 0.0186
## Virginia -2.70 0.0296
## Washington -1.75 0.0157
## West Virginia -2.55 0.0200
## Wisconsin -2.49 0.0245
## Wyoming -2.39 0.0202
It turns out that computing standard errors for the prediction is not straightforward for linear mixed models and quite complicated for nonlinear mixed models that we will perform later. You can read about the complexity here.
Here is one method for computing the predicted value and a prediction interval that relies on sampling. To maintain clarity I’ll focus just on two states, but one could do these plots for all 50 states. I’ll first print the data for the state of New York. The table includes the day, the fit from the regression equation, the confidence interval around the fit, the fit placed back on the original scale (i.e., \(10^{\mbox{fit}}\)) and the original data on the percentage scale.
## day.numeric fit upr lwr fit.per percap100
## 1 0 -1.416 -0.436 -2.437 0.041 0.001
## 2 1 -1.368 -0.343 -2.337 0.043 0.001
## 3 2 -1.331 -0.317 -2.318 0.047 0.001
## 4 3 -1.338 -0.331 -2.317 0.046 0.002
## 5 4 -1.284 -0.306 -2.279 0.051 0.002
## 6 5 -1.263 -0.376 -2.276 0.053 0.003
## 7 6 -1.235 -0.259 -2.267 0.056 0.003
## 8 7 -1.224 -0.267 -2.241 0.061 0.005
## 9 8 -1.270 -0.249 -2.159 0.065 0.008
## 10 9 -1.205 -0.248 -2.166 0.064 0.016
## 11 10 -1.170 -0.165 -2.110 0.065 0.029
## 12 11 -1.119 -0.165 -2.124 0.070 0.043
## 13 12 -1.116 -0.117 -2.121 0.074 0.060
## 14 13 -1.095 -0.141 -2.091 0.075 0.081
## 15 14 -1.109 -0.140 -2.005 0.080 0.107
## 16 15 -1.035 -0.106 -1.933 0.088 0.131
## 17 16 -1.039 -0.110 -2.051 0.094 0.158
## 18 17 -1.018 0.000 -1.973 0.097 0.194
## 19 18 -0.974 -0.102 -1.989 0.102 0.230
## 20 19 -0.940 0.092 -1.862 0.105 0.268
## 21 20 -0.918 0.002 -1.970 0.117 0.305
## 22 21 -0.946 -0.043 -1.845 0.125 0.341
## 23 22 -0.925 0.091 -1.881 0.125 0.388
## 24 23 -0.874 0.090 -1.872 0.139 0.430
## 25 24 -0.890 0.094 -1.773 0.133 0.473
## 26 25 -0.803 0.167 -1.797 0.148 0.527
## 27 26 -0.808 0.218 -1.876 0.158 0.582
## 28 27 -0.830 0.127 -1.734 0.137 0.630
## 29 28 -0.753 0.181 -1.791 0.167 0.675
## 30 29 -0.739 0.289 -1.788 0.178 0.716
## 31 30 -0.746 0.184 -1.732 0.194 0.773
## 32 31 -0.705 0.209 -1.668 0.181 0.828
## 33 32 -0.666 0.234 -1.625 0.212 0.882
## 34 33 -0.681 0.337 -1.532 0.210 0.926
## 35 34 -0.686 0.343 -1.598 0.231 0.967
## 36 35 -0.594 0.339 -1.558 0.223 1.002
## 37 36 -0.599 0.319 -1.587 0.241 1.039
## 38 37 -0.586 0.310 -1.584 0.243 1.097
## 39 38 -0.564 0.328 -1.563 0.241 1.145
## 40 39 -0.579 0.456 -1.514 0.273 1.180
## 41 40 -0.515 0.477 -1.472 0.286 1.215
## 42 41 -0.505 0.556 -1.483 0.318 1.245
## 43 42 -0.453 0.516 -1.367 0.355 1.271
## 44 43 -0.468 0.496 -1.470 0.343 1.297
## 45 44 -0.414 0.591 -1.391 0.356 1.321
## 46 45 -0.407 0.518 -1.416 0.350 1.348
## 47 46 -0.387 0.531 -1.275 0.409 1.390
## 48 47 -0.383 0.566 -1.332 0.463 1.444
## 49 48 -0.370 0.638 -1.280 0.461 1.474
## 50 49 -0.313 0.661 -1.327 0.486 1.494
## 51 50 -0.298 0.677 -1.284 0.505 1.510
## 52 51 -0.272 0.675 -1.252 0.489 1.534
## 53 52 -0.239 0.664 -1.257 0.533 1.558
## 54 53 -0.248 0.725 -1.139 0.553 1.578
## 55 54 -0.219 0.731 -1.131 0.611 1.602
## 56 55 -0.199 0.759 -1.096 0.644 1.619
## 57 56 -0.193 0.743 -1.207 0.589 1.632
## 58 57 -0.147 0.836 -1.109 0.714 1.644
## 59 58 -0.096 0.856 -1.077 0.697 1.658
## 60 59 -0.088 0.911 -1.063 0.723 1.676
## 61 60 -0.083 0.893 -1.025 0.829 1.691
## 62 61 -0.071 0.962 -1.044 0.880 1.705
## 63 62 -0.038 0.967 -1.074 0.871 1.716
## 64 63 -0.020 0.999 -0.916 0.892 1.725
## 65 64 0.019 0.943 -1.059 0.936 1.732
## 66 65 0.021 0.951 -0.915 1.058 1.743
## 67 66 0.023 0.979 -0.869 1.093 1.755
## 68 67 0.053 1.087 -0.864 1.123 1.770
## 69 68 0.068 0.995 -0.868 1.175 1.782
## 70 69 0.113 1.017 -0.814 1.269 1.792
## 71 70 0.128 1.029 -0.758 1.371 1.798
## 72 71 0.122 1.091 -0.891 1.369 1.806
## 73 72 0.158 1.106 -0.847 1.473 1.813
## 74 73 0.176 1.124 -0.773 1.559 1.824
## 75 74 0.187 1.126 -0.814 1.598 1.833
## 76 75 0.268 1.198 -0.656 1.672 1.842
## 77 76 0.251 1.243 -0.704 1.853 1.850
## 78 77 0.280 1.276 -0.720 1.901 1.856
## 79 78 0.296 1.241 -0.623 2.058 1.862
## 80 79 0.281 1.245 -0.643 2.204 1.868
## 81 80 0.340 1.336 -0.666 2.147 1.877
## 82 81 0.367 1.336 -0.637 2.375 1.885
## 83 82 0.389 1.286 -0.595 2.435 1.892
## 84 83 0.415 1.376 -0.492 2.566 1.897
## 85 84 0.423 1.454 -0.603 2.851 1.902
## 86 85 0.438 1.418 -0.414 2.710 1.909
## 87 86 0.455 1.412 -0.533 3.001 1.914
## 88 87 0.516 1.495 -0.509 3.002 1.920
## 89 88 0.469 1.431 -0.498 3.357 1.925
## 90 89 0.529 1.502 -0.420 3.473 1.931
## 91 90 0.552 1.529 -0.366 3.524 1.935
## 92 91 0.602 1.593 -0.393 3.544 1.938
## 93 92 0.582 1.529 -0.345 4.317 1.942
## 94 93 0.633 1.605 -0.386 4.022 1.945
## 95 94 0.674 1.611 -0.403 4.115 1.949
## 96 95 0.660 1.590 -0.274 4.454 1.953
## 97 96 0.708 1.591 -0.228 4.603 1.958
## 98 97 0.736 1.751 -0.264 4.744 1.962
## 99 98 0.736 1.724 -0.220 5.326 1.965
## 100 99 0.730 1.687 -0.289 5.502 1.968
## 101 100 0.807 1.777 -0.221 6.001 1.971
## 102 101 0.793 1.811 -0.145 6.088 1.974
## 103 102 0.826 1.749 -0.085 6.207 1.978
## 104 103 0.871 1.825 -0.132 7.085 1.982
## 105 104 0.878 1.907 -0.172 7.116 1.985
## 106 105 0.887 1.913 -0.062 7.326 1.988
## 107 106 0.907 1.889 -0.069 7.906 1.991
## 108 107 0.907 1.937 -0.034 7.848 1.994
Note that the linear pattern (line and prediction band) doesn’t do a good job of capturing the actual data points. Some points are over predicted in the early days, then under predicted, then over predicted again. This would produce a pattern where the residuals are negative, then positive, then negative again as we saw in one of the earlier residual plots. The data looked approximately linear but upon close inspection a model that is actually linear in the log scale seems to systematically miss the underlying pattern.
To check this is not just a fluke for New York, let’s look at another state. For Michigan a similar story, where we see over, under and over prediction. These plots suggest while the linear model may seem ok at first pass, there may some systematic deviations form the line that are worth capturing. We can see that if we forecast out five days or so, the line will continue to increase but it appears that the points are increasing at a slower rate. In this case, forecasts will likely be systematically off the mark.
## day.numeric fit upr lwr fit.per
## 1 0 -2.07213 -1.46111 -2.715 0.00830
## 2 1 -2.05902 -1.40050 -2.681 0.00892
## 3 2 -1.98765 -1.34180 -2.582 0.01011
## 4 3 -1.98442 -1.35725 -2.676 0.01018
## 5 4 -2.00701 -1.36637 -2.616 0.01009
## 6 5 -1.90239 -1.28589 -2.616 0.01092
## 7 6 -1.93888 -1.22723 -2.571 0.01204
## 8 7 -1.91686 -1.27934 -2.543 0.01253
## 9 8 -1.87839 -1.23526 -2.546 0.01284
## 10 9 -1.87851 -1.24706 -2.522 0.01293
## 11 10 -1.85992 -1.15177 -2.473 0.01331
## 12 11 -1.80770 -1.19556 -2.449 0.01688
## 13 12 -1.81464 -1.17141 -2.397 0.01676
## 14 13 -1.77020 -1.13197 -2.436 0.01581
## 15 14 -1.71471 -1.09498 -2.377 0.01934
## 16 15 -1.75466 -1.08522 -2.393 0.01753
## 17 16 -1.68627 -1.04857 -2.335 0.02147
## 18 17 -1.68566 -1.05651 -2.320 0.01997
## 19 18 -1.66057 -0.97881 -2.288 0.02375
## 20 19 -1.62764 -1.01677 -2.231 0.02358
## 21 20 -1.57373 -0.96145 -2.228 0.02655
## 22 21 -1.54841 -0.94391 -2.157 0.02644
## 23 22 -1.56688 -0.95367 -2.200 0.02706
## 24 23 -1.53587 -0.93649 -2.167 0.03192
## 25 24 -1.47571 -0.81738 -2.109 0.03100
## 26 25 -1.46858 -0.86184 -2.139 0.03493
## 27 26 -1.43531 -0.77592 -2.098 0.03671
## 28 27 -1.40618 -0.76013 -2.011 0.03718
## 29 28 -1.39993 -0.80117 -1.992 0.03983
## 30 29 -1.38722 -0.73017 -1.970 0.04036
## 31 30 -1.35865 -0.68832 -1.962 0.04531
## 32 31 -1.33674 -0.69148 -1.969 0.04453
## 33 32 -1.33824 -0.71203 -1.965 0.05312
## 34 33 -1.29518 -0.63932 -1.883 0.05282
## 35 34 -1.28760 -0.67819 -1.898 0.05699
## 36 35 -1.21077 -0.62507 -1.879 0.06361
## 37 36 -1.17608 -0.54185 -1.834 0.06121
## 38 37 -1.19609 -0.57063 -1.785 0.06569
## 39 38 -1.16433 -0.52137 -1.797 0.06698
## 40 39 -1.14734 -0.47424 -1.811 0.07002
## 41 40 -1.12025 -0.51498 -1.777 0.07252
## 42 41 -1.07770 -0.43960 -1.711 0.08267
## 43 42 -1.04930 -0.40090 -1.645 0.08724
## 44 43 -1.02073 -0.38809 -1.669 0.08762
## 45 44 -1.01915 -0.38440 -1.632 0.09165
## 46 45 -1.01164 -0.35674 -1.627 0.11200
## 47 46 -0.96991 -0.33123 -1.619 0.10967
## 48 47 -0.97830 -0.34109 -1.595 0.11042
## 49 48 -0.90394 -0.27835 -1.559 0.11999
## 50 49 -0.87684 -0.27421 -1.498 0.12737
## 51 50 -0.88046 -0.25359 -1.538 0.14083
## 52 51 -0.82480 -0.19440 -1.486 0.13682
## 53 52 -0.80782 -0.21219 -1.428 0.15519
## 54 53 -0.82023 -0.16050 -1.460 0.15985
## 55 54 -0.79507 -0.18977 -1.426 0.17088
## 56 55 -0.76345 -0.12350 -1.403 0.16627
## 57 56 -0.76324 -0.14893 -1.396 0.19269
## 58 57 -0.67307 -0.06071 -1.310 0.18753
## 59 58 -0.69396 -0.08418 -1.338 0.20164
## 60 59 -0.62627 0.00945 -1.296 0.21718
## 61 60 -0.66368 -0.03913 -1.285 0.23121
## 62 61 -0.62692 0.02552 -1.251 0.23297
## 63 62 -0.60780 0.06791 -1.247 0.24142
## 64 63 -0.54823 0.10764 -1.171 0.28032
## 65 64 -0.54407 0.10559 -1.167 0.27414
## 66 65 -0.51398 0.11058 -1.144 0.28092
## 67 66 -0.50512 0.14880 -1.203 0.32772
## 68 67 -0.48448 0.13592 -1.145 0.33476
## 69 68 -0.44776 0.20838 -1.054 0.31838
## 70 69 -0.39953 0.19487 -1.065 0.38721
## 71 70 -0.42647 0.23372 -1.031 0.42471
## 72 71 -0.40865 0.23407 -0.985 0.43105
## 73 72 -0.33320 0.27953 -0.981 0.43530
## 74 73 -0.33235 0.26919 -0.981 0.47451
## 75 74 -0.28964 0.31867 -0.910 0.47562
## 76 75 -0.25193 0.37388 -0.908 0.51317
## 77 76 -0.24637 0.42302 -0.874 0.56027
## 78 77 -0.22427 0.38618 -0.810 0.64240
## 79 78 -0.22975 0.41766 -0.857 0.63140
## 80 79 -0.18470 0.43266 -0.819 0.65178
## 81 80 -0.18725 0.43899 -0.831 0.70636
## 82 81 -0.13246 0.47818 -0.780 0.79559
## 83 82 -0.08870 0.57145 -0.738 0.81867
## 84 83 -0.05673 0.56190 -0.694 0.90326
## 85 84 -0.08702 0.61042 -0.699 0.86693
## 86 85 -0.05789 0.60017 -0.666 0.94885
## 87 86 0.00374 0.62054 -0.633 0.94901
## 88 87 -0.01587 0.69060 -0.621 0.97248
## 89 88 0.04973 0.65244 -0.643 1.03024
## 90 89 0.04976 0.69661 -0.572 1.13040
## 91 90 0.07058 0.76922 -0.536 1.22379
## 92 91 0.09368 0.75410 -0.520 1.23168
## 93 92 0.13129 0.76547 -0.506 1.25713
## 94 93 0.14595 0.82916 -0.463 1.37686
## 95 94 0.16967 0.83072 -0.462 1.49727
## 96 95 0.19223 0.83642 -0.471 1.67695
## 97 96 0.24193 0.86984 -0.426 1.69312
## 98 97 0.22581 0.91420 -0.402 1.80533
## 99 98 0.28413 0.90153 -0.333 1.93098
## 100 99 0.31789 0.97758 -0.315 1.96438
## 101 100 0.28966 0.93622 -0.336 2.07520
## 102 101 0.31502 0.97602 -0.328 2.11767
## 103 102 0.33898 0.97677 -0.276 2.26648
## 104 103 0.42367 1.00706 -0.271 2.48267
## 105 104 0.42170 1.10230 -0.250 2.62421
## 106 105 0.42918 1.06998 -0.187 2.62148
## 107 106 0.46500 1.09778 -0.138 2.88370
## 108 107 0.49994 1.19978 -0.153 2.98519
## percap100
## 1 0.00000
## 2 0.00000
## 3 0.00002
## 4 0.00003
## 5 0.00024
## 6 0.00036
## 7 0.00045
## 8 0.00076
## 9 0.00090
## 10 0.00159
## 11 0.00314
## 12 0.00471
## 13 0.00625
## 14 0.01131
## 15 0.01455
## 16 0.01943
## 17 0.02469
## 18 0.03033
## 19 0.03850
## 20 0.04892
## 21 0.05755
## 22 0.06806
## 23 0.07954
## 24 0.09721
## 25 0.11235
## 26 0.13226
## 27 0.14741
## 28 0.16275
## 29 0.17827
## 30 0.19652
## 31 0.21085
## 32 0.22306
## 33 0.23289
## 34 0.24510
## 35 0.25193
## 36 0.26633
## 37 0.28053
## 38 0.29156
## 39 0.29978
## 40 0.31238
## 41 0.32044
## 42 0.32701
## 43 0.33338
## 44 0.34062
## 45 0.35418
## 46 0.36860
## 47 0.38346
## 48 0.38805
## 49 0.39556
## 50 0.40050
## 51 0.41183
## 52 0.42396
## 53 0.43496
## 54 0.44542
## 55 0.45443
## 56 0.46066
## 57 0.46367
## 58 0.46933
## 59 0.47758
## 60 0.48432
## 61 0.49190
## 62 0.49696
## 63 0.50106
## 64 0.50652
## 65 0.51284
## 66 0.51840
## 67 0.53189
## 68 0.53832
## 69 0.54337
## 70 0.54985
## 71 0.55878
## 72 0.56488
## 73 0.57345
## 74 0.58012
## 75 0.58567
## 76 0.59070
## 77 0.59419
## 78 0.59645
## 79 0.59999
## 80 0.60617
## 81 0.61141
## 82 0.61858
## 83 0.62250
## 84 0.62737
## 85 0.62954
## 86 0.63266
## 87 0.63683
## 88 0.64005
## 89 0.64847
## 90 0.64941
## 91 0.64996
## 92 0.65131
## 93 0.65194
## 94 0.65209
## 95 0.65476
## 96 0.65699
## 97 0.65863
## 98 0.66081
## 99 0.66112
## 100 0.66296
## 101 0.66524
## 102 0.66825
## 103 0.67124
## 104 0.67573
## 105 0.67739
## 106 0.67985
## 107 0.68225
## 108 0.68583
These plots suggest a major issue with this linear mixed model regression. The observation that the trajectories do not display a straight line in the log scale suggests these data do not follow an exponential growth model. It is more complicated than that. We see similar violations of straight lines in the death data (e.g., see the New York Times graphs on the number of deaths for a similar curvature away from a straight line). The violation of the exponential could be due to many factors, such as interventions of social distancing, diseases tend to follow an exponential curve early but then switch to a different process (see below for logistic growth curves), additional sources of noise contaminating the data such as reporting bias, etc.
Now that we understand the slopes and intercepts, let’s make some predictions. I’ll go 5 days out. The first plot will be on the log scale, but be mindful that these predictions are based on an exponential growth model that the residual analysis suggests may not hold for these data.
Using the same data I take the exponential of those predictions to see the percentages with their predicted curves. The Y axis is on the percentage scale (count/population * 100).
Other approaches I could have taken include using the state’s population as a weight and computed weighted linear mixed models on the log of the count data, or, because I’m working in log scale, I could use the state population as an offset in the linear mixed model (as in offset(log(population))) and use log counts as the dependent variable. These are alternative ways of taking population size into account. Further checks include taking into the account possible correlated residuals. For example, it isn’t reasonable to assume that the residual at day t is independent from the residual at day t+1 for a given state, which is what my model assumed in what I presented above. I’ll show how to include a correlation pattern on the residuals later in this chapter. There is clearly a lot more one would need to do in order to justify the use of the analytic strategy in this section.
Of course, once the basic structure of this linear mixed model on the log scale is set (e.g., error structure on residuals is determined, how best to use the state’s population in the model, etc), then one could bring in additional predictors. We could, for example, take some of the data sets we downloaded that have the dates of when states took different measures and see if any of those state mandates changed, say, the slopes for the states. At this point, once the complex error structure, linearity, and random effect structure are determined, then the rest is just routine regression that follows the analogous criteria in regression. For example, one could include interactions between predictors or controls using other predictors.
5.1.4 Comparison with polynomial regression
In the previous model I showed that the linear mixed model regression (allowing for each state to have their own slope and intercept) on the log of the state-level percentages can be used to model these data. Here I want to go on a little tangent and illustrate how well a polynomial can mimic the exponential pattern we see in the data.
Let’s take the case that in a particular locale the rate of covid-19 follows this general curve. In this subsection I made up the data so I know the curve follows exponential growth with an additive error term (the plus \(\epsilon\)) because I added random normally distributed noise with mean 0 and standard deviation .25.
I’ll run several regressions in order and produce one plot at the end. The points on the graph are the observed data points, the colored curves emerge from different regression models. The first regression is a linear regression with just x (days 1-25) as a linear predictor. I added a violet straight line to indicate the best fitting straight line—not a good fit. The second regression adds a quadratic term and will appear as a red curve. This is an improvement, but it is nonmonotonic and shows a decrease in the first few days (which is not a pattern displayed in the raw data). The third regression adds a cubic term and fits the points relatively well.
Next, I estimate the exponential directly using nonlinear regression. Instead of the parameter being a multiplier of the predictor (like in linear regression), the parameter serves as the growth factor. The green curve follows the data closely. Here only one parameter was estimated and it was .1502, very close to the actual .15 I used to estimate the data. The polynomial did quite well but needed 4 parameters (intercept and three slopes); those parameters are not easy to interpret. The single parameter of the exponential yields a very good fit with only one interpretable parameter. This makes sense because these hypothetical data were generated from an exponential model. Note that here I am using the nls() command, which estimates a nonlinear regression.
Finally, for comparison, I run a linear regression through these data after transforming the Y variable into the log, then re-expressing the predicted scores back to the original scale like I did in the predictions using the linear mixed model with the lmer() command above. I’ll draw that curve in black—very similar result to the nonlinear regression with the exponential and the third order polynomial.
Polynomials can do a reasonable job at capturing functions but they are not always easy to interpret without some additional work (e.g., Cudek & du Toit, 2002). The third order polynomial got close but good luck in interpreting the four parameters (intercept and three \(\beta\)s). The quadratic though while it was close predicts that the counts in the early days will drop (the red curves is decreasing from day 1 to day 4) so that’s not good because the data points don’t see to be showing that pattern.
While polynomials may do a good job of fitting data in hand, they may not be the useful for prediction and forecast—basically, extrapolating out of the range of the data. Here I take the same plot just examined but extend the prediction out 25 days beyond the data. The vertical black line marks the region of data (left) and prediction (right). The green curve is the estimated exponential growth fit to the data and extended 25 days out. The blue curve is the cubic form that fits the data relatively well (left side) but in extrapolation out 25 days from the data may not do a good job of predicting the actual curvature of the exponential function. The gray bands refer to the 95% prediction bands. Note that the bands for the exponential curve appear to be too narrow, and this is an outgrowth that the theory for such intervals in the nonlinear case is not clear cut. A simulation-based approach to estimate the prediction interval may be better.
Polynomials are frequently used. I found this website that uses a 4th order polynomial to model covid-19 data from Spain, Italy and US. This page also focuses on the daily incidence rate, a topic I mentioned earlier. Personally, I’m suspicious of using such high order terms to model such curves especially if they are used to forecast out from the data (i.e., extrapolation). [As of June 17, the website no longer shows polynomials.]
The polynomial idea to approximate functions can be extended in more complex ways. Here is a tutorial using the MARS package in R; this is probably the direction I’d go if I was interested in taking this type of approximation approach. But I’d rather stick to more interpretable functional forms for most of the remaining sections.
5.1.5 Thoughts on the log transformation
This type of model where we transform the dependent variable by converting to logs, creates an additive error term in the log scale; that is, log(counts) = f(days) + \(\epsilon\). But maybe that isn’t the right error structure. Maybe the error is added to the counts rather than the log of the counts; that is, the data may exhibit a counts = f(days) + \(\epsilon\) structure, which is a different error structure than the one on the log scale. The point here is that while one may think about using a transformation to linearize a model, that transformation also has an implicit set of assumptions and has potential side-effects on the modeling such as introducing particular error structure.
We now turn to modeling the curvature directly using nonlinear regression methods that not only permits complicated functioanl forms such as exponentials but also permits modeling the error as an additive effect on the counts as in the form: counts = f(days) + \(\epsilon\) model.
5.2 Exponential Nonlinear Mixed Model Regression
5.2.1 Exponential Background
For a good explanation of exponential growth and logistic growth (which will be described in the next subsection) see this video.
You can think of this exponential form as being similar to a balance in a savings account that builds with compound interest. At each time step, a percentage is added to the current principal thus increasing the balance in the savings account. At the subsequent time step, the principal is now higher so the interest earned on that day will also be higher than the previous time step. In the case of the covid-19 positive test counts, if each day the total count grows by some percentage, analogous to the principal in the savings account, then the growth is exponential.
I’m using one form of the exponential where the “rate” parameter is the base and it is raised to the power t. I did this to maintain a connection to the savings account analogy where the principal grows at rate x (where, say, a 5% interest rate has x = 1.05). The form is
\[ \begin{aligned} \mbox{count} &= y r^t \end{aligned} \] where t is the day, r is the rate (i.e., an “interest rate” of 5% has rate = 1.05), and y is a scaling parameter. The hypothetical plot above used a rate of 1.15 and a multiplier of .000555, which is in part based on the population of NY of 19.5M. I estimated these numbers from data collected in mid March, early into the covid-19 pandemic, and extrapolated out 60 days. Back in mid-March the idea of having 350,000 cases in New York within a couple of months seemed crazy. On May 7 New York reported 327,000 cases.
There are other forms of the exponential that are equivalent, just on a different scale. For example, in the natural log scale, the form I’m using \(yr^t\) is equivalently expressed as \(y*\exp{(log(r)t)}\) and in base 10 it is equivalently expressed as \(y*10^{log10(r)t}\). These are equivalent formulations, one just needs to keep track of the scale of the rate across these different choices of the base.
5.2.2 Exponential: The Liftoff Parameter
The exponential function can vary in terms of liftoff, where the curve breaks away from 0.
Here I plot two hypothetical states that have the identical set of parameters except that one state (black) has a liftoff of 0 and the other state (blue) has a liftoff of 4. It looks like the counts in the state depicted by the black curve is shooting up and by the end of the sequence almost double the count than the state represented by the blue curve.
To illustrate how time locking can show structure, let me use the previous plot, where the two states look to have different patterns. Time locking the two states to the first day when they each have nonzero cases shows that both states have identical trajectories. It is just that one state started earlier than the other state and so the patterns in the previous plot look (dramatically) different, and just by a delay of 4 days! Much like singing “Row, row, row your boat” in rounds—voices sing the same melody but start at different times creating a harmonious whole.
A good example of controlling for different liftoff patterns is by John Burn-Murdoch of the Financial Times. These visualization are unique from the ones I have seen on the web in that their curves are not plotted on calendar time but in terms of when the country hit X cases (sometimes X is 3 or 10 depending on the graph). This normalizes the onset and allows us to compare across units that had different starting points. A common phrase for this is “time locking” to a particular event, in this case time locking to when a country hit, say, 10 cases.
There is a sense in which we didn’t have to worry about liftoff in the linear mixed model on the log scale we ran in the previous subsection because the intercept parameter essentially took care of that. We could complicate the exponential model by including a random effect intercept, but I’ll keep things simple in these notes.
5.2.3 Estimating the exponential with the nonlinear mixed model
Let’s estimate an exponential growth model using a nonlinear mixed model regression. This mimics the LMER model we ran earlier in these notes but rather than transforming with a log to convert the data into straight lines, this time we model the curvature directly with an exponential function. To simplify things I constrain the liftoff parameter to 0 and the multiplier b1 to 1. To estimate all four parameters simultaneously we need to move to a different R package saemix that uses a stochastic EM algorithm to estimate this nonlinear mixed model because nlme can’t handle very complex models like this one without doing more ground work in setting up a self-starting function that has information about the gradient of the function. But, some additional work needs to be done to check that all four parameters can be estimated. There may be a redundancy with the rate and the b1 parameters (related to the base of the exponent that I described earlier in the Exponential Growth Background subsection when moving to different bases like base 10 or \(\exp\)). Sometimes parameters cannot be identified.
For these estimations I’m using percent of positive cases in the state (count/population) rather than the count.
Value | Std.Error | DF | t-value | p-value | |
---|---|---|---|---|---|
rate | 1.024 | 0.0007034 | 5295 | 1455 | 0 |
y | 0.07825 | 0.0145 | 5295 | 5.395 | 7.152e-08 |
Min | Q1 | Med | Q3 | Max |
---|---|---|---|---|
-5.73 | -0.3757 | -0.04362 | 0.2262 | 4.116 |
Observations | Groups | Log-restricted-likelihood | |
---|---|---|---|
state.abb | 5346 | 50 | 4247 |
lower | est. | upper | |
---|---|---|---|
rate | 1.02 | 1.024 | 1.025 |
y | 0.05 | 0.078 | 0.107 |
The fixed effects parameters refer to state-level parameters. You can think of these as the typical values for the states. The random effects part refers to the variability across states in those parameters. For example, while the fixed effects y parameter is estimated at 0.08, the states have a standard deviation of 0.102.
Let’s plot the fitted values of each state. These are the predicted exponential curves according to the model. Note that this plot represents the model estimates rather than the actual data.
We can examine specific states. The best fitting exponential curve for New York is shown in the next figure (observed data points are in blue).
Consistent to what we observed in the log transformed data and the linear mixed model, the points do not appear to follow an exponential curve, with the case of New York being one example.
We now examine the residuals to evaluate whether there is any structure the model is failing to pick up. The overall plot of the residuals suggests some major issues. For example, I colored in blue the residuals corresponding to New York and connected them with line segments to help them stand out. There is other structure in those residuals.
Here is a zoomed in version of the residual plot focusing in on the major “clump” of points.
The QQ plot raises further suspicion on this model due to the long tails.
Overall, the exponential curve does not appear to offer a solid representation of these data. This is consistent with the conclusion we reached from the linear mixed model on the log data. We will move to a different form that may be more appropriate for these data.
5.3 Logistic Nonlinear Mixed Regression
Let’s switch to a logistic growth model (which is not the same as logistic regression for binary data). The nlme package has some additional functions to simplify the fitting of logistic growth models (e.g., SSlogis), which make it easier to set up starting values. In other work I’ve seen more efficient estimation (and less fussiness around starting values) with the stochastic EM approach to fitting nonlinear regression models such as in the package saemix.
The nlme() command has a difficult time with the three parameters of the logistic growth model. I did a little bit of tinkering with starting values and the three parameters. I was able to get a reasonable fit with fitting three parameters of the logistic growth model and having two of them be random effects (i.e., they are allowed to vary by state). A more careful analysis would need to be done to make this publishable, including exploring other parameterizations of logistic growth that may behave better with nlme.
The logistic growth model starts off being close to an exponential at first but eventually tapers off. Many biological systems follow a logistic growth function. Here is a link to a relatively simple explanation of logistic growth.
This is the form of logistic growth I’m using
\[ \begin{aligned} count &= \frac{asymptote}{1 + ye^{\beta_1(day.mid - day)}} \end{aligned} \] The asymptote parameter controls the maximum value the function reaches, the day.mid parameter is both the day at which the function is half way to the asymptote and is also the inflection point and \(\beta_1\) is a scaling parameter defined to be the distance between the inflection point day.mid and point at which the count is 73% of the asymptote (basically, the difference between day.mid and the day corresponding to the count asymptote*\(\frac{1}{1+exp(-1)}\), see Pinhero & Bates). It is possible to have an extra parameter y, which is a multiplier, but be careful that the model is identified because \(y e^{x_1}\) can be reexpressed as \(e^{u + x1}\) where \(u=\log{(y)}\) creating issues in separately estimating y from additive parameters that are in the exponential. For most of the following I’ll constrain y to 1, thus setting the scale, and not estimate the y parameter.
The next three plots examine how each of the three parameters control the shape of the logistic growth curve. I’m making use of the SSlogis function to define these logistic growth curves. The SSlogis() function labels these parameters asym, xmid and scal, respectively.
Let’s fit this logistic growth function to these data. I now use the per capita count of positive tests out of 10,000 to normalize by state population.
## [1] "File name associated with this run is v.95-111-gbfd5aae-dataworkspace.RData"
Value | Std.Error | DF | t-value | p-value | |
---|---|---|---|---|---|
Asym | 79.83 | 8.651 | 5294 | 9.228 | 3.889e-20 |
xmid | 68.26 | 3.543 | 5294 | 19.27 | 5.339e-80 |
scal | 17.75 | 0.7954 | 5294 | 22.31 | 1.838e-105 |
Min | Q1 | Med | Q3 | Max |
---|---|---|---|---|
-4.882 | -0.6009 | -0.132 | 0.3575 | 6.159 |
Observations | Groups | Log-restricted-likelihood | |
---|---|---|---|
state.abb | 5346 | 50 | -12546 |
lower | est. | upper | |
---|---|---|---|
Asym | 62.9 | 79.8 | 96.8 |
xmid | 61.3 | 68.3 | 75.2 |
scal | 16.2 | 17.7 | 19.3 |
## lag ACF
## 1 0 1.000
## 2 1 0.972
## 3 2 0.936
## 4 3 0.895
## 5 4 0.848
## 6 5 0.795
## 7 6 0.737
We examine the same three residual plots that we used with the exponential growth model and see a slight improvement in the zoomed in version and slightly less extreme tails. While better, these residual plots suggest there is still some structure that is not adequately modeled. I also include the autocorrelation function plot, suggesting significant autocorrelation in the residuals that is not being modeled.
Below is the plot of the predicted curves for this logistic growth model. Notice that the fits for some states begin to taper off according to the logistic growth model. One could examine these differences to see which model performs better in predictive accuracy (i.e., see if the actual data for the state tapers off or continues to grow exponentially). Such patterns are testable and the ideal way to compare models and decide which one provides a better representation of the data.
Here is the predicted curve for New York with the actual data points in blue. We know from the analyses of the residuals that the model fit is still not ideal, but this plots suggests a logistic growth pattern is a reasonable fit to the data and better than the pure exponential growth model. Where the model is not capturing the data well is the liftoff and the sharp increase once the curve started to increase. There is also a pattern in the data around day 75 that is worth examining (e.g., checking what happened around that time in New York, such as a change in counting policy or a change in diagnostic test) and the actual data pattern is continuing to increase more rapidly than the predicted logistic growth model after day 55.
Another way to compare across models is to use an index such as the AIC, which is a measure based on information theory and akin to R^2 adjusted that can be used to compare regression models that vary in the number of parameters. One needs to be careful when using AIC across models where the dependent variable is on different scales as in these notes. For example, my log transform of percentage cases (count/population) in the linear mixed model is on a different scale than the exponential nonlinear regression model I computed above. R provides such information-based criteria measures such as AIC() and an alternative called BIC(). Here I give AIC and BIC for the logistic growth model. When comparing models on comparable dependent variables the model with the lower AIC (or BIC) value is selected.
## [1] 25112
## [1] 25178
The AIC is a function of the likelihood function and the number of parameters; BIC is a function of those two values as well as the number of data points. The two indices are functionally related by BIC = AIC + k*(log(n)-2). The logistic growth model I estimated has 7 parameters (three fixed effects, two random effects variances, one correlation between the two random effects and the residual variance) with n=5346.
Another consideration is that the residuals may not be independent given that these are time series data. Yesterday’s residual may be correlated with today’s residual. Here I add a correlation structure to the nlme command using an autocorrelation lag of 1 (AR p =1) and a moving average lag of 1 (MA q = 1). The ARMA implementation in nlme, though, operates completely on the residuals. So, the AR refers to the previous residual correlation and the MA refers to a set of independent and identically distributed noise terms apart from the residuals (see Pinhero & Bates, 2000, as this is not standard). You can think of the MA noise parameters are “factors” that are added to produce an additional source of correlation across residuals, much like a common factor would in a factor analysis model, but separate from the serial correlation of residuals. One could also try a heterogeneous residual variance model (the weight argument described above) along with the correlated error. More diagnostics would be needed to settle on the appropriate correlational structure for the error term plus the usual checks on the residuals to ensure we are properly meeting the statistical assumptions.
NEED TO FIX
Here is a test of the two logistic growth models (with and without correlated error structure). The model with correlated error structure fits significantly better with only two additional parameters: one for the autogressive portion and one for the moving average portion.
For illustration purposes, here is another way of fitting this model using a different package lme4. While lme4 is in some ways easier to use, it is not as flexible as nlme, which allows, for example, correlated error structure on the residuals and the ability to impose structure on the covariance matrix between random effects. This model includes random effects from the asym and xmid parameters but there are convergence issues when all three parameters are allowed to be random effects.
Estimate | Std. Error | t value | |
---|---|---|---|
asym | 61.79 | 0.1239 | 498.6 |
xmid | 57.59 | 0.1278 | 450.8 |
scal | 12.88 | 0.06371 | 202.2 |
5.3.1 Additional Predictors: Example with State-Level Poverty Rate
Now that we have a reasonable model, let’s see how we can include predictors to the model. One way to include predictors is to examine if the parameters of the logistic growth regression are influenced by the predictor, e.g. do the state asymptote parameters vary according to the predictor. We can accomplish this by, say, having the asymp parameter for each state be a linear function of the predictor, as in asym = \(\beta_0\) + \(\beta_2\) predictor + \(\epsilon\). Our current model is the special case where \(\beta_2\) is set to zero, thus asym = \(\beta_0\) + \(\epsilon\) where the intercept is the fixed effect (same value for each state) and the “\(\epsilon\)” is the random effect (a term associated with each state). By expanding the model to include a predictor associated with the asymp parameter we can examine if the predictor is linearly related to the asymp parameter.
For illustration, I examine whether the poverty rate in each state is associated with the “scal” random effect coefficient in the logistic growth model.
It looks like a slight positive association is present though the data are noisy. In principle, I could test this regression slope through a regular regression but it is better to do it in the context of the nonlinear logistic growth regression model directly. The reason is that a linear regression using the coefficients from the logistic growth as though they were an observed variable doesn’t take into account the error structure of these parameters—the parameters aren’t observed data but they are estimates from another model. By including the poverty predictor simultaneously in the logistic growth model, we can model the uncertainty much better. It would be even better to run this as a Bayesian model, which I’ll add in a later version using the brm package.
Value | Std.Error | DF | t-value | p-value | |
---|---|---|---|---|---|
Asym | 80.78 | 10.09 | 5293 | 8.006 | 1.445e-15 |
xmid | 68.33 | 3.717 | 5293 | 18.38 | 3.355e-73 |
scal | 14.77 | 1.995 | 5293 | 7.402 | 1.551e-13 |
b2 | 0.2315 | 0.1436 | 5293 | 1.611 | 0.1072 |
Min | Q1 | Med | Q3 | Max |
---|---|---|---|---|
-4.888 | -0.6051 | -0.1323 | 0.3573 | 6.159 |
Observations | Groups | Log-restricted-likelihood | |
---|---|---|---|
state.abb | 5346 | 50 | -12544 |
lower | est. | upper | |
---|---|---|---|
Asym | 61.01 | 80.784 | 100.557 |
xmid | 61.05 | 68.333 | 75.618 |
scal | 10.86 | 14.770 | 18.681 |
b2 | -0.05 | 0.231 | 0.513 |
DOUBLECHECK: significance status has changed.
The \(\beta\) associated with poverty is statistically significant in this example so there is evidence that the state variability in the scal parameter of this logistic growth model is associated with the state’s poverty level. In other words, state-level poverty is associated with how quickly a state increases in positive tests (the scal parameter). We need to be careful in interpreting this association given that the dependent variable we are using could reflect covid incidence but could also reflect the number of tests a state has conducted.
This example illustrates how one goes about adding predictors to such a nonlinear model. One could use more complicated predictors, even test differences across groups on parameter values (e.g., the question do states with democratic governors have different parameter values than states with republican governors, can be tested by creating an appropriate grouping code for the political party of the governor and including that code as a predictor in the same way I included the predictor poverty).
While the presentation has focused on associations, the overall framework can be extended to strengthen inference using various methods including instrumental variables (e.g., Carrol et al, 2004) and newer approaches (e.g., Runge et al, 2019), though much theoretical work remains to be done to move these nonlinear mixed models from mere description to stronger inferences by allowing more direct tests of possible alternative explanations. For an introduction to some basic modern methods in causal inference see Bauer and Cohen.
5.3.2 Additional assumption checking: random effect parameters
I’ll revert back to the simple logistic growth model at the start of this subsection. The residual plots already raised concern about the model fit. We can also examine additional assumptions of the model such as the distribution of the random effects. The random effect parameters in the nonlinear mixed logistic growth model are assumed to follow a multivariate normal distribution, which seems to be reasonable so many days into the pandemic. Here is a 2D density plot (I know, a lot to ask for when there are relatively few pairs of points, one for each state), separate qqplots and boxplots for the asymptote and scale parameters. The qqplot for the asymptote parameter has a long tail, mostly due to New York and New Jersey; the ones for the xmid and scal parameters look ok.
5.4 Evaluating Exponential and Logistic Growth Models
The overall point is that testing whether the data fit an exponential growth model, a logistic growth model, or various other plausible growth trajectories is not merely a modeling fitting exercise. There is much diagnostic testing one needs to do in order to figure out in what ways is a model working well and where it is messing up. The particular way a model is going awry may suggest directions for improvement and may offer clues about the underlying processes that generated the data, which is usually the important part of such an exercise.
The model selection game is more complex than merely selecting the model that has the best fit value on a standard metric such as AIC or BIC or predictive accuracy. To me, there is deeper insight that emerges from understanding the type of growth that is underlying the processes under investigation. We are in a better position to understand how to intervene if we understand the growth process that underlies a data set. Just because a model achieves relatively good performance on measures of fit does not imply that the model is following the same mechanisms of the processes that generated the actual data. This is where the diagnostic tests come in to help us diagnose such situations.
Let me illustrate what I mean by deeper implications. We know that if a growth pattern follows an exponential function, then the plot should be linear in the log scale. Think, the logical implication: “if p, then q”. Now, our data suggest that in the log scale we do not see linearity. What can we conclude? Well, through the logical contrapositive, the observation of not q, implies not p. In other words, the data rule out the simple exponential. Concluding that we can rule out an entire functional form from consideration is a more powerful result than merely claiming one model fits better than another.
The Center for Quality, Safety & Value Analytics at Rush University released a calculator that lets the user interactively change the model on cumulative cases. For example, one can click on exponential, or logistic, or (gasp) quadratic and run a model fit along with a forecast. The user can also select the state.
To get deeper in such process models of growth, we need to develop some additional machinery including differential equations, which are equations that govern changes over time. I’ll briefly touch on these models in the next chapter.
5.5 Splines, Smoothers and Time Series
I’ll briefly give an example of splines because it will be helpful in subsequent sections. I don’t recommend going the route of splines and smoothers in this context. While splines can provide great fit to the data and can be used for interpolation (e.g., if we missed a day of data collection, we could interpolate), splines and smoothers are not helpful at informing one of the underlying process nor in forecasting (extrapolating) from one’s data, which is what we want to be able to do in this case. For illustration, and to show that I too can get curves that approximate the data points closely, I ran a mixed model spline regression where the knots are treated as a random effect by state and show the plots just for New York and Michigan for brevity. One would need to do all the usual diagnostics for this mixed model as well.
The splines approach can be extended in the context of time series to permit forecasts. Here I’ll show the use of the forecast package and the excellent online book by Hyndman and Athanasopoulos. I’ll forecast 10 days out from the current date using New York data and compute an error band, show how to check residuals with the checkresiduals() command, and how to use hierarchical time series to model state trajectories within the US.
I tend to lump a different class of models into the bucket of models considered in this subsection. There are models that directly model the coefficients as varying by time. Polynomials can be thought of as having time varying coefficients. For example, the quadratic \(Y = \beta_0 + \beta_1 t + \beta_2 t^2\) can be rewritten as a linear regression with one predictor \(t\) that has intercept \(\beta_0\) and a time-varying slope term (\(\beta_1 + \beta_2 t)\). Splines extend this logic by allowing the slope at a given \(t\) to vary continuously. There are models that take this idea and run with it. One such approach is a nonhomogenous Poisson process, which uses the Poisson distribution to model counts and allows the rate parameter to vary by time (hence the term nonhomogenous). There are several R packages that implement such models, including NHPoisson and some extensions to spatial cases such as spatstat. .In the modeling presented in this book, we mostly work with counts so a Poisson would be a natural standard distribution to consider rather than blindly relying on normal distributions assumptions as I have done in several sections. I have highlighted how the normal distribution assumptions have been suspect. A different approach for implementing time-varying coefficients is in the R package tvReg.
5.6 Bayesian Estimation of Nonlinear Regression: Adding value to prediction and uncertainty
I will illustrate the use of Bayesian nonlinear regression modeling to estimate prediction uncertainty. The Bayesian approach also allows for more general models than the standard regression approaches described earlier in this chapter, these include expanding the assumptions limitations of the classic approach. For example, within a Bayesian approach one can include predictors of the variance terms, which is not easy to do in the classic setting. This could be useful, for example, if a predictor influences not only the value of a random effect parameter but also its variance. Or, we may be able to do a better job of developing models that are more appropriate for the count data we are using throughout these notes. Another example of something that is difficult to do in the classical framework is dealing with the distribution of random effects that do not follow a normal distribution. Earlier we saw that there may be two clusters of states and that the joint distribution of random effect parameters appears to be skewed. This makes suspect inferences based on random effects that assume a joint normal distribution. These nonstandard cases can be easily handled in the Bayesian framework.
I co-wrote an introductory chapter on Bayesian statistics with Fred Feinberg that highlights some of the advantages and disadvantages of the Bayesian framework. For a complete book on Bayesian statistics I very much like the comprehensive book by Gelman et al. Bayesian Data Analysis. A more readable textbook is Kruschke’s Doing Bayesian Data Analysis.
My Bayesian example here will take a problem that was extremely difficult in what we did earlier but is relatively easy to do in the Bayesian context: put intervals (or, as a Bayesian would say, credible intervals because the interpretation is slightly different than a standard confidence interval) around predictions form a nonlinear random effects regression model. This is an important detail that the classical approach has a difficult time addressing, as I mentioned in earlier subsections of this chapter when I wasn’t able to establish the uncertainty around the predictions. While uncertainty intervals around the parameter estimates are possible in the classical approach, computing error bars around the prediction interval in a random effects nonlinear model is not straightforward.
I’ll follow the same modeling implementation as used earlier. The brm() function in the brms package provides a convenient wrapper to the Stan Bayesian modeling using typical R commands. I’ll follow a similar set of assumptions as I did before (e.g., normally distributed random effects using relatively “flat” priors). The computation takes over four hours on my desktop computer so for now I’ll set the iteration to 2000 with 4 chains, which are the default settings. When these notes are complete and I’m no longer running the code each evening, I will increase the number of iterations, say, to 10000 and vary some of the other computational details to produce more stable estimates. Experts in Bayesian analysis will see some issues with the diagnostic plots I show but I’m sure many will agree with my decision to keep things relatively quick for now in this draft form.
NEED TO FIX BAYESIAN MODEL TO USE percap10000 dv
Here are the signature Bayesian plots of each parameter (density and trace plots) as well as the intercorrelations across the parameters.
## Family: gaussian
## Links: mu = identity; sigma = identity
## Formula: count ~ asymp/(1 + exp(b1 * (liftoff - day.numeric)))
## asymp ~ 1 + (1 | state.abb)
## b1 ~ 1
## liftoff ~ 1 + (1 | state.abb)
## Data: allstates.long (Number of observations: 3096)
## Samples: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
## total post-warmup samples = 4000
##
## Group-Level Effects:
## ~state.abb (Number of levels: 50)
## Estimate Est.Error l-95% CI
## sd(asymp_Intercept) 51126.47 5290.57 42011.74
## sd(liftoff_Intercept) 6.24 0.85 4.83
## u-95% CI Rhat Bulk_ESS Tail_ESS
## sd(asymp_Intercept) 62401.18 1.02 306 660
## sd(liftoff_Intercept) 8.11 1.00 830 1259
##
## Population-Level Effects:
## Estimate Est.Error l-95% CI u-95% CI
## asymp_Intercept 26053.45 7813.14 10030.09 40176.05
## b1_Intercept 0.12 0.00 0.12 0.12
## liftoff_Intercept 41.15 1.04 39.06 43.31
## Rhat Bulk_ESS Tail_ESS
## asymp_Intercept 1.26 13 20
## b1_Intercept 1.00 7468 2567
## liftoff_Intercept 1.01 477 754
##
## Family Specific Parameters:
## Estimate Est.Error l-95% CI u-95% CI Rhat
## sigma 1485.06 18.68 1448.80 1521.42 1.00
## Bulk_ESS Tail_ESS
## sigma 5914 3183
##
## Samples were drawn using sampling(NUTS). For each parameter, Bulk_ESS
## and Tail_ESS are effective sample size measures, and Rhat is the potential
## scale reduction factor on split chains (at convergence, Rhat = 1).
These are the prediction bands around the “fixed effect” part of the model and a plot for the state of Michigan.
5.6.1 Bayesian extensions
Pending: show a Bayesian approach to the generalized nonlinear mixed model
5.7 State-space modeling
The simple idea of a time series introduced earlier in Section @ref{splines} can be extend to a context involving a latent variable, or as it is called in this context, a state. The basic idea is that there are two equations governing different levels of analysis. One equation governs our observations and another equation govern a latent state.
One form of this approach has these equations. For the state-space portion, \[ S(t+1) = S(t) + \epsilon_s \] where S(t) is the state at time and the \(\epsilon_s\) is the noise in the state model. This equation governs the transition from one state to another at each time step possibly with error. The error is assumed to be normally distributed with mean = 0 and some variance. If the variance is constrained to be 0, then there is no noise in process modeling the transition across states. This model can be extend to include parameters, transition probabilities, covariates, structure on the error terms and other bells-and-whistles usually associated with regression models.
The second equation governs what we observe \[ Y(t) = S(t) + \epsilon_m \] where Y(t) is our observation at time t, S(t) is the state at time t and the \(\epsilon_m\) is the noise associated with our observation. Typically, the two \(\epsilon\)s in these two equations are assumed to be independent. If they are both normally distributed, then this is typically known as a dynamic linear model.
The way to think about these two equations is that there is a process governing the way way the system moves from time step to time step and there is an additional process that can lead to noisy observations of those states. There are analogous models in other areas of statistics (e.g., factor analysis can be represented in a similar way of a measurement model separate from a structural model).
I adapted some of the code from this webpage.
R example pending.
# keep library here while developing section
library(TSstudio)
library(dlm)
# split data to train on all but the last nahead data points
nahead <- 10
#work with daily counts
split.ny <- ts_split(ts(c(nycount.ts[1],diff(nycount.ts))), sample.out=nahead)
training <- split.ny$train
testing <- split.ny$test
model <- function(i) {
#return(dlmModPoly(3,dV=i[1], dW=i[2:3]))
return(dlmModPoly(2))
}
dlm.mle <- dlmMLE(training, parm = c(.1, .001, 1,1), build=model)
dlmfit <- model(dlm.mle$par)
#applying kalman filter
dlmfilter <- dlmFilter(training, dlmfit)
dlmsmoothed <- dlmSmooth(training, dlmfit)
I will return to state-space models in Chapter 6 when discussing process models.
5.8 Basic Machine Learning Examples
In my opinion, while impressive progress has been made in text analysis and image analysis, the machine learning literature has lagged behind where it needs to be on development of methods that address multiple time series (e.g., times series by state, country or county). Here I review one approach, an implementation of a recurrent neural network (RNN) that I used for the data from New York state. We need to use an RNN, a specialized version of a neural network, because we have time series data. Here is one description, another description and a third description by UM’s Ivo Dinov of RNNs. The R package I will illustrate is rnn and it is a basic implementation of a recurrent neural network. There are much better implementations, such as the keras package and I’ll explore that later once I make more progress on other parts of these notes. For now, we’ll use the very simplified rnn package in R.
The underlying common element of a neural network is that they take inputs, weight them, sum and add a “bias” term. This is similar to regression in weighting predictors by betas, sum the products and add and intercept. The weighted sum is then converted into a number between 0 and 1, using the logistic form similar to logistic regression that converts the model on the real number line into the scale of the dependent variable that is a probability between 0 and 1. This can be done repeatedly to create multiple units, or different sets of weighted sums, in a manner similar to principal components analysis (PCA) where the observed variables are weighted and summed to produce components. It is possible to create additional layers with new outputs based on these weighted sums (so, weighted sums of nonlinear transformations of weighted sums). The the final layer of units is then mapped onto the outcome variable.
Here is a graphical representation of what I mean. This example has four inputs (i.e., four variables or features), one hidden layer with 8 units, and one output layer that is a single number prediction (like our counts of positive tests). The hidden layer is a set of 8 units. The two B terms are the “bias” terms that feed into the weighted sums. The thick black lines refer to higher positive weights and the thicker gray refer to smaller negative. Example adapted from the tutorial in the NeuralNetTools R package.
The RNN approach we will use is a simplified version. More appropriate approaches would be long short-term memory models.
It is common to model time series using the counts for each day (such as with the incidence plot we saw in the Section 4.4) rather than the cumulative counts we have been using throughout most of these notes. I’ll follow that convention here.
The incident plot for New York State.
5.8.1 Simple RNN example
The following involves a relatively large chunk of code. Other implementations of deep learning networks require even more code. The basic idea is that we put all our data into one data frame, then partition it into testing data and training data. We want to be sure we partition early so as not to contaminate the testing data with any information that is in the testing data. For example, if we compute a mean we may inadvertently compute a mean for all the data (testing and training), and then if we use that mean in training we have contaminated the training data with information from the testing data.
The only information I have to work with so far is the number days and the previously observed daily counts; that is, as of this point in these notes we don’t have access to other possible predictors of a state’s daily count. Here, “previously observed” means if I’m at time t, then any data prior to t is “previous” data that I have but any data after t has not occurred. In the case of data I’m downloading, t may be, say, 4/10/20 so from that perspective any data after 4/10/20 cannot be used because as of that time point t I don’t know of data after t. Part of the machine learning algorithm works by varying t to different days, repeatedly feeding those sequences of data to the model and trying to learn the patterns by figuring out what it is getting wrong, making adjustments in the model’s parameters (the weights and bias terms) and making new predictions, and iterating that process.
The rest of the code is creating daily counts and several features to use as predictors. We don’t have a rich set of predictors set up yet so I created some from the day variable. I will use day, day\(^2\) and day\(^3\) (of course, mean centering day before computing the higher order terms). I created a predictor of how much daily change there was (e.g., the count at t minus the count at t - 1). This serves as a slope estimate of change, which is a first order difference because I’m working in discrete time (days); technically, it is a secant rather than the slope (which would correspond to the tangent). I also created a “difference of difference” (or second order difference analogous to acceleration, or how the change is changing) to measure how much the slope is changing from day to day. In other words how different is the change today from the change we saw yesterday. This process of creating new variables from existing variables is called “feature engineering.”
This model has 7 inputs: day, day\(^2\), day\(^3\), count, count difference, count second order difference and running mean of the counts from the previous 3 days. I currently have just have a few units in a single hidden layer, and one unit in the output layer. Of course, to make this more interesting I could add many more predictors including state-level and daily information (e.g., measures of compliance to social distancing measures; weather, which could affect people’s behavior going outside; changes in a state’s social distancing policy).
In the figure below the red points are the actual daily cases in New York. The green curve is what the machine learning model learned. I intentionally over trained the model. The last day shows the prediction by the machine learning model in solid blue and the actual in solid red.
I’ll be the first to acknowledge that this example is just for demonstration purposes. Our data set is way, way too small to have any chance of estimating meaningful machine learning models, I created a kludgy set of predictors (aka features) without much thought, I haven’t included more predictors to the model and I’ve only focused on number of positive tests (e.g., a better demonstration of machine learning methods would be to use positive testing rates as predictors of outcomes such as subsequent death rates). the particular forms of the predictors I’m using (polynomial, first and second order differences) are known not to behave well when extrapolating beyond one’s data, as we are doing here when predicting the subsequent day. I also have not optimized for the various tuning parameters including the learning rate, so there is much one can do to improve the fit of this particular example.
There are more diagnostics to consider such as error in prediction and we can iterate over the tuning parameters to find optimal values that give good predictive validity without overfitting. Note that between day 25 and 40 the overall “trend” of the open red circles is relatively flat (as an average) but the daily variability is increasing. The current set of predictors I’m using in this RNN doesn’t have the ability to easily capture changes in the variability. This is one clue for additional predictors (features, see next subsection) that could be added to the model. This could be an interesting part of the story and something that can be addressed not only with machine learning models but also for the other models we considered in this chapter. Models that are not capturing this change in variance are possibly missing something important about the underlying process (which could just be something as simple as not all jurisdictions in New York state are reporting daily but nonetheless an important property to understand if we want to use these approaches to make forecasts). We could check whether this increasing variance occurs in other states and at different levels of analysis such as the county level. We could check whether this increase in variance is consistent with a multiplicative error model where error (the “plus \(\epsilon\)” term we discussed earlier) could provide a clue to the underlying process. The point is that there is a potential signal here that our current models are not capturing, and we need to figure out whether we need to move to a different class of models or whether this heterogeneity is due to a simple factor that can be easily addressed.
The increasing variance was not easy to detect in the cumulative plots and models on cumulative data such as the log linear, exponential and logistic models we covered earlier in this chapter. If you go back and look at those plots, even the ones using the curve fitting spline methods, they show systematic “under and over the curve” errors consistent with what we are seeing in the incidence plot. The increasing variance is there but just difficult to spot in the way we examined these data previously. Sometimes converting data to different forms, such as cumulative and incidence forms, helps highlight different aspects of the same data. It is not easy to see in the barplot of the New York incidence presented at the beginning of the RNN section. It is often useful to cross-check one’s interpretation with different model forms and plots.
There are many other approaches that fall under the large machine learning umbrella, these include extensions of RNNs such as long short-term memory deep learning models that can learn patterns further back in time than simple RNNs, general additive models with penalized smoothers, genetic algorithms, and symbolic regression as well as several packages in R to compute these methods. Overall, I was underwhelmed by the effort so far. Some of the R packages gave error messages even running the very examples supplied in the package or they made strange predictions. Part of the issue is that we don’t have enough data to allow these machine learning methods to shine. For a more detailed and systematic discussion machine learning approaches for time series data see Makridakis et al.
5.8.2 Gaussian Process Regression
There are many approaches that fall under the Machine Learning umbrella, with neural networks presented in the previous subsection being just one type of approach. In this subsection I will consider a different approach that mingles Bayesian methods with machine learning approaches and standard statistical models. The approach is to treat the function as a draw from a parent distribution of functions (see Erickson for a short introduction and Rasmussen & Williams (2006) for a book length treatment). I demonstrate one implementation using the GauPro package in R. The default is a Gaussian kernel but other can be used as well. In this demonstration I stick with the default settings but these can be tuned as with most machine learning algorithms.
There are related approaches in the area of functional data analysis that also treat the function as a sample but they use different estimation approaches than those in used in Gaussian process models.
5.8.3 Feature engineering
To implement machine learning methods for these data I need to spend more time thinking about the feature engineering side of things. In machine learning parlance feature engineering refers to how the input variables are processed. When one works with time, for instance, it is common to think about multiple ways that time could enter into the model and include all of them. Machine learning algorithms are designed to drop out the irrelevant formulations. There is a commonly used time series package used in machine learning (TSFRESH in python and an effort to port this to R tsfeaturex) that computes several hundred possible measures on each time series (mean, max, min, variance, entropy, auto-correlation, etc) and stores these computations into a large matrix so that they can be used down stream in subsequent analyses. I didn’t put in the effort to go through the sensible features to compute and include those as input into the models so I shouldn’t be surprised at the relatively low performance of these models given that I didn’t play by the rules of machine learning.
The concept of feature engineering is much like entering linear, quadratic, cubic terms of a predictor into a regression equation. The idea is that variants of the predictor in the form of a polynomial are treated as predictors. Take that idea, inject it with steroids, and you have feature engineering in machine learning.
As a simple illustration of feature extraction, here is the output of the daily count variable for each of the 50 states.
## # A tibble: 6 x 2
## state.abb f.median_count
## <fct> <dbl>
## 1 Alabama 8000
## 2 Alaska 369
## 3 Arizona 8166.
## 4 Arkansas 3464
## 5 California 52686.
## 6 Colorado 16009
As you can see tsfeaturex computes 82 different measures on the count data for each state. Those 82 measures could then be included as state-level predictors in a machine learning algorithm using a type of regularizer that introduces sparseness (drops predictors that are not useful in the prediction).
A more appropriate machine learning strategy would be to take the time trajectory data for every country reported in the Johns Hopkins site (about 140 countries) and see if we can learn patterns about the nature of the trajectories, given various aspects of the country’s demographics, dates they instituted various policies (shelter at home), information about their health care system, etc. One could use the principles developed here about web scraping and gathering these other sources of data, merging them into a single file, and running appropriate machine learning algorithms to find patterns.
An interesting use of machine learning methods (specifically computer vision) is the development of a physical distancing index by a group at UM. Physical movement of humans and social distancing is detected in major cities. This website has some live cameras and charts to illustrate their index.
I’ll continue adding to this section and improving the quality of the machine learning example as time frees up from completing other sections.
5.9 Summary
We covered a lot of material in this chapter. We started with a simple linear mixed model on log transformed data that seemingly did a reasonable job of accounting for the patterns across states. The finding that the linear relation in the log scale holds fairly well suggests that there is exponential growth. The ability to make a statement about the underlying process, in this case exponential growth, is far more valuable than finding a good fit to a data set. But there was a suggestion that the exponential may not be the ideal fit as there was some systematic deviation from a growth curve. The rest of these notes covered a more direct way of fitting exponential growth models through nonlinear regression, a different type of growth model based on the logistic curve and a toy example using a standard machine learning example.
A key idea I followed in this chapter is not to have a single pattern that represents all states but to use models that simultaneously tell us something about the overall pattern across states (the fixed effect portion of the output) and the variability, or heterogeneity, across the states (the random effect portion of the model). We could get fancier with this idea where, for example, we could weight the results based on population size of each state, so counts from more populous states receive more weight. There are several generalizations of these notions from different perspectives such as statistics and machine learning that you can follow in papers (e.g., varying coefficient models such as one by Hastie and Tibshirani and extensions of tree-based methods like CART in the R package vcrpart) as well as books (Hastie et al; Ramsey & Silverman). Once we properly characterize the shape of the trajectories and the variability across units, we can then study the associations between predictors and the parameters of the model, such as I attempted to do with the state-level poverty data and a parameter from the logistic growth model.