Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Case study: trimming redundant features before a model

A churn table contains nine columns. The modeling team wants to know which columns carry their own information — and which are derived, duplicated, or concentrated. The profiler measures which columns are derivable from others, how their values are distributed, and which columns predict the target. The modeling team can use these results to review candidate features.

5000 rows × 9 columns (standard budget); key candidate: x1; 5 functional dependencies, 11 predictive dependencies, 8 conditional rules

The headline reports functional dependencies, predictable columns, and rules. Its key candidate: x1 needs context: x1 is a random float, unique and non-null in all 5,000 rows. It meets the observed key criteria but does not represent an entity identifier.

For feature trimming, inspect dependencies for derived columns, concentration for columns with little variation, and predictive statements for candidate inputs.

— dependencies
  [functional] score, segment → channel holds on 99.64% of rows (18 violations in 5000 rows)
  [functional] plan, score → segment holds on 99.46% of rows (27 violations in 5000 rows)
  [functional] segment, score → plan holds on 99.22% of rows (39 violations in 5000 rows)
  [predictive] score depends on x2 and x1 jointly: 99.7% of the pair's joint partial-dependence variance is interaction (H² = 1.00); the interaction variance is 0.113265 against a target variance of 0.11732 (96.5%), from a surrogate with holdout R² 0.98 against 0.00 for an additive refit
  [predictive] score follows 8 local linear regimes (first split x2 ≤ 0.611857; holdout R² 0.910 versus 0.002 for one linear model)
  [predictive] segment is predictable from [plan] (holdout accuracy 0.97 vs 0.51 majority baseline)
  [predictive] plan is predictable from [segment] (holdout accuracy 0.97 vs 0.52 majority baseline)
  [predictive] tenure_months is predictable from [tenure, x1] (holdout R² = 1.00)
  [predictive] tenure is predictable from [tenure_months, x2, score] (holdout R² = 1.00)
  [predictive] score is predictable from [tenure, x1, x2, channel, segment, churn] (holdout R² = 0.98)
  [predictive] x2 is predictable from [tenure, x1, score, segment, plan, churn] (holdout R² = 0.88)
  [predictive] x1 is predictable from [tenure, x2, score, segment] (holdout R² = 0.83)
  [predictive] churn is predictable from [tenure, x2, score] (holdout accuracy 0.95 vs 0.77 majority baseline)
  [functional] tenure → tenure_months (tenure_months is a function of tenure; 0 violations in 5000 rows)
  [functional] tenure_months → tenure (tenure is a function of tenure_months; 0 violations in 5000 rows)
  [predictive] churn is predicted from [tenure] with 0.896 cross-validated accuracy (majority baseline 0.769)

— concentration and roles
  column channel is highly concentrated: 98.1% 'web' (effective cardinality 1.10)
  numeric column tenure behaves like a category (60 distinct values)
  numeric column tenure_months behaves like a category (60 distinct values)
  column x1 looks like a unique identifier (5000 distinct of 5000 values)
  column x2 looks like a unique identifier (5000 distinct of 5000 values)

— rules
  When tenure > 1 and tenure <= 3, churn = true holds in 30 of 31 matching diagnostic rows (96.77%; baseline 24.40%)
  When tenure > 9 and tenure <= 11, churn = true holds in 38 of 41 matching diagnostic rows (92.68%; baseline 24.40%)
  When tenure > 24 and tenure <= 26, churn = false holds in 35 of 35 matching diagnostic rows (100.00%; baseline 75.60%)
  When tenure > 29 and tenure <= 31, churn = false holds in 34 of 35 matching diagnostic rows (97.14%; baseline 75.60%)
  When plan = "scale", segment = "b2b" holds in 484 of 492 matching diagnostic rows (98.37%; baseline 50.00%)
  When segment = "retail", plan = "starter" holds in 496 of 504 matching diagnostic rows (98.41%; baseline 51.19%)
  When segment = "b2b", plan = "scale" holds in 484 of 504 matching diagnostic rows (96.03%; baseline 48.81%)
  When plan = "starter", segment = "retail" holds in 496 of 516 matching diagnostic rows (96.12%; baseline 50.00%)

