📄 ols_gcbma.m
字号:
function results = ols_gcbma(y,x,ndraw,prior)
% PURPOSE: MC^3 x-matrix specification for homoscedastic OLS model
% ------------------------------------------------------
% usage: results = ols_gcbma(y,x,ndraw,prior)
% where: % where: y = dependent variable vector (nobs x 1)
% x = studentized or well-scaled x-matrix (you should include an
% intercept)
% ndraw = # of draws
% prior = a structure variable with:
% prior.g = g-value for g-prior, default: max(1/n,1/k^2)
% prior.nmodels = # of top models to save (default = 1000)
% prior.nu = informative Gamma(nu,d0) prior on sige
% prior.d0 = default: nu=0,d0=0 (diffuse prior)
%-------------------------------------------------------------
% RETURNS: a structure:
% results.meth = 'ols_gcbma'
% results.munique = # of unique models found
% results.nmodels = # of top models to save from input or (default = 1000)
% results.freqs = a matrix with frequency distribution of
% variables appearing in all unique models found
% results.models = a matrix with top nmodels information
% results.allmodels = a matrix with info on all unique models found
% results.mprob = a vector of posterior model probabilities
% results.vprob = a vector with variable probabilities
% results.nobs = # of observations
% results.nvar = # of variables in x-matrix
% results.ndraw = # of draws
% results.y = y-vector from input (nobs x 1)
% results.nu = nu prior parameter
% results.d0 = d0 prior parameter
% results.time1 = time for BMA sampling
% results.time2 = total time taken
% --------------------------------------------------------------
% NOTES: 1) the model descriptions and log-marginals for all unique models found
% are written to a file lmarginal.ols
% --------------------------------------------------------------
% SEE ALSO: prt_bmao(), for printing results
% model_averageo() function, that can be used to construct
% estimates based on averaging over models using posterior
% model probabilities as weights
% --------------------------------------------------------------
% REFERENCES:
% Fernandez,Carmen, Eduardo Ley, and Mark F. J. Steel, (2001a)
%'Model uncertainty in cross-country growth regressions,'
% Journal of Applied Econometrics}, Volume 16, number 5, pp. 563 - 576.
%
% Fernandez,Carmen, Eduardo Ley, and Mark F. J. Steel, (2001b)
% 'Benchmark priors for Bayesian model averaging', Journal of Econometrics
% Volume 100, number 2, pp. 381-427.
%----------------------------------------------------------------
% written by:
% James P. LeSage, last updated 6/2004
% Dept of Economics
% University of Toledo
% 2801 W. Bancroft St,
% Toledo, OH 43606
% jlesage@spatial-econometrics.com
t1 = clock;
% error checking on inputs
[n junk] = size(y);
[n1 k] = size(x);
time1 = 0;
time2 = 0;
nobsa = n;
results.nobs = n;
results.nvar = k;
results.y = y;
if n1 ~= n
error('ols_gcbma: x-matrix contains wrong # of observations');
end;
[nu,d0,sige,g,gmodels] = ols_parse(prior,x);
nmodels = gmodels;
% storage for draws
nvar = k;
mlog = [];
msave = [];
visits = zeros(ndraw,1);
vsave = zeros(ndraw,nvar);
% ====== initializations
% compute this stuff once to save time
in = ones(n,1);
% start with a random selection of variables
vtmp=zeros(nvar,1);
for v=1:nvar
vtmp(v)=bino_rnd(1,0.5,1,1);
end
vin=selif(seqa(1,1,nvar).*vtmp,vtmp)';
vout=delif(seqa(1,1,nvar)-seqa(1,1,nvar).*vtmp,vtmp)';
cnt = 0;
%<====================== start draws
t0 = clock;
hwait = waitbar(0,'OLS BMA : MCMC sampling ...');
for i=1:ndraw;
% choose new model
[vinew vonew] = sample(vin,vout);
for j=1:length(vinew);
vsave(i,vinew(1,j)) = 1.0;
end;
[j visits] = find_new(i,vsave,vinew,visits);
if i == 1 % first draw, compute logpost for initial model
lmarg = bmapost(y,x,vinew,nu,d0,g);
mlog = [mlog
lmarg];
msave = [msave
vsave(i,:)];
cnt = cnt+1; % count of unique models found
lmarg_old = lmarg;
end; % end of if i == 1
if visits(i,1) ~= 0 % we found a new model
cnt = cnt+1; % increase counter for new models
lmarg_new = bmapost(y,x,vinew,nu,d0,g);
mlog = [mlog
lmarg_new];
msave = [msave
vsave(i,:)];
else % we have a model that we have already computed the log-marginal for
% so, we could look it up, but it is faster to just compute it again
lmarg_new = bmapost(y,x,vinew,nu,d0,g);
end;
bf = model_odds(lmarg_new,lmarg_old);
if bf >=1;
flag = 1;
else
flag = bino_rnd(1,bf,1,1);
end;
if flag == 1 % change models
vin = vinew;
vout = vonew;
lmarg_old = lmarg_new;
end;
waitbar(i/ndraw);
end; % end of sampling loop
close(hwait);
time1 = abs(etime(clock,t0));
results.time1 = time1;
results.munique = cnt;
% write out results for 1000 best models
out = [mlog msave];
clear mlog;
clear msave;
save lmarginal.ols out -ascii;
psum = 0.0;
posts = [];
load lmarginal.ols;
mlog = lmarginal(:,1);
models = lmarginal(:,2:end);
adj = max(mlog);
madj = mlog - adj;
isum = exp(madj);
postprob = isum/sum(isum);
[probs_sort,pind] = sort(postprob);
results.mprob = probs_sort;
msort = models(pind,:);
out = [msort probs_sort];
[no,junk] = size(out);
% return all unique models sampled
results.allmodels = out;
results.vprob = sum(out)/no;
results.freq = sum(out);
% just pull out nmodels requested by the user
if (nmodels > no) % the user wants more models output than were found
nmodels = no; % we can only output what was found
else
% the user is okay
end;
outn = out(no-nmodels+1:no,:);
results.models = msort(no-nmodels+1:no,:);
results.ndraw = ndraw;
results.nu = nu;
results.d0 = d0;
time2 = abs(etime(clock,t1));
results.time2 = time2;
function [nu,d0,sige,g,gmodels] = ols_parse(prior,x)
% PURPOSE: parses input arguments for ols_gcbma models
% ---------------------------------------------------
% USAGE: [nu,d0,rho,sige,g,gmodels] =
% ols_parse(prior,x)
% where prior contains the structure variable with inputs,
% x is the matrix of explanatory variables input
% and the outputs are either user-inputs or default values
% ---------------------------------------------------
% set defaults
[n,k] = size(x);
g1 = (k*k);
g2 = n;
g = 1/max([g1 g2]); % Fernandez, Ley Steel default g-value
gmodels = 1000;
sige = 1.0;
nu = 0;
d0 = 0;
fields = fieldnames(prior);
nf = length(fields);
if nf > 0
for i=1:nf
if strcmp(fields{i},'nu')
nu = prior.nu;
elseif strcmp(fields{i},'d0')
d0 = prior.d0;
elseif strcmp(fields{i},'g')
g = prior.g;
elseif strcmp(fields{i},'nmodels')
gmodels = prior.nmodels;
end;
end;
else, % the user has input a blank info structure
% so we use the defaults
end;
function [j,visits] = find_new(i,vsave,vinew,visits)
% PURPOSE: determines if the variables in vinew represent a new model
% (called by bma_g)
%-------------------------------------------------------
% USAGE: [j,visits] = find_new(i,vsave,vinew,visits)
% where: i = size of vsave to search = draw #
% vsave = (i x nvar) matrix of indicators for models
% vinew = (1 x nvar) vector with current model indicators
% visits = (i x nvar) matrix for recording # of visits to a model
%-------------------------------------------------------
% RETURNS: j = index to an old model found
% visits = matrix recording visits to old models
%-------------------------------------------------------
% written by:
% James P. LeSage, Dept of Economics 7/2003
% University of Toledo
% 2801 W. Bancroft St,
% Toledo, OH 43606
% jlesage@spatial-econometrics.com
[junk nvar] = size(vsave);
vitmp = zeros(1,nvar);
for k=1:nvar
for j=1:length(vinew)
if vinew(1,j) == k
vitmp(1,k) = 1;
end;
end;
end;
nobs = i;
new = 0;
j = 1;
while (new == 0 & j <= nobs)
if vsave(j,:) == vitmp(1,:)
visits(j,1) = visits(j,1) + 1;
new = 1;
end;
j = j+1;
end;
j = j-1;
function lmout = bmapost(y,xall,vin,nu1,d1,g)
% PURPOSE: evaluates log marginal posterior of OLS bma model
% (OLS Bayesian model averaging)
%-----------------------------------------------------------
% USAGE: lpost = bmapost(y,xall,vin,nu1,d1,g)
% where: y = dependent variable vector (nobs x 1)
% xall = explanatory variables matrix (nobs x k)
% vin = a 1xk vector of columns to use from x, e.g. [1 3 5]
% nu1 = prior parameter on sigma
% d1 = prior parameter on sigma
% g = g prior hyperparameter
%-----------------------------------------------------------
% RETURNS: lpost = log marginal posterior, a scalar
% containing the log marginal
%-----------------------------------------------------------
% REFERENCES: Raftery and Madigan (1997) 'Bayesian model averaging
% for linear regression models', 92, pp. 179-191
% ----------------------------------------------------------
% written by:
% James P. LeSage, Dept of Economics 7/2003
% University of Toledo
% 2801 W. Bancroft St,
% Toledo, OH 43606
% jlesage@spatial-econometrics.com
[nobs,nv1] = size(xall);
nvar = length(vin);
v1 = nvar;
for i=1:nvar
if vin(1,i) >= nv1
v1 = i; % # of variables in x1
end;
end;
iota = ones(nobs,1);
xt = [iota xall(:,vin)];
[nobs,k] = size(xt);
nm1o2 = (nobs-1)/2;
no2 = nobs/2;
% now compute vectorized log-marginal likelihood
% to use in trapezoid numerical integration over rho
xpx = xt'*xt;
b0 = (xpx)\(xt'*y);
e0 = y - xt*b0;
epe0 = (1/(1+g))*(e0'*e0);
ybar = mean(y);
yhat = y - ybar*iota;
Qterm = (g/(1+g))*(yhat'*yhat);
logdetx = (nvar/2)*log(g/(1+g));
den = logdetx - nm1o2*log(nu1*d1 + epe0 + Qterm);
kterm = gammaln(nm1o2) -no2*log(pi);
lmout = kterm + den;
function odds = model_odds(lmarg1,lmarg2)
% PURPOSE: computes Bayes factor for 2 models using log-marginals as input
% ---------------------------------------------------
% USAGE: probs = model_odds(logmarginal1,logmargina2)
% where: logmarginal1,logmarginal2 = the log-marginal posterior for the
% two models
% ---------------------------------------------------
% RETURNS: a Bayes factor, a scalar
% ---------------------------------------------------
% written by:
% James P. LeSage, 6/2004
% Dept of Economics
% University of Toledo
% 2801 W. Bancroft St,
% Toledo, OH 43606
% jlesage@spatial-econometrics.com
lmarginal = [lmarg1 lmarg2];
% now scale log-marginals before exponentiating
adj = max(lmarginal);
madj = lmarginal - adj;
xx = exp(madj);
% compute posterior probabilities
psum = sum(xx);
probs = xx/psum;
odds = (probs(1)+realmin)/(probs(2)+realmin);
function [vinew,vonew] = sample(vin,vout)
% PURPOSE: function used by sar BMA models to sample variables for changing model size
% ----------------------------------------------------------
% USAGE: [vinew vonew] = sample(vin,vout)
% where: vin = a 1 x nvar1 vector of variable #'s for
% variables included in the model
% vout = a 1 x nvar2 vector of variable #'s for
% variables excluded from the model
% ----------------------------------------------------------
% RETURNS: vinew = a 1 x nvar1+1 or 1 x nvar1-1 vector of
% variable #'s in the new model
% vonew = a 1 x nvar2+1 or 1 x nvar2-1 vector of
% variable #'s excluded from the new model
% ----------------------------------------------------------
% written by:
% James P. LeSage, Dept of Economics
% University of Toledo
% 2801 W. Bancroft St,
% Toledo, OH 43606
% jlesage@spatial-econometrics.com
% last modified June, 2004
% find size of variables in/out of the model
nv1 = length(vout);
nv2 = length(vin);
nvar = nv1+nv2;
% decide on increase, move, decrease model size
coin = unif_rnd(1,0,1);
if coin < 0.33
if nv1 == 0
increase = 1;
else
increase = 0;
end
elseif coin > 0.66
if nv2 == 0
increase = 0;
else
increase = 1;
end
else
increase = 2;
end;
switch increase
case {0} % decrease the # variables in the model
choose = round(unif_rnd(1,1,length(vout)));
vinew = [vin vout(choose)];
vonew = zeros(1,length(vout)-1);
cnt = 1;
for i=1:length(vout);
if i~= choose
vonew(cnt) = vout(i);
cnt = cnt+1;
end;
end; % end of for loop
case {1} % increase the # variables in the model
choose = round(unif_rnd(1,1,length(vin)));
vinew = zeros(1,length(vin)-1);
cnt = 1;
for i=1:length(vin);
if i~= choose
vinew(cnt) = vin(i);
cnt = cnt+1;
end;
end; % end of for loop
vonew = zeros(1,length(vout)+1);
cnt = 1;
for i=1:length(vout);
vonew(cnt) = vout(cnt);
cnt = cnt+1;
end;
vonew(cnt) = vin(choose);
case {2} % change a variable that is in with one that is out
choose1 = round(unif_rnd(1,1,length(vout)));
choose2 = round(unif_rnd(1,1,length(vin)));
vinew = vin;
vonew = vout;
for i=1:length(vout);
if i == choose1
for j=1:length(vin);
if j == choose2
vinew(j) = vout(i);
vonew(i) = vin(j);
end;
end; % end of for j loop
end; % end of if i == choose1
end; % end of for i loop
otherwise
disp('error in sample function');
end; % end of switch
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -