API
Summary statistics
PosteriorStats.SummaryStats — Typestruct SummaryStatsA container for a column table of values computed by summarize.
This object implements the Tables and TableTraits column table interfaces. It has a custom show method.
SummaryStats behaves like an OrderedDict of columns, where the columns can be accessed using either Symbols or a 1-based integer index. However, this interface is not part of the public API and may change in the future. We recommend using it only interactively.
Constructor
SummaryStats(data; name="SummaryStats"[, labels])Construct a SummaryStats from tabular data.
data must implement the Tables interface. If it contains a column label, this will be used for the row labels or will be replaced with the labels if provided.
Keywords
name::AbstractString: The name of the collection of summary statistics, used as the table title in display.labels::AbstractVector: The names of the parameters indata, used as row labels in display. If not provided, then the columnlabelindatawill be used if it exists. Otherwise, the parameter names will be numeric indices.
PosteriorStats.summarize — Functionsummarize(data; kind=:all,kwargs...) -> SummaryStats
summarize(data, stats_funs...; kwargs...) -> SummaryStatsCompute summary statistics on each param in data.
Arguments
data: a 3D array of real samples with shape(draws, chains, params)or another object for which asummarizemethod is defined.stats_funs: a collection of functions that reduces a matrix with shape(draws, chains)to a scalar or a collection of scalars. Alternatively, an item instats_funsmay be aPairof the formname => funspecifying the name to be used for the statistic or of the form(name1, ...) => funwhen the function returns a collection. When the function returns a collection, the names in this latter format must be provided.
Keywords
var_names: a collection specifying the names of the parameters indata. If not provided, the names the indices of the parameter dimension indata.name::String: the name of the summary statistics, used as the table title in display.kind::Symbol: The named collection of summary statistics to be computed::all: Everything in:statsand:diagnostics:stats:mean,std,<ci>:diagnostics:ess_tail,ess_bulk,rhat,mcse_mean,mcse_std:all_median: Everything in:stats_medianand:diagnostics_median:stats_median:median,mad,<ci>:diagnostics_median:ess_median,ess_tail,rhat,mcse_median
kwargs: additional keyword arguments passed todefault_summary_stats, including:
See also SummaryStats, default_summary_stats
Extended Help
Examples
Compute all summary statistics (the default):
Display precision
When an estimator and its MCSE are both computed, the MCSE is used to determine the number of significant digits that will be displayed.
julia> using Statistics, StatsBase
julia> x = randn(1000, 4, 3) .+ reshape(0:10:20, 1, 1, :);
julia> summarize(x)
SummaryStats
mean std eti89 ess_tail ess_bulk rhat mcse_mean mcse_std
1 0.0003 0.99 -1.57 .. 1.59 3567 3663 1.00 0.016 0.012
2 10.02 0.99 8.47 .. 11.6 3841 3906 1.00 0.016 0.011
3 19.98 0.99 18.4 .. 21.6 3892 3749 1.00 0.016 0.012Compute just the default statistics with a 94% HDI, and provide the parameter names:
julia> var_names=[:x, :y, :z];
julia> summarize(x; var_names, kind=:stats, ci_fun=hdi, ci_prob=0.94)
SummaryStats
mean std hdi94
x 0.000275 0.989 -1.92 .. 1.78
y 10.0 0.988 8.17 .. 11.9
z 20.0 0.988 18.1 .. 21.9Compute Statistics.mean, Statistics.std and the Monte Carlo standard error (MCSE) of the mean estimate:
julia> summarize(x, mean, std, :mcse_mean => sem; name="Mean/Std")
Mean/Std
mean std mcse_mean
1 0.0003 0.989 0.016
2 10.02 0.988 0.016
3 19.98 0.988 0.016Compute multiple quantiles simultaneously:
julia> percs = (5, 25, 50, 75, 95);
julia> summarize(x, Symbol.(:q, percs) => Base.Fix2(quantile, percs ./ 100))
SummaryStats
q5 q25 q50 q75 q95
1 -1.61 -0.668 0.00447 0.653 1.64
2 8.41 9.34 10.0 10.7 11.6
3 18.4 19.3 20.0 20.6 21.6Extending summarize to custom types
To support computing summary statistics from a custom object MyType, overload the method summarize(::MyType, stats_funs...; kwargs...), which should ultimately call summarize(::AbstractArray{<:Union{Real,Missing},3}, stats_funs...; other_kwargs...), where other_kwargs are the keyword arguments passed to summarize.
PosteriorStats.default_summary_stats — Functiondefault_summary_stats(kind::Symbol=:all; kwargs...)Return a collection of stats functions based on the named preset kind.
These functions are then passed to summarize.
Arguments
kind::Symbol: The named collection of summary statistics to be computed::all: Everything in:statsand:diagnostics:stats:mean,std,<ci>:diagnostics:ess_tail,ess_bulk,rhat,mcse_mean,mcse_std:all_median: Everything in:stats_medianand:diagnostics_median:stats_median:median,mad,<ci>:diagnostics_median:ess_median,ess_tail,rhat,mcse_median
Keywords
Credible intervals
PosteriorStats.hdi — Functionhdi(samples::AbstractVecOrMat{<:Real}; [prob, sorted, method]) -> IntervalSets.ClosedInterval
hdi(samples::AbstractArray{<:Real}; [prob, sorted, method]) -> Array{<:IntervalSets.ClosedInterval}Estimate the highest density interval (HDI) of samples for the probability prob.
The HDI is the minimum width Bayesian credible interval (BCI). That is, it is the smallest possible interval containing (100*prob)% of the probability mass.[1] This implementation uses the algorithm of Chen and Shao [2].
Arguments
samples: an array of shape(draws[, chains[, params...]]). If multiple parameters are present, a marginal HDI is computed for each.
Keywords
prob: the probability mass to be contained in the HDI. Default is0.89.sorted=false: iftrue, the input samples are assumed to be sorted.method::Symbol: the method used to estimate the HDI. Available options are::unimodal: Assumes a unimodal distribution (default). Bounds are entries insamples.:multimodal: Fits a density estimator tosamplesand finds the HDI of the estimated density. For continuous data, the density estimator is a kernel density estimate (KDE) computed usingkde_reflected. For discrete data, a histogram with bin width 1 is used.:multimodal_sample: Like:multimodal, but uses the density estimator to find the entries insampleswith the highest density and computes the HDI from those points. This can correct for inaccuracies in the density estimator.
is_discrete::Union{Bool,Nothing}=nothing: Specify if the data is discrete (integer-valued). Ifnothing, it's automatically determined.kwargs: For continuous data and multimodalmethods, remaining keywords are forwarded tokde_reflected.
Returns
intervals: Ifsamplesis a vector or matrix, then a singleIntervalSets.ClosedIntervalis returned for:unimodalmethod, or a vector ofClosedIntervalfor multimodal methods. For higher dimensional inputs, an array with the shape(params...,)is returned, containing marginal HDIs for each parameter.
Any default value of prob is arbitrary. The default value of prob=0.89 instead of a more common default like prob=0.95 is chosen to remind the user of this arbitrariness.
Examples
Here we calculate the 83% HDI for a normal random variable:
julia> x = randn(2_000);
julia> hdi(x; prob=0.83)
-1.3826605224220527 .. 1.259817149822839We can also calculate the HDI for a 3-dimensional array of samples:
julia> x = randn(1_000, 1, 1) .+ reshape(0:5:10, 1, 1, :);
julia> hdi(x)
3-element Vector{IntervalSets.ClosedInterval{Float64}}:
-1.5427053100097161 .. 1.5359155759683685
3.4572946899902837 .. 6.535915575968368
8.457294689990285 .. 11.53591557596837For multimodal distributions, you can use the :multimodal method:
julia> x = vcat(randn(1000), randn(1000) .+ 5);
julia> hdi(x; method=:multimodal)
2-element Vector{IntervalSets.ClosedInterval{Float64}}:
-1.684083621714902 .. 1.6431153298071857
3.4032753058196996 .. 6.724956514470275References
PosteriorStats.hdi! — Functionhdi!(samples::AbstractArray{<:Real}; [prob, sorted])A version of hdi that partially sorts samples in-place while computing the HDI.
PosteriorStats.eti — Functioneti(samples::AbstractVecOrMat{<:Real}; [prob, kwargs...]) -> IntervalSets.ClosedInterval
eti(samples::AbstractArray{<:Real}; [prob, kwargs...]) -> Array{<:IntervalSets.ClosedInterval}Estimate the equal-tailed interval (ETI) of samples for the probability prob.
The ETI of a given probability is the credible interval wih the property that the probability of being below the interval is equal to the probability of being above it. That is, it is defined by the (1-prob)/2 and 1 - (1-prob)/2quantiles of the samples.
Arguments
samples: an array of shape(draws[, chains[, params...]]). If multiple parameters are present
Keywords
prob: the probability mass to be contained in the ETI. Default is0.89.kwargs: remaining keywords are passed toStatistics.quantile.
Returns
intervals: Ifsamplesis a vector or matrix, then a singleIntervalSets.ClosedIntervalis returned. Otherwise, an array with the shape(params...,), is returned, containing a marginal ETI for each parameter.
Any default value of prob is arbitrary. The default value of prob=0.89 instead of a more common default like prob=0.95 is chosen to reminder the user of this arbitrariness.
Examples
Here we calculate the 83% ETI for a normal random variable:
julia> x = randn(2_000);
julia> eti(x; prob=0.83)
-1.3740585250299766 .. 1.2860771129421198We can also calculate the ETI for a 3-dimensional array of samples:
julia> x = randn(1_000, 1, 1) .+ reshape(0:5:10, 1, 1, :);
julia> eti(x)
3-element Vector{IntervalSets.ClosedInterval{Float64}}:
-1.610045656629508 .. 1.6318466811022705
3.389954343370492 .. 6.63184668110227
8.38995434337049 .. 11.631846681102271PosteriorStats.eti! — Functioneti!(samples::AbstractArray{<:Real}; [prob, kwargs...])A version of eti that partially sorts samples in-place while computing the ETI.
LOO
PosteriorStats.AbstractELPDResult — Typeabstract type AbstractELPDResultAn abstract type representing the result of an ELPD computation.
Every subtype stores estimates of both the expected log predictive density (elpd) and the effective number of parameters p, as well as standard errors and pointwise estimates of each, from which other relevant estimates can be computed.
Subtypes implement the following functions:
PosteriorStats.PSISLOOResult — TypeResults of Pareto-smoothed importance sampling leave-one-out cross-validation (PSIS-LOO).
See also: loo, AbstractELPDResult
estimates: Estimates of the expected log pointwise predictive density (ELPD) and effective number of parameters (p)pointwise: Pointwise estimatespsis_result: APSIS.PSISResultwith Pareto-smoothed importance sampling (PSIS) results
PosteriorStats.elpd_estimates — Functionelpd_estimates(result::AbstractELPDResult; pointwise=false) -> (; elpd, se_elpd, lpd)Return the (E)LPD estimates from the result.
PosteriorStats.information_criterion — Functioninformation_criterion(elpd, scale::Symbol)Compute the information criterion for the given scale from the elpd estimate.
scale must be one of (:deviance, :log, :negative_log).
See also: loo
information_criterion(result::AbstractELPDResult, scale::Symbol; pointwise=false)Compute information criterion for the given scale from the existing ELPD result.
scale must be one of (:deviance, :log, :negative_log).
If pointwise=true, then pointwise estimates are returned.
PosteriorStats.loo — Functionloo(log_likelihood; reff=nothing, kwargs...) -> PSISLOOResult{<:NamedTuple,<:NamedTuple}Compute the Pareto-smoothed importance sampling leave-one-out cross-validation (PSIS-LOO). [3, 4]
log_likelihood must be an array of log-likelihood values with shape (chains, draws[, params...]).
Keywords
reff::Union{Real,AbstractArray{<:Real}}: The relative effective sample size(s) of the likelihood values. If an array, it must have the same data dimensions as the corresponding log-likelihood variable. If not provided, then this is estimated usingMCMCDiagnosticTools.ess.kwargs: Remaining keywords are forwarded toPSIS.psis.
See also: PSISLOOResult
Examples
Manually compute $R_\mathrm{eff}$ and calculate PSIS-LOO of a model:
julia> using ArviZExampleData, LogExpFunctions, MCMCDiagnosticTools
julia> idata = load_example_data("centered_eight");
julia> log_like = PermutedDimsArray(idata.log_likelihood.obs, (:draw, :chain, :school));
julia> reff = ess(softmax(log_like; dims=(1, 2)); kind=:basic, split_chains=1, relative=true);
julia> loo(log_like; reff)
PSISLOOResult with estimates
elpd se_elpd p se_p
-31 1.4 0.9 0.33
and PSISResult with 500 draws, 4 chains, and 8 parameters
Pareto shape (k) diagnostic values:
Count Min. ESS
(-Inf, 0.5] good 4 (50.0%) 270
(0.5, 0.7] okay 4 (50.0%) 307References
Model comparison
PosteriorStats.ModelComparisonResult — TypeModelComparisonResultResult of model comparison using ELPD.
This struct implements the Tables and TableTraits interfaces.
Each field returns a collection of the corresponding entry for each model:
name: Names of the models, if provided.rank: Ranks of the models (ordered by decreasing ELPD)elpd_diff: ELPD of a model subtracted from the largest ELPD of any modelse_elpd_diff: Standard error of the ELPD differenceweight: Model weights computed withweights_methodelpd_result:AbstactELPDResults for each model, which can be used to access useful stats like ELPD estimates, pointwise estimates, and Pareto shape values for PSIS-LOOweights_method: Method used to compute model weights withmodel_weights
PosteriorStats.compare — Functioncompare(models; kwargs...) -> ModelComparisonResultCompare models based on their expected log pointwise predictive density (ELPD).
The ELPD is estimated by Pareto smoothed importance sampling leave-one-out cross-validation (PSIS-LOO), the same method used by loo. For more theory, see Spiegelhalter et al. [5].
Arguments
models: aTuple,NamedTuple, orAbstractVectorwhose values are eitherAbstractELPDResultentries or any argument toloo.
Keywords
weights_method::AbstractModelWeightsMethod=Stacking(): the method to be used to weight the models. Seemodel_weightsfor detailssort::Bool=true: Whether to sort models by decreasing ELPD.
Returns
ModelComparisonResult: A container for the model comparison results. The fields contain a similar collection tomodels.
Examples
Compare the centered and non centered models of the eight school problem:
julia> using ArviZExampleData
julia> models = (
centered=load_example_data("centered_eight"),
non_centered=load_example_data("non_centered_eight"),
);
julia> mc = compare(models)
┌ Warning: 1 parameters had Pareto shape values 0.7 < k ≤ 1. Resulting importance sampling estimates are likely to be unstable.
└ @ PSIS ~/.julia/packages/PSIS/...
ModelComparisonResult with Stacking weights
rank elpd se_elpd elpd_diff se_elpd_diff weight p se_p
non_centered 1 -31 1.5 0 0.0 1.0 0.9 0.32
centered 2 -31 1.4 0.03 0.061 0.0 0.9 0.33
julia> mc.weight |> pairs
pairs(::NamedTuple) with 2 entries:
:non_centered => 1.0
:centered => 3.50546e-31Compare the same models from pre-computed PSIS-LOO results and computing BootstrappedPseudoBMA weights:
julia> elpd_results = mc.elpd_result;
julia> compare(elpd_results; weights_method=BootstrappedPseudoBMA())
ModelComparisonResult with BootstrappedPseudoBMA weights
rank elpd se_elpd elpd_diff se_elpd_diff weight p se_p
non_centered 1 -31 1.5 0 0.0 0.51 0.9 0.32
centered 2 -31 1.4 0.03 0.061 0.49 0.9 0.33References
- [5] Spiegelhalter et al. J. R. Stat. Soc. B 64 (2002)
PosteriorStats.model_weights — Functionmodel_weights(elpd_results; method=Stacking())
model_weights(method::AbstractModelWeightsMethod, elpd_results)Compute weights for each model in elpd_results using method.
elpd_results is a Tuple, NamedTuple, or AbstractVector with AbstractELPDResult entries. The weights are returned in the same type of collection.
Stacking is the recommended approach, as it performs well even when the true data generating process is not included among the candidate models. See Yao et al. [6] for details.
See also: AbstractModelWeightsMethod, compare
Examples
Compute Stacking weights for two models:
julia> using ArviZExampleData
julia> models = (
centered=load_example_data("centered_eight"),
non_centered=load_example_data("non_centered_eight"),
);
julia> elpd_results = map(models) do idata
log_like = PermutedDimsArray(idata.log_likelihood.obs, (2, 3, 1))
return loo(log_like)
end;
┌ Warning: 1 parameters had Pareto shape values 0.7 < k ≤ 1. Resulting importance sampling estimates are likely to be unstable.
└ @ PSIS ~/.julia/packages/PSIS/...
julia> model_weights(elpd_results; method=Stacking()) |> pairs
pairs(::NamedTuple) with 2 entries:
:centered => 3.50546e-31
:non_centered => 1.0Now we compute BootstrappedPseudoBMA weights for the same models:
julia> model_weights(elpd_results; method=BootstrappedPseudoBMA()) |> pairs
pairs(::NamedTuple) with 2 entries:
:centered => 0.492513
:non_centered => 0.507487References
- [6] Yao et al. Bayesian Analysis 13, 3 (2018)
The following model weighting methods are available
PosteriorStats.AbstractModelWeightsMethod — Typeabstract type AbstractModelWeightsMethodAn abstract type representing methods for computing model weights.
Subtypes implement model_weights(method, elpd_results).
PosteriorStats.BootstrappedPseudoBMA — Typestruct BootstrappedPseudoBMA{R<:Random.AbstractRNG, T<:Real} <: AbstractModelWeightsMethodModel weighting method using pseudo Bayesian Model Averaging using Akaike-type weighting with the Bayesian bootstrap (pseudo-BMA+)[6].
The Bayesian bootstrap stabilizes the model weights.
BootstrappedPseudoBMA(; rng=Random.default_rng(), samples=1_000, alpha=1)
BootstrappedPseudoBMA(rng, samples, alpha)Construct the method.
rng::Random.AbstractRNG: The random number generator to use for the Bayesian bootstrapsamples::Int64: The number of samples to draw for bootstrappingalpha::Real: The shape parameter in the Dirichlet distribution used for the Bayesian bootstrap. The default (1) corresponds to a uniform distribution on the simplex.
See also: Stacking
References
- [6] Yao et al. Bayesian Analysis 13, 3 (2018)
PosteriorStats.PseudoBMA — Typestruct PseudoBMA <: AbstractModelWeightsMethodModel weighting method using pseudo Bayesian Model Averaging (pseudo-BMA) and Akaike-type weighting.
PseudoBMA(; regularize=false)
PseudoBMA(regularize)Construct the method with optional regularization of the weights using the standard error of the ELPD estimate.
This approach is not recommended, as it produces unstable weight estimates. It is recommended to instead use BootstrappedPseudoBMA to stabilize the weights or Stacking. For details, see Yao et al. [6].
See also: Stacking
References
- [6] Yao et al. Bayesian Analysis 13, 3 (2018)
PosteriorStats.Stacking — Typestruct Stacking{O<:Optim.AbstractOptimizer} <: AbstractModelWeightsMethodModel weighting using stacking of predictive distributions[6].
Stacking(; optimizer=Optim.LBFGS(), options=Optim.Options()
Stacking(optimizer[, options])Construct the method, optionally customizing the optimization.
optimizer::Optim.AbstractOptimizer: The optimizer to use for the optimization of the weights. The optimizer must support projected gradient optimization via amanifoldfield.options::Optim.Options: The Optim options to use for the optimization of the weights.
See also: BootstrappedPseudoBMA
References
- [6] Yao et al. Bayesian Analysis 13, 3 (2018)
Predictive checks
PosteriorStats.loo_pit — Functionloo_pit(y, y_pred, log_weights) -> Union{Real,AbstractArray}Compute leave-one-out probability integral transform (LOO-PIT) checks.
Arguments
y: array of observations with shape(params...,)y_pred: array of posterior predictive samples with shape(draws, chains, params...).log_weights: array of normalized log LOO importance weights with shape(draws, chains, params...).
Returns
pitvals: LOO-PIT values with same size asy. Ifyis a scalar, thenpitvalsis a scalar.
LOO-PIT is a marginal posterior predictive check. If $y_{-i}$ is the array $y$ of observations with the $i$th observation left out, and $y_i^*$ is a posterior prediction of the $i$th observation, then the LOO-PIT value for the $i$th observation is defined as
\[P(y_i^* \le y_i \mid y_{-i}) = \int_{-\infty}^{y_i} p(y_i^* \mid y_{-i}) \mathrm{d} y_i^*\]
The LOO posterior predictions and the corresponding observations should have similar distributions, so if conditional predictive distributions are well-calibrated, then for continuous data, all LOO-PIT values should be approximately uniformly distributed on $[0, 1]$. [7]
For discrete data, the LOO-PIT values will typically not be uniformly distributed on $[0, 1]$, and this function is not recommended.
Examples
Calculate LOO-PIT values using as test quantity the observed values themselves.
julia> using ArviZExampleData
julia> idata = load_example_data("centered_eight");
julia> y = idata.observed_data.obs;
julia> y_pred = PermutedDimsArray(idata.posterior_predictive.obs, (:draw, :chain, :school));
julia> log_like = PermutedDimsArray(idata.log_likelihood.obs, (:draw, :chain, :school));
julia> log_weights = loo(log_like).psis_result.log_weights;
julia> loo_pit(y, y_pred, log_weights)
┌ 8-element DimArray{Float64, 1} ┐
├────────────────────────────────┴─────────────────────────────── dims ┐
↓ school Categorical{String} ["Choate", …, "Mt. Hermon"] Unordered
└──────────────────────────────────────────────────────────────────────┘
"Choate" 0.942759
"Deerfield" 0.641057
"Phillips Andover" 0.32729
"Phillips Exeter" 0.581451
"Hotchkiss" 0.288523
"Lawrenceville" 0.393741
"St. Paul's" 0.886175
"Mt. Hermon" 0.638821Calculate LOO-PIT values using as test quantity the square of the difference between each observation and mu.
julia> using Statistics
julia> mu = idata.posterior.mu;
julia> T = y .- median(mu);
julia> T_pred = y_pred .- mu;
julia> loo_pit(T .^ 2, T_pred .^ 2, log_weights)
┌ 8-element DimArray{Float64, 1} ┐
├────────────────────────────────┴─────────────────────────────── dims ┐
↓ school Categorical{String} ["Choate", …, "Mt. Hermon"] Unordered
└──────────────────────────────────────────────────────────────────────┘
"Choate" 0.868148
"Deerfield" 0.27421
"Phillips Andover" 0.321719
"Phillips Exeter" 0.193169
"Hotchkiss" 0.370422
"Lawrenceville" 0.195601
"St. Paul's" 0.817408
"Mt. Hermon" 0.326795References
- [7] Gabry et al. J. R. Stat. Soc. Ser. A Stat. Soc. 182 (2019).
PosteriorStats.r2_score — Functionr2_score(y_true::AbstractVector, y_pred::AbstractArray; kwargs...) -> (; r2, r2_std)$R²$ for linear Bayesian regression models.[8]
The $R²$, or coefficient of determination, is defined as the proportion of variance in the data that is explained by the model. For each draw, it is computed as the variance of the predicted values divided by the variance of the predicted values plus the variance of the residuals.
The distribution of the $R²$ scores can then be summarized using a point estimate and a credible interval (CI).
Arguments
y_true: Observed data of lengthnoutputsy_pred: Predicted data with size(ndraws[, nchains], noutputs)
Keywords
summary::Bool=true: Whether to return a summary or an array of $R²$ scores. The summary is a named tuple with the point estimate:r2and the credible interval:<ci_fun>.point_estimate=Statistics.mean: The function used to compute the point estimate of the $R²$ scores ifsummaryistrue. Supported options are:ci_fun=eti: The function used to compute the credible interval ifsummaryistrue. Supported options areetiandhdi.ci_prob=0.89: The probability mass to be contained in the credible interval.
Examples
julia> using ArviZExampleData
julia> idata = load_example_data("regression1d");
julia> y_true = idata.observed_data.y;
julia> y_pred = PermutedDimsArray(idata.posterior_predictive.y, (:draw, :chain, :y_dim_0));
julia> r2_score(y_true, y_pred)
(r2 = 0.683196996216511, eti = 0.6230680117869596 .. 0.7384123771046265)References
- [8] Gelman et al, The Am. Stat., 73(3) (2019)
Utilities
PosteriorStats.kde_reflected — Functionkde_reflected(data::AbstractVector{<:Real}; bounds=extrema(data), kwargs...)Compute the boundary-corrected kernel density estimate (KDE) of data using reflection.
For $x \in (l, u)$, the reflected KDE has the density
\[\hat{f}_R(x) = \hat{f}(x) + \hat{f}(2l - x) + \hat{f}(2u - x),\]
where $\hat{f}$ is the usual KDE of data. This is equivalent to augmenting the original data with 2 additional copies of the data reflected around each bound, computing the usual KDE, trimming the KDE to the bounds, and renormalizing.
Any non-finite bounds are ignored. Remaining kwargs are passed to KernelDensity.kde. The default bandwidth is estimated using the Improved Sheather-Jones (ISJ) method [9].
References
- [9] Botev et al. Ann. Stat., 38: 5 (2010)
PosteriorStats.pointwise_loglikelihoods — Functionpointwise_loglikelihoodsCompute pointwise conditional log-likelihoods for ELPD-based model comparison/validation.
Given model parameters $\theta$ and observations $y$, the pointwise conditional log-likelihood of $y_i$ given $y_{-i}$ (the elements of $y$ excluding $y_i$) and $\theta$ is defined as
\[\log p(y_i \mid y_{-i}, \theta)\]
This method is a utility function that dependant packages can override to provide pointwise conditional log-likelihoods for their own models/distributions.
See also: loo
PosteriorStats.pointwise_loglikelihoods — Methodpointwise_loglikelihoods(y, dists)Compute pointwise conditional log-likelihoods of y for non-factorized distributions.
A non-factorized observation model $p(y \mid \theta)$, where $y$ is an array of observations and $\theta$ are model parameters, can be factorized as $p(y_i \mid y_{-i}, \theta) p(y_{-i} \mid \theta)$. However, completely factorizing into individual likelihood terms can be tedious, expensive, and poorly supported by a given PPL. This utility function computes $\log p(y_i \mid y_{-i}, \theta)$ terms for all $i$; the resulting pointwise conditional log-likelihoods can be used e.g. in loo.
Arguments
y: array of observations with shape(params...,)dists: array of shape(draws[, chains])containing parametrizedDistributions.Distributions representing a non-factorized observation model, one for each posterior draw. The following distributions are currently supported:Distributions.MvNormal[10]Distributions.MvNormalCanonDistributions.MatrixNormalDistributions.MvLogNormalDistributions.GenericMvTDist[10, but uses a more efficient implementation]
Returns
log_like: log-likelihood values with shape(draws[, chains], params...)
References