The trimming checklist

Redundant measurements. tenure and tenure_months are exact functions of each other: 0 violations in both directions. Because tenure_months is tenure / 12 rounded to two decimals, every observed integer month count maps to one year value and back, so the profiler’s partition test finds a bijection rather than fitting a slope. These two columns contain the same observed information. Keeping both can divide feature importance between equivalent inputs. Decision: drop tenure_months, keep tenure.

Check what a unique float represents. x1 and x2 both surface as identifier-role columns, and x1 wins the headline’s key ranking. In a feature table that is a warning: the column is unique because it is continuous, not because it identifies an entity. Keep it as a feature; do not join on it.

Interactions are not redundancy. score is predictable from the rest of the table at holdout R² 0.98, and the model’s gain is almost entirely on x2 and x1 (gain shares 0.63 and 0.37, respectively; every other input is below 0.001). The piecewise model makes the same point from another angle: score follows 8 local linear regimes with holdout R² 0.910, against 0.002 for one global linear model. The low global linear R² misses the interaction used to construct score. Keep x1 and x2 as candidate inputs and compare models with an explicit product feature.

Review concentrated columns. channel is 98.1% one value — effective cardinality 1.10. Most rows therefore have the same encoded value. Exclude it in this fixture, but check the minority rows and predictive performance before dropping a similarly concentrated column in a real dataset.

Inspect approximate mappings. The rules from segment to plan hold in 96–98% of matching rows depending on the segment (b2b → scale 96.03%, retail → starter 98.41%); the profiler also lists segment, score → plan at 99.22% with 39 violations. The additional condition needs scrutiny: score is a near-unique float, so putting it in the antecedent can leave few repeated input combinations. Check support and violations before treating these mappings as constraints or using them to remove features.

The target is predictable. The model predicts churn mainly from tenure; x2 and score each contribute less than 0.001 of model gain. Holdout accuracy is 0.95 against a 0.77 majority baseline. A decision table on tenure alone reaches cross-validated accuracy 0.896 against 0.769. These results support evaluating tenure as a predictor.

churn is predictable from [tenure, x2, score] (holdout accuracy 0.95 vs 0.77 majority baseline)
   inputs: ['score', 'tenure', 'x2'] | score: 0.951 | baseline: 0.767
churn is predicted from [tenure] with 0.896 cross-validated accuracy (majority baseline 0.769)
   inputs: ['tenure'] | score: 0.896 | baseline: 0.769

The control: shuffle the target

As a negative control, shuffle churn and profile the table again. The predictive findings about churn should disappear. If they remain, investigate possible leakage in the analysis.

predictive churn findings after shuffling: 0

No predictive finding about the shuffled target remains. This control checks that the screen does not report predictability after the planted target relationship has been removed.

Summary

StatementEvidence classTrimming decision
tenure and tenure_months are exact functions of each other (0 violations)measured · fulldrop the rounded copy
score predictable from the rest (holdout R² 0.98; 8 regimes, 0.910 vs 0.002 linear)estimated · holdoutkeep x1, x2; consider an explicit product
channel 98.1% one valuemeasured · fullexclude from one-hot
segment → plan 96–98%; segment, score → plan 99.22%measured · diagnostic partitioninspect mapping violations and support
churn from tenure (0.896 CV; holdout 0.95 vs 0.77)estimated · holdoutevaluate tenure as a predictor

The groups view links findings that share columns:

group-1 — 9 columns, 27 findings
   columns: channel, churn, plan, score, segment, tenure, tenure_months, x1, x2
    Connected findings; inspect individual statements and directions before inferring redundancy.

The whole table is one connected component: the exact copy joins tenure to tenure_months, the predictive statements join score to x1 and x2, and other shared-column links connect churn and channel. One derived column can connect otherwise separate sets of findings into a single component. Use groups to navigate shared columns; assess redundancy from the individual findings.