featurizer × donorschoose

Which classroom projects get funded? (projects ← resources, teacher & school history)

all-agg config · 1063 features · v0.6.0 · live-DB validated

What changed since the Jul-6 snapshot. v0.6.0 rewrote the correlated-subquery aggregator tier to set-based pre-aggregation (one window pre-pass + GROUP BY per family, ADR-0010). This revalidation first fixed a latent SyntaxError: an over-63-byte companion-CTE name was hash-capped with a ~ separator and emitted unquoted, which PostgreSQL parses as an operator — it hard-blocked the all-agg config on data with long categorical column names (this DB). Result (measured, not projected): the all-agg matrix now materializes on every live DB (it previously errored or would not finish). The times are honest, though: on the larger event streams the advanced tier is still heavy — well above ADR-0010's synthetic <120 s target (that target was never actually run on this DB, since the config SyntaxError'd). The wide variant (all-agg × 14 transformers) still trips unguarded ln/sqrt on negative/zero inputs — the known math-hardening follow-up, not a v0.6.0 regression.

1 · Featurizer configuration

target
projects
max_depth
2
intervals
P1M, P6M, P12M
entities
projects, resources, teacher_history, school_history
relationships
projects.entity_id ← resources.entity_id (as-of); projects.teacher_acctid ← teacher_history.teacher_acctid (as-of); projects.schoolid ← school_history.schoolid (as-of)
aggregations
the 65-primitive default-active set (incl. the set-based gap/categorical/sequence families)

2 · Live database structure

Event knowledge dates span 2012-01-012013-12-31.

ontology.entities — 3000 rows

columntype
entity_idbigint
projectidtext
teacher_acctidtext
schoolidtext
school_statetext
school_metrotext
school_charterboolean
school_magnetboolean
teacher_prefixtext
teacher_teach_for_americaboolean
primary_focus_areatext
primary_focus_subjecttext
resource_typetext
poverty_leveltext
grade_leveltext
eligible_double_matchboolean
total_pricenumeric
students_reachedinteger
date_posteddate

ontology.events — 16682 rows

columntype
event_idbigint
entity_idbigint
datedate
project_resource_typetext
item_unit_pricenumeric
item_quantitynumeric
line_totalnumeric
vendoridtext

ontology.project_funding — 3000 rows

columntype
entity_idbigint
projectidtext
date_posteddate
total_pricenumeric
raised_totalnumeric
raised_4monumeric
unfunded_4moboolean

3 · Full-cohort materialization (v0.6.0)

Each variant materialized through featurizer's grouped/TEMP-shard path (to_dataframe(connection=…)) at one as-of date; no permanent writes. narrow = the triage config's own primitives; all-agg = the full 65-aggregator default set with identity; wide = all-agg × 14 transformers (lags, rolling, EMA, cusum…).

variantfeaturesshardsrowscolsdup-namessecondsstatus
narrow1751300017701.5materialized
all-agg10631300010650281.1materialized
widetimeouttimeout

