stats¶
Power-law tail fits with likelihood-ratio comparisons against lognormal and exponential tails.
Heavy-tail tests for degree and strength distributions.
A straight line on a log-log plot is weak evidence of a power law. This module follows Clauset, Shalizi and Newman (2009), "Power-law distributions in empirical data", SIAM Review 51(4):
- Estimate the exponent by maximum likelihood for every candidate lower
bound
xmin, and keep thexminwhose fit has the smallest Kolmogorov-Smirnov distance to the data. - Fit lognormal and exponential distributions to the same tail.
- Compare each alternative with the power law using Vuong's normalized log-likelihood ratio test.
Degrees are integers and use the discrete likelihoods (Hurwitz zeta for the power law). Strengths are real-valued and use the continuous likelihoods.
The implementation uses SciPy directly instead of the powerlaw package,
which would add matplotlib and mpmath as dependencies. The test suite checks
the continuous estimates against powerlaw.
FitQuantity
module-attribute
¶
FitQuantity: TypeAlias = Literal[
"degree",
"in_degree",
"out_degree",
"strength",
"in_strength",
"out_strength",
]
Which per-node quantity to fit. Degrees are discrete; strengths continuous.
Distribution
module-attribute
¶
A fitted distribution family: the power law, or one of the two alternatives it is compared against (lognormal and exponential).
DistributionComparison
dataclass
¶
Result of a likelihood-ratio test of the power law against one alternative.
Attributes:
| Name | Type | Description |
|---|---|---|
alternative |
str
|
Name of the alternative distribution. |
loglikelihood_ratio |
float
|
Vuong's |
p_value |
float
|
Two-sided p-value for |
favoured
¶
Return the better-supported distribution, or "inconclusive".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
significance
|
float
|
Threshold for the p-value. Clauset et al. use 0.1. |
0.1
|
Returns:
| Type | Description |
|---|---|
str
|
|
PowerLawFit
dataclass
¶
PowerLawFit(
quantity: str,
discrete: bool,
alpha: float,
xmin: float,
n: int,
n_tail: int,
ks_distance: float,
vs_lognormal: DistributionComparison,
vs_exponential: DistributionComparison,
lognormal_mu: float,
lognormal_sigma: float,
exponential_rate: float,
values: tuple[float, ...],
)
A power-law fit to the tail of a distribution, with model comparisons.
Attributes:
| Name | Type | Description |
|---|---|---|
quantity |
str
|
What was fitted, for example |
discrete |
bool
|
Whether discrete likelihoods were used. |
alpha |
float
|
Estimated exponent of |
xmin |
float
|
Lower bound of the power-law tail. |
n |
int
|
Number of positive observations. |
n_tail |
int
|
Number of observations at or above |
ks_distance |
float
|
Kolmogorov-Smirnov distance between the tail and the fitted power law. |
vs_lognormal, vs_exponential |
Likelihood-ratio tests against the two alternatives. |
|
lognormal_mu, lognormal_sigma |
Parameters of the lognormal fitted to the tail. |
|
exponential_rate |
float
|
Rate of the exponential fitted to the tail. |
values |
tuple[float, ...]
|
The observations, sorted ascending. Excluded from |
ccdf
¶
ccdf(
x: ArrayLike, distribution: Distribution = "power_law"
) -> FloatArray
Evaluate a fitted model's complementary CDF, conditional on x >= xmin.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
ArrayLike
|
Points at or above |
required |
distribution
|
Distribution
|
|
'power_law'
|
Returns:
| Type | Description |
|---|---|
ndarray
|
|
fit_power_law
¶
fit_power_law(
values: ArrayLike,
*,
discrete: bool,
xmin: float | None = None,
min_tail: int = 10,
quantity: str = "values",
) -> PowerLawFit
Fit a power law to the tail of a sample and compare it with alternatives.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
ArrayLike
|
Observations. Non-positive values are ignored. |
required |
discrete
|
bool
|
Use discrete likelihoods. Values are then expected to be integers. |
required |
xmin
|
float | None
|
Fix the lower bound instead of choosing it by KS distance. |
None
|
min_tail
|
int
|
Smallest tail size considered when choosing |
10
|
quantity
|
str
|
Label stored on the result. |
'values'
|
Returns:
| Type | Description |
|---|---|
PowerLawFit
|
The fit and its comparisons with lognormal and exponential models. |
Raises:
| Type | Description |
|---|---|
InsufficientDataError
|
If fewer than |
degree_distribution_fit
¶
degree_distribution_fit(
g: Graph[Any],
quantity: FitQuantity = "degree",
*,
xmin: float | None = None,
min_tail: int = 10,
) -> PowerLawFit
Test whether a graph's degree or strength distribution has a power-law tail.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
g
|
Graph[Any]
|
A graph; strengths use the edge attribute |
required |
quantity
|
FitQuantity
|
Per-node quantity to fit; see |
'degree'
|
xmin
|
float | None
|
Fix the lower bound of the tail instead of estimating it. |
None
|
min_tail
|
int
|
Smallest tail size considered when estimating |
10
|
Returns:
| Type | Description |
|---|---|
PowerLawFit
|
Exponent, |
Raises:
| Type | Description |
|---|---|
UnknownMetricError
|
If |
InsufficientDataError
|
If the graph is too small for a tail fit. |
Examples: