delicatessen.sandwich.delta_method
- delta_method(theta, g, covariance, deriv_method='exact', dx=1e-09)
Function to apply the Delta Method for a given parameter vector and transformation. The Delta Method is defined as
\[Var \left[ g(\theta) \right] \approx g'(\theta) \; \Sigma_{\theta} \; g'(\theta)^T\]where \(\theta\) is the parameter vector, \(g\) is a vector-valued function that returns a 1 dimensional vector, \(g'\) is the gradient (or partial derivatives), and \(\Sigma_{\theta}\) is the covariance matrix for \(\theta\). In words, the variance of the transformation of the parameters is equal to covariance of the parameters sandwiched between the derivatives of the transformation functions. This expression then provides a variance estimator when replacing \(\theta\) and \(\Sigma\) with \(\hat{\theta}\) and \(\hat{\Sigma}\), respectively.
As described elsewhere, the sandwich variance estimator automates the Delta Method. Therefore, one can simply program the corresponding estimating equation to estimate the variance for that transformation. However, this can be computationally inefficient when \(g\) outputs a large vector. This functionality offers a way to apply the Delta Method outside of
MEstimatorandGMMEstimator. Internally, this function is used to compute the variance for some prediction functionalities.- Parameters
theta (ndarray, list, set) – Parameter vector of dimension v to apply the transformation function
gwith.g (function, callable) – Vector function that transforms the v dimension parameter vector
thetainto a w dimensional vector.covariance (ndarray, list, set) – Corresponding cvariance matrix for the parameter vector
theta.deriv_method (str, optional) – Method to compute the derivative of the function
g. Default is'exact'. Options include numerical approximation via the forward difference method via SciPy ('approx'), forward difference implemented by-hand (‘fapprox’), backward difference implemented by-hand (‘bapprox’), central difference implemented by-hand (‘capprox’), or forward-mode automatic differentiation ('exact').dx (float, optional) – Spacing to use to numerically approximate the partial derivatives of the bread matrix. Here, a small value for
dxshould be used, since some large values can result in poor approximations. This argument is only used when numerical approximation methods. Default is1e-9.
- Returns
Returns a p-by-p NumPy array for the input
theta, where p is the length of the output vector from the function \(g\)- Return type
array
Examples
To illustrate how
delta_methodis intended to be used, we will first use an M-estimator to compute the point and variance estimates for the parameter vector \(\theta\).>>> import numpy as np >>> import pandas as pd >>> from delicatessen import MEstimator, delta_method >>> from delicatessen.estimating_equations import ee_ipw
Here, we will replicate the example from the documentation for
ee_ipw.>>> n = 200 >>> d = pd.DataFrame() >>> d['W'] = np.random.binomial(1, p=0.5, size=n) >>> d['A'] = np.random.binomial(1, p=(0.25 + 0.5*d['W']), size=n) >>> d['Ya0'] = np.random.binomial(1, p=(0.75 - 0.5*d['W']), size=n) >>> d['Ya1'] = np.random.binomial(1, p=(0.75 - 0.5*d['W'] - 0.1*1), size=n) >>> d['Y'] = (1-d['A'])*d['Ya0'] + d['A']*d['Ya1'] >>> d['C'] = 1
Defining \(psi\), or the stacked estimating equations
>>> def psi(theta): >>> return ee_ipw(theta, y=d['Y'], A=d['A'], >>> W=d[['C', 'W']])
Calling the M-estimation procedure
>>> estr = MEstimator(stacked_equations=psi, init=[0., 0.5, 0.5, 0., 0.]) >>> estr.estimate(solver='lm')
Per the documentation for
ee_ipw, the average causal effect (or risk difference) is given by the following>>> estr.theta[0] # causal mean difference of 1 versus 0 >>> estr.variance[0, 0] # corresponding variance estimate
Now suppose that
ee_ipwdid not directly provide the risk difference. Further, imagine we were interested in the risk ratio (log-transformed). Both of these quantities are transformations of the risk under action 1 (i.e.,theta[1]) and the risk under action 0 (i.e.,theta[2]). The following defines a function that applies and returns this pair of transformations>>> def causal_contrasts(theta): >>> risk1, risk0 = theta >>> risk_diff = risk1 - risk0 >>> log_risk_ratio = np.log(risk1) - np.log(risk0) >>> return risk_diff, log_risk_ratio
To estimate the variance for this transformation, one can now use the delta method. While one could manually compute the derivatives for this function,
delta_methodautomates this procedure. Below is howdelta_methodcan be applied to compute the variance>>> risks = estr.theta[1:3] # Risks >>> risks_c0var = estr.variance[1:3, 1:3] # Variance for risks >>> rd, log_rr = causal_contrasts(theta=risks) # RD, log(RR)
>>> covar = delta_method(theta=risks, # Delta method >>> g=causal_contrasts, # ... function g >>> covariance=risks_c0var) # ... covariance
The output from
delta_methodis the corresponding covariance matrix for risk difference and risk ratio. We can get the corresponding 95% confidence intervals via>>> rd_stderr = np.sqrt(covar[0, 0]) >>> rd_lcl, rd_ucl = rd - 1.96*rd_stderr, rd + 1.96*rd_stderr >>> rr_stderr = np.sqrt(covar[1, 1]) >>> rr_lcl, rr_ucl = np.exp(log_rr - 1.96*rr_stderr), np.exp(log_rr + 1.96*rr_stderr)
While these transformations are straightforward to stack as estimating functions,
delta_methodoffers another option for estimating the variance of transformations that offers computational benefits in some settings.References
Boos DD, & Stefanski LA. (2013). Large Sample Theory: The Basics, In Essential Statistical Inference: Theory and Methods, 237-240.
Cox C. (2005). Delta method. Encyclopedia of Biostatistics.
Oehlert GW. (1992). A Note on the Delta Method. The American Statistician, 46(1), 27-29.