DM_PREDICTIVE

This function returns the one-step-ahead posterior predictive probabilities under a Dirichlet-Multinomial model. For category counts updated into posterior hyperparameters, each category probability is the posterior mean.

Given posterior Dirichlet parameters \boldsymbol{\alpha}', the predictive probability for category i is:

p_i = \frac{\alpha_i'}{\sum_{j=1}^K \alpha_j'}

These probabilities sum to 1 and provide the expected category frequencies for the next draw.

Excel Usage

=DM_PREDICTIVE(alpha_posterior)
  • alpha_posterior (list[list], required): Posterior Dirichlet hyperparameters as a 2D range of positive values.

Returns (list[list]): Single-row 2D array of posterior predictive probabilities for each category.

Example 1: Balanced posterior produces balanced predictive probabilities

Inputs:

alpha_posterior
3 3 3

Excel formula:

=DM_PREDICTIVE({3,3,3})

Expected output:

Result
0.333333 0.333333 0.333333
Example 2: Skewed posterior emphasizes dominant category

Inputs:

alpha_posterior
12 2 1

Excel formula:

=DM_PREDICTIVE({12,2,1})

Expected output:

Result
0.8 0.133333 0.0666667
Example 3: Matrix-shaped posterior parameters are flattened correctly

Inputs:

alpha_posterior
4 1
2 3

Excel formula:

=DM_PREDICTIVE({4,1;2,3})

Expected output:

Result
0.4 0.1 0.2 0.3
Example 4: Weak posterior still returns normalized probabilities

Inputs:

alpha_posterior
0.6 0.9 1.2 0.8

Excel formula:

=DM_PREDICTIVE({0.6,0.9,1.2,0.8})

Expected output:

Result
0.171429 0.257143 0.342857 0.228571

Python Code

def dm_predictive(alpha_posterior):
    """
    Compute posterior predictive category probabilities from Dirichlet parameters.

    See: https://en.wikipedia.org/wiki/Dirichlet_distribution#Conjugate_to_categorical_or_multinomial

    This example function is provided as-is without any representation of accuracy.

    Args:
        alpha_posterior (list[list]): Posterior Dirichlet hyperparameters as a 2D range of positive values.

    Returns:
        list[list]: Single-row 2D array of posterior predictive probabilities for each category.
    """
    try:
        def to2d(v):
            return [[v]] if not isinstance(v, list) else v

        alpha_posterior = to2d(alpha_posterior)

        if not isinstance(alpha_posterior, list) or not all(isinstance(row, list) for row in alpha_posterior):
            return "Error: alpha_posterior must be a 2D list"

        alpha_flat = []
        for row in alpha_posterior:
            for val in row:
                try:
                    alpha_flat.append(float(val))
                except (TypeError, ValueError):
                    continue

        if len(alpha_flat) < 2:
            return "Error: alpha_posterior must contain at least two positive values"
        if any(a <= 0 for a in alpha_flat):
            return "Error: alpha_posterior values must be positive"

        total_alpha = float(sum(alpha_flat))
        probs = [a / total_alpha for a in alpha_flat]

        return [probs]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

Posterior Dirichlet hyperparameters as a 2D range of positive values.