--- title: "VGAMs for survey data: theory" author: "Thomas Lumley" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{VGAMs for survey data: theory} %\VignetteEngine{knitr::rmarkdown} \usepackage[utf8]{inputenc} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE) ``` The **VGAM** package's `vglm()` function, like the **survey** package's `svymle()` function, allows for maximum likelihood fitting where linear predictors are added to one or more parameters of a distribution --- but `vglm()` is a lot faster and has many distributions already built in. This is how we make **svyVGAM** handle complex sampling. I will write $\beta$ for the regression parameters, $\theta$ for the base parameters of the response distribution, and $\eta$ for the linear predictors. So, for example, in a classical linear model there would be two parameters $\theta$: the mean ($\theta_1$) and variance ($\theta_2$). The mean would have a set of regression parameters and the variance would have a single parameter. Collectively, these would be $\beta$ (maybe $\beta_{11}\dots\beta_{1p}$ and $\beta_{21}$), and the two combinations that are plugged in as $\theta$ would be called $\eta_1$ and $\eta_2$. The big advantage of **VGAM** is that it does a lot of the work for the user: while the user can add new families, there are many pre-prepared ones, and there are built-in ways to constrain parameters to be equal or related in some other way. To provide survey versions of `vglm()`, we need to (a) get design-consistent point estimates out of `vglm()`, and (b) construct design-based standard errors for the fit. The first is easy: `vglm()` accepts frequency weights, which are [equivalent to sampling weights for point estimation](https://notstatschat.rbind.io/2020/08/04/weights-in-statistics/) with independent observations. The second can be done in two ways: resampling (which is straightforward, if potentially slow), and linearisation. Linearisation requires computing the influence functions of the parameters $$h_i(\beta) = -\widehat{\cal I}^{-1}_w U_i(\beta)$$ where $\widehat{\cal I}_w$ is the weighted estimate of the population Fisher information, $U_i=\partial_\beta \ell_i(\beta)$ is the loglikelihood contribution of the $i$th observation, and $w_i$ is its weight. The influence functions have the property $$\hat\beta-\beta_0 = \sum_i w_i h_i(\beta_0)+o_p(\|\hat\beta-\beta_0\|)$$ so that the variance of $\hat\beta$ is asymptotically the variance of the population total of the influence functions. The survey package provides a function `svyrecvar()` to estimate standard errors given the influence functions, or (a bit less efficiently) you can just call `svytotal()`. ### Resampling A design object of class `svyrep.design` contains sets of replicate weights analogous to jackknife or bootstrap replicates. We need to call `vglm()` with each set of weights. It should be helpful to specify the full-sample estimates as starting values. One complication is that sets of replicate weights will typically include some zeroes, which `vglm()` does not allow (eg, a bootstrap or jackknife resample will omit some observations). We set these to $10^{-9}$ times the maximum weight, which has the desired effect that the observations are present in the fit but with (effectively) zero weight. ### Linearisation The `cov.unscaled` slot of a `summary.vglm` object contains the inverse of the estimated population Fisher information, $\widehat{\cal I}^{-1}_w$. The `vglm` object provides $\partial_\eta\ell_i(\eta)$ for the base parameters $\theta$, and also the model matrices that specify $\partial_\beta\eta$, so we can construct $U_i$. We need to take care with the constraints, which can cause a coefficient $\beta$ to appear in more than one linear predictor. Suppose $\beta_x$ appears in both $\eta_1$ and $\eta_2$, with $x$ values $x_1$ and $x_2$. The chain rule tells us $$\partial_{\beta_x}\ell_i =\partial_{\eta_1}\ell_i\partial_{\beta_x}\eta_1 + \partial_{\eta_2}\ell_i\partial_{\beta_x}\eta_2 = (\partial_{\eta_1}\ell_i) x_{1i}+ (\partial_{\eta_2}\ell_i) x_{2i} $$ We might have $x_1\equiv x_2\,(=x)$, but that just means $$\partial_{\beta_x}\ell_i = (\partial_{\eta_1}\ell_i) x_{i}+ (\partial_{\eta_2}\ell_i) x_{i} $$ The constraint matrix $C$ consists of 1s and 0s. If there are $p$ parameters in $M$ equations the matrix is $M\times p$, with $C_{jk}=1$ if parameter $k$ is in linear predictor $j$. In the default, unconstrained setup, the constraint matrix consists of an $M\times M$ identity matrix for each parameter, pasted columnwise to give a $M\times pM$ matrix. In the proportional odds model, as another example, there are separate intercepts for each linear predictor but the other parameters all appear in every linear predictor. The first $M\times M$ block is the identity, and the rest of the matrix is a column of 1s for each predictor variable. Another way to say this is that $C_{jk}=\partial_{ (\beta_kx_k)}\eta_j$ So, if we want $\partial\beta\ell_i$, the chain rule says \begin{eqnarray*} \frac{\partial \ell_i}{\partial \beta_j} &=& \sum_k\frac{\partial \ell_i}{\partial\eta_k} \frac{\partial \eta_k}{\partial \beta_j}\\ &=& \sum_k\frac{\partial \ell_i}{\partial \eta_k} \frac{\partial \eta_k}{\partial (x\beta)_j}\frac{\partial (x\beta)_j}{\partial \beta_j}\\ &=&\sum_k \frac{\partial \ell_i}{\partial \eta_k} C_{kj}x_{ij} \end{eqnarray*} There is one further complication. The `model.matrix` method for `vglm` objects returns a model matrix of dimension $Mn\times p$ rather than $n\times p$, so we need to sum over the rows for each observation, which can be identified from the row names, and then rescale. The right standardisation appears to come from defining $$\tilde C_{kj}=\frac{C_{kj}}{\sum_k C_{kj}}$$ and then $$\frac{\partial \ell_i}{\partial \beta_j}=\sum_k \frac{\partial \ell_i}{\partial \eta_k} \tilde C_{kj}x_{ikj}.$$