shards = ⌈features / 1664⌉ group-queries (PostgreSQL's per-row column cap); dup-names = duplicate output column identifiers (0 = the 63-byte-cap hashing is collision-free).

4 · Generated features — a sample

Full intended label, the rendered short-name (the ≤63-byte column identifier; hash-capped when long), kind, a generated description, and a few real values from the live DB.

labelshort-name (column)kinddescriptionvalues
students_reachedstudents_reachedvariableDirect column projects.students_reached22, 120, 22
total_pricetotal_pricevariableDirect column projects.total_price578.53, 226.68, 814.38
projects.grade_level=Grades 3-5projects.grade_level=Grades 3-5one_hot1 when projects.grade_level = 'Grades 3-5', else 0 (fixed-vocabulary one-hot; NULL/out-of-vocabulary rows are all-zero)0, 0, 0
projects.grade_level=Grades 6-8projects.grade_level=Grades 6-8one_hot1 when projects.grade_level = 'Grades 6-8', else 0 (fixed-vocabulary one-hot; NULL/out-of-vocabulary rows are all-zero)0, 1, 1
projects.grade_level=Grades 9-12projects.grade_level=Grades 9-12one_hot1 when projects.grade_level = 'Grades 9-12', else 0 (fixed-vocabulary one-hot; NULL/out-of-vocabulary rows are all-zero)0, 0, 0
projects.grade_level=Grades PreK-2projects.grade_level=Grades PreK-2one_hot1 when projects.grade_level = 'Grades PreK-2', else 0 (fixed-vocabulary one-hot; NULL/out-of-vocabulary rows are all-zero)1, 0, 0
projects.poverty_level=high povertyprojects.poverty_level=high povertyone_hot1 when projects.poverty_level = 'high poverty', else 0 (fixed-vocabulary one-hot; NULL/out-of-vocabulary rows are all-zero)0, 0, 0
BURSTINESS(resources.date)BURSTINESS(resources.date)derivedGoh-Barabasi burstiness index (-1 to 1), applied to resources.date∅, ∅, ∅
BURSTINESS(resources.date|interval=P12M)BURSTINESS(resources.date|interval=P12M)derivedGoh-Barabasi burstiness index (-1 to 1), applied to resources.date, over the trailing P12M window∅, ∅, ∅
BURSTINESS(resources.date|interval=P1M)BURSTINESS(resources.date|interval=P1M)derivedGoh-Barabasi burstiness index (-1 to 1), applied to resources.date, over the trailing P1M window∅, ∅, ∅
BURSTINESS(resources.date|interval=P6M)BURSTINESS(resources.date|interval=P6M)derivedGoh-Barabasi burstiness index (-1 to 1), applied to resources.date, over the trailing P6M window∅, ∅, ∅
BURSTINESS(school_history.date_posted)BURSTINESS(school_history.date_posted)derivedGoh-Barabasi burstiness index (-1 to 1), applied to school_history.date_posted∅, ∅, ∅
BURSTINESS(school_history.date_posted|interval=P12M)BURSTINESS(school_history.date_posted|interval=P12M)derivedGoh-Barabasi burstiness index (-1 to 1), applied to school_history.date_posted, over the trailing P12M window∅, ∅, ∅
BURSTINESS(school_history.date_posted|interval=P1M)BURSTINESS(school_history.date_posted|interval=P1M)derivedGoh-Barabasi burstiness index (-1 to 1), applied to school_history.date_posted, over the trailing P1M window∅, ∅, ∅
BURSTINESS(school_history.date_posted|interval=P6M)BURSTINESS(school_history.date_posted|interval=P6M)derivedGoh-Barabasi burstiness index (-1 to 1), applied to school_history.date_posted, over the trailing P6M window∅, ∅, ∅
BURSTINESS(teacher_history.date_posted)BURSTINESS(teacher_history.date_posted)derivedGoh-Barabasi burstiness index (-1 to 1), applied to teacher_history.date_posted∅, ∅, ∅
BURSTINESS(teacher_history.date_posted|interval=P12M)BURSTINESS(teacher_history.date_posted|interval=P12M)derivedGoh-Barabasi burstiness index (-1 to 1), applied to teacher_history.date_posted, over the trailing P12M window∅, ∅, ∅
COSINOR_AMPLITUDE_WEEKLY(resources.item_unit_price|interval=P12M)COSINOR_AMPLITUDE_WEEKLY(resources.item_unit_price|int~0e6a801e cappedderivedWeekly cosinor amplitude (sin/cos regression approximation), applied to resources.item_unit_price, over the trailing P12M window∅, ∅, ∅
COSINOR_AMPLITUDE_WEEKLY(resources.item_unit_price|interval=P6M)COSINOR_AMPLITUDE_WEEKLY(resources.item_unit_price|int~18561e23 cappedderivedWeekly cosinor amplitude (sin/cos regression approximation), applied to resources.item_unit_price, over the trailing P6M window∅, ∅, ∅
COSINOR_AMPLITUDE_WEEKLY(resources.item_unit_price|interval=P1M)COSINOR_AMPLITUDE_WEEKLY(resources.item_unit_price|int~2e0699ee cappedderivedWeekly cosinor amplitude (sin/cos regression approximation), applied to resources.item_unit_price, over the trailing P1M window∅, ∅, ∅
COSINOR_AMPLITUDE_WEEKLY(school_history.students_reached|interval=P1M)COSINOR_AMPLITUDE_WEEKLY(school_history.students_reach~361ad217 cappedderivedWeekly cosinor amplitude (sin/cos regression approximation), applied to school_history.students_reached, over the trailing P1M window∅, ∅, ∅
ACF_1(resources.item_quantity)ACF_1(resources.item_quantity)derivedLag-1 autocorrelation: corr(x_t, x_{t-1}), applied to resources.item_quantity∅, ∅, ∅
ACF_1(resources.item_quantity|interval=P12M)ACF_1(resources.item_quantity|interval=P12M)derivedLag-1 autocorrelation: corr(x_t, x_{t-1}), applied to resources.item_quantity, over the trailing P12M window∅, ∅, ∅
ACF_1(resources.item_quantity|interval=P1M)ACF_1(resources.item_quantity|interval=P1M)derivedLag-1 autocorrelation: corr(x_t, x_{t-1}), applied to resources.item_quantity, over the trailing P1M window∅, ∅, ∅
ACF_1(resources.item_quantity|interval=P6M)ACF_1(resources.item_quantity|interval=P6M)derivedLag-1 autocorrelation: corr(x_t, x_{t-1}), applied to resources.item_quantity, over the trailing P6M window∅, ∅, ∅
ACF_1(resources.item_unit_price)ACF_1(resources.item_unit_price)derivedLag-1 autocorrelation: corr(x_t, x_{t-1}), applied to resources.item_unit_price0.514, ∅, ∅
ACF_1(resources.item_unit_price|interval=P12M)ACF_1(resources.item_unit_price|interval=P12M)derivedLag-1 autocorrelation: corr(x_t, x_{t-1}), applied to resources.item_unit_price, over the trailing P12M window∅, ∅, ∅
ACF_1(resources.item_unit_price|interval=P1M)ACF_1(resources.item_unit_price|interval=P1M)derivedLag-1 autocorrelation: corr(x_t, x_{t-1}), applied to resources.item_unit_price, over the trailing P1M window∅, ∅, ∅

A set-based aggregator's SQL (companion pre-agg CTE, ADR-0010)

ENTROPY(resources.project_resource_type)

-SUM(freq::float / total * LN(freq::float / total))