This page describes five files of the analytics module in src/cluster_erp/modules/analytics/: statistics.py (robust descriptives and outlier screens), inference.py (hypothesis tests and models), inference_service.py (the fetch layer that turns declared facts into samples), distributions.py (the distribution functions behind p-values), and stratification.py (stratified ratios). Every method turns its precondition into a gate and refuses to answer when the precondition fails (src/cluster_erp/modules/analytics/statistics.py:1-14).
Scope and source¶
- Defined in:
StatisticsEngine(src/cluster_erp/modules/analytics/statistics.py:97), the pure test functions ininference.py,InferenceEngine(src/cluster_erp/modules/analytics/inference_service.py:153),distributions.py, andstratified_ratio(src/cluster_erp/modules/analytics/stratification.py:54). - Routes:
GET /analysis/statistics/{fact_key}/{column},GET /analysis/outliers/{fact_key}/{column},GET /analysis/stratified/{fact_key},GET /analysis/levels/{fact_key}, and the routes under/analysis/tests/,/analysis/pca/, and/analysis/cluster/(src/cluster_erp/modules/analytics/routes.py:117-940).
Descriptive statistics and outliers¶
| Operation | What it returns | Gates | Source |
|---|---|---|---|
describe |
Count, robust descriptives (median, IQR, MAD scaled to sigma, trimmed mean), and the quantile type used | currency scope, live filter | src/cluster_erp/modules/analytics/statistics.py:179-310 |
outliers |
An IQR fence and a generalised ESD screen as a review queue | n below analytics_min_n_for_zscore refused; IQR of zero refuses the fence; mixed currencies refused |
src/cluster_erp/modules/analytics/statistics.py:312-432 |
The engine supports the quantile types 1 and 7, the two that the database computes natively (src/cluster_erp/modules/analytics/statistics.py:64-68). The parameters come from settings: analytics_quantile_type (default 1), analytics_trimmed_mean_pct (10), analytics_mad_sigma_constant (1.4826), analytics_min_n_for_zscore (11), and analytics_min_iqr_for_fence (0) (src/cluster_erp/config/settings.py:437-452, src/cluster_erp/modules/analytics/service.py:242-253). The docstring states that an outlier screen is a human review queue, never an automatic deletion or correction (src/cluster_erp/modules/analytics/statistics.py:21-25).
Hypothesis tests and models¶
Each test is a pure function on lists. InferenceEngine fetches the samples and calls it.
| Test or model | Function | Engine method | Source |
|---|---|---|---|
| Welch t test, with Student's pooled t alongside | welch_t_test |
t_test |
src/cluster_erp/modules/analytics/inference.py:96, src/cluster_erp/modules/analytics/inference_service.py:672 |
| Paired t test | paired_t_test |
paired_t |
src/cluster_erp/modules/analytics/inference.py:193, src/cluster_erp/modules/analytics/inference_service.py:751 |
| One-way ANOVA and Welch ANOVA | one_way_anova |
anova |
src/cluster_erp/modules/analytics/inference.py:229, src/cluster_erp/modules/analytics/inference_service.py:702 |
| Mann-Whitney U | mann_whitney_u |
mann_whitney |
src/cluster_erp/modules/analytics/inference.py:362, src/cluster_erp/modules/analytics/inference_service.py:721 |
| Chi-square independence, Fisher's exact test for a 2x2 that fails Cochran's rule | chi_square_independence |
chi_square |
src/cluster_erp/modules/analytics/inference.py:432, src/cluster_erp/modules/analytics/inference_service.py:774 |
| Pearson and Spearman correlation | pearson_correlation, spearman_correlation |
correlation |
src/cluster_erp/modules/analytics/inference.py:560-623, src/cluster_erp/modules/analytics/inference_service.py:812 |
| Kruskal-Wallis | kruskal_wallis |
kruskal |
src/cluster_erp/modules/analytics/inference.py:624, src/cluster_erp/modules/analytics/inference_service.py:854 |
| Wilcoxon signed rank | wilcoxon_signed_rank |
wilcoxon |
src/cluster_erp/modules/analytics/inference.py:705, src/cluster_erp/modules/analytics/inference_service.py:892 |
| Levene (Brown-Forsythe) | levene_brown_forsythe |
levene |
src/cluster_erp/modules/analytics/inference.py:1564, src/cluster_erp/modules/analytics/inference_service.py:873 |
| Normality (D'Agostino K2) and Shapiro-Wilk | dagostino_k2, shapiro_wilk |
normality, shapiro |
src/cluster_erp/modules/analytics/inference.py:1388-1563, src/cluster_erp/modules/analytics/inference_service.py:915, src/cluster_erp/modules/analytics/inference_service.py:1110 |
| Principal components and k-means | principal_components, kmeans_cluster |
pca, kmeans |
src/cluster_erp/modules/analytics/inference.py:875-1015, src/cluster_erp/modules/analytics/inference_service.py:972-1014 |
| Repeated-measures ANOVA | repeated_measures_anova |
rm_anova |
src/cluster_erp/modules/analytics/inference.py:1017, src/cluster_erp/modules/analytics/inference_service.py:1016 |
| Logistic and linear regression | logistic_regression, linear_regression |
logistic, regression |
src/cluster_erp/modules/analytics/inference.py:1100-1386, src/cluster_erp/modules/analytics/inference_service.py:1065, src/cluster_erp/modules/analytics/inference_service.py:1134 |
Rules stated by the module (src/cluster_erp/modules/analytics/inference.py:1-34):
- Each test returns an effect size with its p-value.
- Two constant groups make t undefined; the test is refused.
- Chi-square follows Cochran's rule; a larger table that violates it is refused with the offending counts.
- Mann-Whitney uses the exact distribution for small tie-free groups and otherwise a corrected normal approximation, and says which.
- Every measurement is returned as a string; counts stay integers.
Sample fetching¶
InferenceEngine is the only place samples come from (src/cluster_erp/modules/analytics/inference_service.py:1-17):
- Columns resolve through
profile_targets, the same allow-list as every other reader. - The fact's live filter always applies.
- A monetary value column spanning several currencies is refused with the currency dimension named.
- Rows are capped by
analytics_inference_max_rows(default 100000), and the cap refuses instead of truncating (src/cluster_erp/config/settings.py:524,src/cluster_erp/modules/analytics/inference_service.py:156-158). - Null values are excluded and counted in the answer.
GET /analysis/levels/{fact_key} lists the levels of a dimension so that the interface can offer groups (src/cluster_erp/modules/analytics/routes.py:385-407, src/cluster_erp/modules/analytics/inference_service.py:571).
Distribution functions¶
distributions.py implements the normal, gamma, beta, t, F, and chi-square functions behind p-values from standard numerical algorithms on the standard library, without extra dependencies, in double precision (src/cluster_erp/modules/analytics/distributions.py:1-17, src/cluster_erp/modules/analytics/distributions.py:31-185).
Stratified ratios¶
stratified_ratio returns three rates per group, each labelled with the question it answers: the stratified rate, the crude rate, and the directly standardised rate. It flags a reversal between the crude and standardised rankings and reports coverage when a group has no observations in a stratum (src/cluster_erp/modules/analytics/stratification.py:1-35, src/cluster_erp/modules/analytics/stratification.py:54, src/cluster_erp/modules/analytics/stratification.py:195). The route is GET /analysis/stratified/{fact_key} (src/cluster_erp/modules/analytics/routes.py:310-383).
Constraints and validation¶
- Statistical figures are computed in IEEE double; monetary inputs are converted to
floatfor test statistics only (src/cluster_erp/modules/analytics/distributions.py:11-17). See the discrepancy on analytics module. - All engines are built at one point in the service, so every answer uses the same quantile type and gates (
src/cluster_erp/modules/analytics/service.py:242-253).
Terms introduced¶
| Term | Code identifier | Definition | Turkish term | Source |
|---|---|---|---|---|
| precondition gate | ANALYTICS_PRECONDITION_FAILED |
A refusal raised when a method's precondition does not hold. | Ön koşul kapısı | src/cluster_erp/modules/analytics/errors.py:39 |
| outlier screen | StatisticsEngine.outliers |
A review queue of values outside a fence; nothing is changed or deleted. | Aykırı değer taraması | src/cluster_erp/modules/analytics/statistics.py:312 |
| standardised rate | stratified_ratio |
A group rate reweighted to a common stratum mix. | Standartlaştırılmış oran | src/cluster_erp/modules/analytics/stratification.py:54 |
Related pages¶
- Analytics module
- Recipes and query builder
- Forecasting and classification
- Reports, summaries, and cross
Verified against commit 92f8051 on 2026-11-13.