NAME
Database::BI::Insights - Automatic statistical insights for Database::BI (Phase 5.2)
SYNOPSIS
use Database::BI::Insights;
my $insights = Database::BI::Insights::compute(
records => \@rows,
columns => \@cols,
spec_key => 'table:sales',
base_url => '/insights?l=table:sales',
);
DESCRIPTION
Pure-arithmetic insight detection. No LLM, no external service calls. Detects four classes of insight:
- outlier
-
A value beyond the Tukey IQR fence (Q1 - 1.5*IQR or Q3 + 1.5*IQR).
- period_delta
-
Overall period-over-period delta between the most recent two month-periods visible in a date column.
- top_mover
-
The dimension member with the largest period-over-period absolute change. Requires at least one categorical column and one date column.
- seasonality
-
Detected via lag-1 autocorrelation on monthly totals. A coefficient >= 0.6 is flagged. Requires at least 8 distinct month-periods.
Every insight includes a view_url that links to the chart or stats view showing the underlying data. An insight without a clickable view_url is a bug.
FUNCTIONS
compute(%args)
my $insights = Database::BI::Insights::compute(
records => \@rows, # arrayref of row hashrefs
columns => \@cols, # arrayref of column names
spec_key => $l, # l= spec string
base_url => $url, # request URL, used only as a fallback
);
Returns an arrayref of insight hashrefs. Each hashref has:
kind -- 'outlier' | 'top_mover' | 'period_delta' | 'seasonality'
headline -- one short sentence
detail -- numbers that substantiate the headline
view_url -- URL to the view showing the data
method -- key for method_note()
method_note($key)
Returns a one-sentence description of the algorithm behind $key.
ALGORITHM NOTES
Outliers
Tukey IQR fence: Q1 - 1.5*IQR and Q3 + 1.5*IQR. Requires at least 4 values per group. Results are sorted by distance from the nearest fence; up to 5 outliers are reported per column.
Period-over-period
Year-month (YYYY-MM) buckets from ISO-8601 date columns. Requires at least 2 distinct periods.
Seasonality
Lag-1 autocorrelation r(1) on the sequence of period sums. Formula: r(1) = cov(y[t], y[t+1]) / var(y[t]). Threshold: r >= 0.6. Requires at least 8 distinct month-periods.
AUTHOR
Nigel Horne <njh@nigelhorne.com>
LICENCE AND COPYRIGHT
Copyright 2026 Nigel Horne.
Usage is subject to the GPL2 licence terms.