BETANBINOM
Overview
The BETANBINOM function computes values for the beta-negative binomial distribution, a discrete probability distribution that models the number of failures before achieving a specified number of successes in a sequence of independent Bernoulli trials, where the probability of success itself varies according to a beta distribution. This makes it a compound probability distribution, combining the negative binomial distribution with a beta-distributed success probability.
The distribution is particularly useful when modeling overdispersed count data where the variance exceeds what the standard negative binomial distribution would predict. It finds applications in Bayesian statistics, reliability analysis, and modeling heterogeneous populations. The beta-negative binomial is also known as the inverse Markov-Pólya distribution or the generalized Waring distribution.
The probability mass function (PMF) is defined as:
f(k) = \binom{n+k-1}{k} \frac{B(a+n, b+k)}{B(a, b)}
where k \geq 0 is the number of failures, n \geq 0 is the number of successes, a > 0 and b > 0 are the shape parameters of the beta distribution, and B(a, b) is the beta function.
This implementation uses SciPy’s betanbinom from the scipy.stats module, which provides methods for computing the probability mass function (PMF), cumulative distribution function (CDF), survival function (SF), inverse CDF (ICDF/PPF), inverse survival function (ISF), and summary statistics including mean, variance, standard deviation, and median. The optional loc parameter shifts the distribution along the x-axis.
For more background on the mathematical properties of this distribution, see the Wikipedia article on the beta-negative binomial distribution.
This example function is provided as-is without any representation of accuracy.
Excel Usage
=BETANBINOM(k, n, a, b, betanbinom_mode, loc)
k(list[list], required): Value at which to evaluate (or probability for ICDF/ISF modes).n(int, required): Number of successes (n >= 0).a(float, required): Alpha parameter of the beta distribution (a > 0).b(float, required): Beta parameter of the beta distribution (b > 0).betanbinom_mode(str, optional, default: “pmf”): Output type to compute.loc(float, optional, default: 0): Location parameter to shift the distribution.
Returns (float): Distribution result (float), or error message string.
Examples
Example 1: PMF at k=2
Inputs:
| k | n | a | b | betanbinom_mode |
|---|---|---|---|---|
| 2 | 5 | 9.3 | 1 | pmf |
Excel formula:
=BETANBINOM(2, 5, 9.3, 1, "pmf")
Expected output:
| Result |
|---|
| 0.0782 |
Example 2: CDF at k=2
Inputs:
| k | n | a | b | betanbinom_mode |
|---|---|---|---|---|
| 2 | 5 | 9.3 | 1 | cdf |
Excel formula:
=BETANBINOM(2, 5, 9.3, 1, "cdf")
Expected output:
| Result |
|---|
| 0.9411 |
Example 3: Survival function at k=2
Inputs:
| k | n | a | b | betanbinom_mode | loc |
|---|---|---|---|---|---|
| 2 | 5 | 9.3 | 1 | sf | 0 |
Excel formula:
=BETANBINOM(2, 5, 9.3, 1, "sf", 0)
Expected output:
| Result |
|---|
| 0.0589 |
Example 4: Inverse CDF for probability 0.5
Inputs:
| k | n | a | b | betanbinom_mode |
|---|---|---|---|---|
| 0.5 | 5 | 9.3 | 1 | icdf |
Excel formula:
=BETANBINOM(0.5, 5, 9.3, 1, "icdf")
Expected output:
| Result |
|---|
| 0 |
Example 5: PMF for 2D array
Inputs:
| k | n | a | b | betanbinom_mode | |
|---|---|---|---|---|---|
| 1 | 2 | 5 | 9.3 | 1 | pmf |
| 3 | 4 |
Excel formula:
=BETANBINOM({1,2;3,4}, 5, 9.3, 1, "pmf")
Expected output:
| Result | |
|---|---|
| 0.2125 | 0.0782 |
| 0.0317 | 0.0138 |
Example 6: Mean of distribution
Inputs:
| k | n | a | b | betanbinom_mode |
|---|---|---|---|---|
| 0 | 5 | 9.3 | 1 | mean |
Excel formula:
=BETANBINOM(0, 5, 9.3, 1, "mean")
Expected output:
0.6024
Python Code
from scipy.stats import betanbinom as scipy_betanbinom
def betanbinom(k, n, a, b, betanbinom_mode='pmf', loc=0):
"""
Compute Beta-negative-binomial distribution values: PMF, CDF, SF, ICDF, ISF, mean, variance, std, or median.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.betanbinom.html
This example function is provided as-is without any representation of accuracy.
Args:
k (list[list]): Value at which to evaluate (or probability for ICDF/ISF modes).
n (int): Number of successes (n >= 0).
a (float): Alpha parameter of the beta distribution (a > 0).
b (float): Beta parameter of the beta distribution (b > 0).
betanbinom_mode (str, optional): Output type to compute. Valid options: PMF, CDF, SF, ICDF, ISF, Mean, Var, Std, Median. Default is 'pmf'.
loc (float, optional): Location parameter to shift the distribution. Default is 0.
Returns:
float: Distribution result (float), or error message string.
"""
# Validate n, a, b
try:
n_val = int(n)
a_val = float(a)
b_val = float(b)
if not (n_val >= 0 and a_val > 0 and b_val > 0):
return "Invalid input: n must be >= 0, a and b must be > 0."
except Exception:
return "Invalid input: n must be integer, a and b must be numbers."
# Validate loc
try:
loc_val = float(loc)
except Exception:
return "Invalid input: loc must be a number."
# Validate betanbinom_mode
valid_modes = {"pmf", "cdf", "sf", "icdf", "isf", "mean", "var", "std", "median"}
if not isinstance(betanbinom_mode, str) or betanbinom_mode not in valid_modes:
return f"Invalid input: betanbinom_mode must be one of {sorted(valid_modes)}."
# Helper to normalize input to 2D list
def to2d(x):
return [[x]] if not isinstance(x, list) else x
# Handle statistics (k is ignored)
if betanbinom_mode in ["mean", "var", "std", "median"]:
if betanbinom_mode == "mean":
return float(scipy_betanbinom.mean(n_val, a_val, b_val, loc=loc_val))
if betanbinom_mode == "var":
return float(scipy_betanbinom.var(n_val, a_val, b_val, loc=loc_val))
if betanbinom_mode == "std":
return float(scipy_betanbinom.std(n_val, a_val, b_val, loc=loc_val))
if betanbinom_mode == "median":
return float(scipy_betanbinom.median(n_val, a_val, b_val, loc=loc_val))
# PMF, CDF, SF, ICDF, ISF
k_2d = to2d(k)
result = []
for row in k_2d:
if not isinstance(row, list):
return "Invalid input: k must be a scalar or 2D list."
result_row = []
for val in row:
try:
kval = float(val)
except Exception:
return "Invalid input: k must be a number."
if betanbinom_mode == "pmf":
res = float(scipy_betanbinom.pmf(kval, n_val, a_val, b_val, loc=loc_val))
elif betanbinom_mode == "cdf":
res = float(scipy_betanbinom.cdf(kval, n_val, a_val, b_val, loc=loc_val))
elif betanbinom_mode == "sf":
res = float(scipy_betanbinom.sf(kval, n_val, a_val, b_val, loc=loc_val))
elif betanbinom_mode == "icdf":
res = float(scipy_betanbinom.ppf(kval, n_val, a_val, b_val, loc=loc_val))
elif betanbinom_mode == "isf":
res = float(scipy_betanbinom.isf(kval, n_val, a_val, b_val, loc=loc_val))
result_row.append(res)
result.append(result_row)
# Return scalar if input was scalar
if not isinstance(k, list) and len(result) == 1 and len(result[0]) == 1:
return result[0][0]
return result