MVGC permutation test demo
Demonstrates permutation significance testing with MVGC on generated VAR data for a 5-node network with known causal structure (see var5_test). Pairwise-conditional Granger causalities are estimated and significance tested using both the theoretical and permutation test null distributions. The theoretical and permutation test null distributions for all pairs are plotted together and compared using a Kolmogorov-Smirnov test (see kstest).
Contents
References
[1] L. Barnett and A. K. Seth, The MVGC Multivariate Granger Causality Toolbox: A New Approach to Granger-causal Inference, J. Neurosci. Methods 223, 2014 [ preprint ].
[2] M. J. Anderson and J. Robinson, Permutation tests for linear models, Aust. N. Z. J. Stat., 43(1), 2001.
Parameters
ntrials = 10; % number of trials nobs = 1000; % number of observations per trial nperms = 100; % number of permutations for permutation test bsize = []; % permutation test block size: empty for automatic (uses model order) regmode = 'OLS'; % VAR model estimation regression mode ('OLS', 'LWR' or empty for default) acmaxlags = 1000; % maximum autocovariance lags (empty for automatic calculation) tstat = ''; % statistical test for MVGC: 'F' for Granger's F-test, 'chi2' for Geweke's chi2 test or leave empty for default alpha = 0.05; % significance level for all statistical tests mhtc = 'FDR'; % multiple hypothesis test correction (see routine 'significance') seed = 0; % random seed (0 for unseeded)
Generate VAR data
% Seed random number generator. rng_seed(seed); % Get VAR coefficients for 5-node test network. AT = var5_test; nvars = size(AT,1); % number of variables % Residuals covariance matrix. SIGT = eye(nvars); % Generate VAR time series data with normally distributed residuals for % specified coefficients and covariance matrix. ptic('\n*** var_to_tsdata... '); X = var_to_tsdata(AT,SIGT,nobs,ntrials); ptoc;
VAR model estimation and autocovariance calculation
morder = size(AT,3); % actual model order; on real data - i.e. with no generative model % available - use information criteria to estimate (see 'mvgc_demo') % Calculate VAR model ptic('*** tsdata_to_var... '); [A,SIG] = tsdata_to_var(X,morder,regmode); ptoc; % Check for failed regression assert(~isbad(A),'VAR estimation failed'); % Now calculate autocovariance according to the VAR model, to as many lags % as it takes to decay to below the numerical tolerance level, or to acmaxlags % lags if specified (i.e. non-empty). ptic('*** var_to_autocov... '); [G,res] = var_to_autocov(A,SIG,acmaxlags); ptoc; % Report and check for errors. fprintf('\nVAR check:\n'); disp(res); % report results... assert(~res.error,'bad VAR'); % ...and bail out if there are errors
Granger causality estimation
% Calculate time-domain pairwise conditional causalities. ptic('*** autocov_to_pwcgc... '); F = autocov_to_pwcgc(G); ptoc; % Theoretical significance test (adjusting for multiple hypotheses). pval_t = mvgc_pval(F,morder,nobs,ntrials,1,1,nvars-2,tstat); sig_t = significance(pval_t,alpha,mhtc);
Permutation test
ptic('\n*** tsdata_to_mvgc_pwc_permtest\n'); FNULL = permtest_tsdata_to_pwcgc(X,morder,bsize,nperms,regmode,acmaxlags); ptoc('*** tsdata_to_mvgc_pwc_permtest took ',[],1); % (We should really check for permutation estimates here.) % Permutation test significance test (adjusting for multiple hypotheses). pval_p = empirical_pval(F,FNULL); sig_p = significance(pval_p,alpha,mhtc);
Plot causalities, p-values, significance and cdfs
figure(1); clf; subplot(2,3,1); plot_pw(F); title('Pairwise-conditional GC'); subplot(2,3,2); plot_pw(pval_t); title({'p-values';'(theoretical)'}); subplot(2,3,3); plot_pw(sig_t); title({['Significant at p = ' num2str(alpha)];'(theoretical)'}); subplot(2,3,5); plot_pw(pval_p); title({'p-values';'(perm test)'}); subplot(2,3,6); plot_pw(sig_p); title({['Significant at p = ' num2str(alpha)];'(perm test)'}); % Plot empirical vs theoretical null cdfs, perform Kolmogorov-Smirnov tests on % null/theoretical distributions. figure(2); clf; pval_ks = nan(nvars); % KS test p-value fmax = max(FNULL(:)); k = 0; for i = 1:nvars for j = 1:nvars k = k+1; if i ~= j FN = sort(FNULL(:,i,j)); PN = empirical_cdf(FN,FNULL(:,i,j)); PT = 1-mvgc_pval(FN,morder,nobs,ntrials,1,1,nvars-2,tstat); % theoretical cdf = 1 - p-value subplot(nvars,nvars,k); plot(FN,[PN PT]); title(sprintf('%d -> %d',j,i)); xlim([0 fmax]); [~, pval_ks(i,j)] = kstest(FN,[FN PT]); % 2-sided KS test of empirical vs. theoretical null distribution end end end % KS significance test (adjusting for multiple hypotheses). sig_ks = significance(pval_ks,alpha,mhtc); % 1 = distributions are significantly different at level alpha fprintf('\nKS-test p-values:\n\n'); disp(pval_ks); fprintf('KS significance test; ones indicates that permutation and theoretical\nnull distributions are significantly different at p-value %g; \n\n',alpha); disp(sig_ks);