Installation
Using CAMEL
Tutorials
|
Sampling with CAMELOn this page... (hide) 1. Installation
2. Getting the HessianThe main idea behing CAMEL is to have a framework that developps both the frequentist and Bayesian approaches for comparison. A known difficulty is to get a (gaussian) proposal matrix that is "not too bad". This is simple if someone already did the work and provides you the already estimation covariance matrix and you just want to repoduce results. But when you add some (or several new parameters) the proposal can (and genrally does) strongly change. CAMEL introduced an "adaptative" algorithm in order to build the covariance on the fly , ie. directly from the samples you generated. This requires having an initial guess. We take advantage from the minimization capabilities of CAMEL to fisrt perform a global minimization which not only gives you the "best fit" but also some estimate of the Hessian matrix (the second derivatives at the minimum). It is often of poor quality (and does NOT represent the "errors" on the parameters) but generally of sufficient quality to feed CAMEL's adaptative algorithm. We will work with (a fake) likelihood based on Pk measured at different redshift and try to determine 4 parameter of the underlying Lambda-CDM parameters. So take this parameter file and have a look at it. Be sure you understand each line (more in session 1. Then run the minimization with $EXECDIR/Minimize lcdm.txt bestfit hessian (the two output arguments are the best-fit/hessian outputs written in external files)
where EXECDIR is here to indicate where the executable lies, ie starting from
Check that the minimization gives something "reasonnable" (how?) 3. Adaptive Metropolis (AM)So let us see how to run the AM algorithm in CAMEL the lazy way (flat priors actually taken from the bounds in your parFile).
algo=ada length=1000 bunchSize=100 It means we use the AM algorithm, to generate 1000 samples(vectors) that will be written into the file every 100 steps. Then we need some rough estimate of the proposal matrix: we use the Hessian determined in the global fit so add proposal_cov=hessian Finally AM has a number of parameters to tune the run. try: t0=100 ts=0 do_move=true scale=1 There are actually 2 things the algorithm is adapting from the data
"do_move" allows to jump randomly the first sample, so that each run will start with a different value. Note that the seed of the random number generator changes for each run. Then run $EXECDIR/mcmc lcdm_mc.par chain1.txt This should last about 3mins. If you are ensure that everything is fine, you can check regularly the number of lines written in chain1.txt (which should increase with time by chuncks of 100) wc -l chain1.txt 4. Checking for convergenceIn order to sample correctly the distribution, the samples distribution must be in a stationary state known as correct "mixing". Then its distribution "converges" to the right function (posterior/likelihood here). This requires running the algorithm sometimes for a long time (steps) before it forgets its origin and go into a region of the parameter space where the proposal matrix is well adapted. There is no way to be 100% sure a chain is mixing correctly, but you may often clearly see when it did not! Here are various ways: 4.1 Trace plotsThe very first thing to do once you have your chain (file) is simply to plot each variable to see how it evolved (parameters+chi2 see 1st line header for the names) looking for the moment were the chain is in a somewhat "stable" regime (stationarity) In python read the (text) file, for instance with Have all variables converged? In your view, when do the distributions begin to be stationary (if anywhere)? With these plots (pedantically called "trace plots") you will identify 99% of the problems (not saying that the remaining 1% is OK) 4.2 Acceptance rateHave a look at the chain1.txt values. What do you notice?
The acceptance rate is a mean value of times the jump was accepted (so value changed in the file).
A rule of thumb is that it should be close to 1/4 (meaning samples are repeated 3/4 of the times). It was established only for Gaussian distribution but in practice this rule also works well for other distributions.
CAMEL computes a this running mean (every 100 steps) and writes it in the file (you should have) named Finally if you wish to see how the scale factor was adapted the file 5. Multiple chainsOnce you are happy with your chain a finer insight can be gained running several chains and comparing their characteristics, so construct 4 independent chains $EXECDIR/mcmc lcdm_mc.par chain2.txt $EXECDIR/mcmc lcdm_mc.par chain3.txt $EXECDIR/mcmc lcdm_mc.par chain4.txt They should be different each time since you start from a different starting point (do_move=true) and the seed of the random number generator is (implicitely) different in each run. We will now use some features of the
So in python: Compare how the chains evolved for in each run : from pylab import * import camel #read the chains in a single list chains=camel.extract_chains('chain',4) #read the variables name from the 1st line of "chain1" with open('chain1.txt', 'r') as f: names= f.readline().split() #overplot the 4 chains for each variable ivar=0 [plot(c[ivar]) for c in chains] title(names[ivar]) #look at the other variables too 5.1 The Gelman-Rubin testNow we can go on with a deeper convergence test. Its idea is, for each parameter, to compare the variance of each variables within each chain to the variance among the chains. This allows to build the "R" statistics and a good rule of thumb to see where the variable converged is to look for:
(or 0.01 if you are more demanding) Fortunately camel.py does already everything for you: #Compute Gelman-Rubin statistic for each parameter it,R = camel.GelmanRubin(chains,gap=10,length_min =0) figure() plot(it,R-1.) legend(names[1:]) axhline( 0.03, color='k', ls='--')
6. Building posteriors6.1 getting mean values and intervalsNow we are more confident that the chains sample correctly the likelihood around its maximum after some number of steps (lets say N0), we construct one single chain with our "best samples" by concatenating the last part of each chain: #define your N0 value N0= #construct a single chain from the last samples (using samples above N0 steps) chain=camel.mergeMC("chain",num=(1,2,3,4),burnin=N0) #names were defined previously - you can still use the following convenience names=camel.MCparnames("chain") #plot the histograms + basic statitics # the first variable is "chi2", we don't want it for ivar in range(1,5): subplot(2,2,ivar) parname=names[ivar] hist(chain[parname]) title(parname) print("%15s " % parname, "\t %f \t %f \t %f" % camel.getci( np.percentile(chain[parname], [16,50,84]))) tight_layout() Now show God your result and ask Him for what She/He put in the simulation. 6.2 Triangle plotOne can produce the famous "triangle plot" which not only shows the (smoothed) 1D histograms but 2D's too. We will use the pip install --user getdist Now starting again from "chain" as the mergedMC values and names as the column names: import camel from getdist import plots, MCSamples #see previously how chain/par are defined #build samples without chi2 mcmc = [chain[par] for par in names[1:]] #the follwing translates to some nice fonts for param names labels=[camel.parname.setdefault(n,n).replace('$','') for n in names[1:]] #getDist functions: samples=[MCSamples( samples=mcmc, names=names[1:],labels=labels)] g = plots.getPlotter() # creates the "plotting" object g.triangle_plot(samples,names[1:],contour_colors='blue',filled=True) 7. Closing the loop
construct the empirical covariance and compare it to the Hessian. Now you are a real expert, time to have a look at this more complete tutorial |