On tabular data, better features beat better algorithms. Good features express what a domain expert would
look at, in a form the model can use: rates instead of totals, recency instead of raw dates, behaviour
relative to the entity's own history, and missingness as information. All of it computed only from data
available at prediction time. scripts/profile_columns.py infers each column's semantic role;
scripts/suggest_features.py turns the roles into ranked ideas, flags probable leaks, and prints an
add_features(df, train) pandas function you can drop into a pipeline.
Trigger Conditions
Activate this skill when the user:
- Asks for feature ideas for a dataset, or "how can I improve this model?" when the model is already tuned
- Has raw tables (transactions, events, customers, sensors) and needs a feature table for ML
- Asks how to use dates, timestamps, IDs, zip codes, free text, coordinates or amounts as features
- Wants per-customer / per-card / per-device aggregates or velocity features
- Is stuck at a plateau and wants domain-driven features (churn, fraud, credit, demand, pricing)
Related: encoding choice in categorical-encoding-selector; scaling in feature-scaling-advisor; point-in-time window features in time-based-feature-builder; checking that new features do not leak in target-leakage-detector; pruning in feature-selection-analyzer.
Workflow
1. ROLES -> python scripts/profile_columns.py data.csv --target y
2. LEAKS -> anything written after prediction time? (suggest_features flags names; confirm with owners)
3. IDEAS -> python scripts/suggest_features.py data.csv --target y [--entity customer_id --time-col ts]
4. DOMAIN -> add the domain playbook features (references/domain-playbooks.md)
5. BUILD -> python scripts/suggest_features.py ... --code > features.py; statistics learned on train only
6. VALIDATE -> add features in groups; keep a group only if the CV metric improves beyond noise
7. GUARD -> re-run leakage checks; document every kept feature (definition, source, availability)Feature Recipes by Column Role
| Role | Recipes | Watch out |
|---|---|---|
| Datetime | month, day of week, hour, is_weekend, holiday flags; cyclical sin/cos for linear models; days since the event at prediction time | raw timestamps let trees memorise periods; never use a date after prediction time |
| Year | age = reference year − year | reference = scoring date, not "today" at training |
| Amount (skewed) | log1p, clipping at train quantiles, ratios to the entity's own average | log of negatives; clip bounds learned on all data |
| Count | log1p / bins, zero indicator, per-unit rate (count / exposure) | counts grow with tenure: normalise |
| Low-card categorical | one-hot (linear) or native categorical (GBMs); group rare levels | unseen levels at serving time |
| High-card categorical | frequency encoding, out-of-fold target encoding, hashing, embeddings | in-sample target encoding leaks |
| Code (zip, NAICS, ICD) | categorical, plus hierarchical prefixes (zip3, NAICS 2-digit) | never as a number |
| Entity key | group-by key for aggregates; never a raw feature | IDs memorise rows |
| Lat/lon | distance to points of interest, grid cell / geohash, density | raw lat/lon is fine for trees, poor for linear |
| Text | length, word count, keyword flags, TF-IDF, sentence embeddings | fit vectorisers in the pipeline |
| Proportion | logit for linear models; keep raw for trees | exact 0/1 need clipping |
| Missingness | is_missing indicator per column with > 1% missing | missingness can itself be a leak (filled after the event) |
Detailed formulas and pandas/sklearn code for each: feature-recipes-by-type.md.
Cross-Column and Entity Features
These usually carry the most signal and are what the model cannot invent on its own:
| Family | Example | Why it helps |
|---|---|---|
| Rates | total_charges / tenure_months, claims / exposure_years | removes the size/exposure effect |
| Ratios to self | amount / card_mean_amount_prior_30d | "unusual for this customer" |
| Differences | days_between(signup, first_purchase) | captures process speed |
| Recency / frequency / monetary | days since last order, orders in 90 d, spend in 90 d | classic RFM; strong for churn and CLV |
| Velocity | transactions per card in the last 1 h / 24 h | fraud, abuse |
| Trend | spend last 30 d / spend previous 30 d | declining engagement predicts churn |
| Group context | price / median price in the neighbourhood | relative position matters more than level |
| Interactions | plan x region, hour x merchant category | linear models need them explicitly; GBMs often find them |
Per-entity aggregates must use only rows strictly before each row's prediction time:
df = df.sort_values(["card_id", "timestamp"])
g = df.groupby("card_id")
df["card_n_prior"] = g.cumcount()
df["card_amount_mean_prior"] = g["amount"].transform(lambda s: s.shift().expanding().mean())
df["amount_vs_card_mean"] = df["amount"] / df["card_amount_mean_prior"]
df["secs_since_prev_txn"] = pd.to_datetime(df["timestamp"]).groupby(df["card_id"]).diff().dt.total_seconds()Window aggregates (last 1 h / 7 d / 30 d) and snapshot tables are covered in aggregation-and-interaction-features.md.
Leakage Rules for Every New Feature
- Available at prediction time? If the value is written or updated after the moment you score, it leaks.
- Statistics learned on train only. Quantiles for clipping, frequency tables, kept levels, target
encodings and scalers are fitted on the training fold and applied elsewhere:
add_features(df, train)takestrainexplicitly for this reason. - Aggregates exclude the current row and the future.
shift()beforeexpanding()/rolling(). - Names are hints, not proof.
suggest_features.pyexcludes columns named like outcomes (status, reason, refund, cancel, chargeback, resolution); confirm write times with the data owner. - A feature that alone gives AUC > 0.9 is a leak until proven otherwise.
Validate Ideas, Do Not Just Add Them
| Step | How |
|---|---|
| Group the ideas | date features, rates, entity aggregates, text, interactions |
| Add one group at a time | same CV folds, same model, same seed |
| Keep if it helps beyond noise | improvement > ~2 x the fold-to-fold standard deviation, or a paired test |
| Check importance and direction | plausible sign/shape (SHAP); surprising strength -> leak check |
| Check stability | importance and effect by time period; drop features whose meaning drifts |
| Cost | compute cost and latency at serving time; online availability |
Ablation code and stability checks: feature-validation.md.
Model Family Matters
| Model | Needs from feature engineering |
|---|---|
| Linear / logistic | scaling, log transforms, one-hot, explicit interactions and splines, cyclical dates |
| Gradient boosting / random forest | rates, aggregates, recency; no scaling; native categoricals; fewer explicit interactions |
| k-NN, SVM, clustering | scaling is mandatory; low-dimensional, meaningful distances |
| Neural nets on tabular | scaling, embeddings for categoricals; still benefit from aggregates |
Output Format
When proposing features, answer with:
- Column roles - the
profile_columns.pytable, corrected where domain knowledge says otherwise. - Possible leaks - columns to exclude or rebuild as-of prediction time, with the reason.
- Ranked ideas - P1 (cheap, usually useful), P2 (worth testing), P3 (situational), each with the column(s), the transformation and why it should help in this domain.
- Code - an
add_features(df, train)function (from--codeor written by hand) where every statistic is learned ontrain. - Validation plan - feature groups, CV setup, keep/drop rule.
Scripts
python scripts/profile_columns.py data.csv --target churned
python scripts/profile_columns.py data.csv --sample 20000 --jsonRoles: id, entity_key, datetime (ISO strings and unix epochs in s/ms), year, binary, count, amount, continuous, percentage (proportions), categorical, high_card, code (zip/postcode/NAICS/ICD), geo_lat, geo_lon, text, constant, target; with distinct count, missing share, min/max, skew, rare levels and singletons. Exit codes: 0 profiled, 2 read error.
python scripts/suggest_features.py data.csv --target churned
python scripts/suggest_features.py txns.csv --target is_fraud --entity card_id --time-col timestamp
python scripts/suggest_features.py data.csv --target price --code > features.py
python scripts/suggest_features.py data.csv --target churned --jsonImports profile_columns.py from the same folder. Prints column roles, possible leaks (outcome-like column
names, excluded from ideas), and P1/P2/P3 ideas: calendar parts (hour only when timestamps have a time),
cyclical encodings, elapsed days to the prediction time, age from year, log1p for skewed amounts and counts,
train-quantile clipping, zero indicators, rare-level grouping, frequency and target encoding, code prefixes,
text length and TF-IDF, logit of proportions, missing indicators, cumulative-total-per-exposure rates, date
differences, haversine distance, and point-in-time per-entity aggregates with --entity + --time-col.
--code prints a runnable add_features(df, train) pandas function with the P1/P2 ideas. Exit codes: 0
printed, 2 usage or read error.
Additional Resources
| File | Content |
|---|---|
| feature-recipes-by-type.md | Code for every column role: dates, cyclical, holidays, amounts, counts, categoricals, codes, geo, text, missingness |
| aggregation-and-interaction-features.md | Point-in-time aggregates, rolling windows, RFM, velocity, trends, ratios to self and group, interactions, splines |
| domain-playbooks.md | Feature lists that work in churn, fraud, credit risk, demand, marketing response, real estate, IoT/maintenance, healthcare |
| feature-validation.md | Group ablation, noise thresholds, stability over time, leakage checks for new features, documentation template |
anomaly-detection-model-builder
Build and evaluate anomaly detection for tabular, sensor and transaction data with few or no labels: define the anomaly type (point, contextual, collective), choose detectors (robust z-score/MAD and IQR rules, Mahalanobis with robust covariance, k-NN distance, LOF, Isolation Forest, one-class SVM, PCA reconstruction / autoencoders, forecasting residuals for time series), combine them by rank, explain each alert by its deviating features, set thresholds from an alert budget or the score distribution, and evaluate with precision@k, PR-AUC and recall on known incidents, or detector agreement when no labels exist. Includes pure-Python detectors (robust z, Mahalanobis, kNN, Isolation Forest, ensemble) and an evaluation script.
catboost-model-builder
Build CatBoost models that use its strengths correctly: raw categorical columns as cat_features (ordered target statistics, no manual encoding), text_features, Pool construction with NaN-safe categories, ordered boosting and has_time for temporal data, symmetric (oblivious) trees, overfitting detector with eval_set and use_best_model, losses for classification, regression (Quantile, Poisson, Tweedie) and ranking (YetiRank), class weights, monotone constraints, feature importance (PredictionValuesChange, LossFunctionChange) and SHAP values, GPU training and model export. Plans cat/text/numeric columns from a CSV and generates a runnable training script, and checks parameter sets for the conflicts CatBoost rejects (iterations vs n_estimators, Bayesian bootstrap with subsample, multiple class-weight options, depth > 16, use_best_model without eval_set).
categorical-encoding-selector
Choose and implement the right encoding for every categorical column given the model family and the data: one-hot (with infrequent-level grouping and handle_unknown), ordinal with an explicit order, cross-fitted target encoding (scikit-learn TargetEncoder, CatBoost ordered statistics, category_encoders inside CV), frequency/count encoding, feature hashing, native categorical support in LightGBM, HistGradientBoosting, XGBoost and CatBoost, prefix levels for codes (zip3, NAICS-2), and embeddings. Measures cardinality, rare-level share, unseen-level rate on a time-ordered holdout and target signal per column, emits the ColumnTransformer, and quantifies target-encoding leakage (in-sample vs out-of-fold vs holdout AUC).
classification-model-selector
Choose the right classification algorithm for tabular, text or mixed data and prove the choice with a fair bake-off: logistic regression (L2, L1, elastic net), linear SVM, naive Bayes, k-NN, RBF SVM, decision trees, random forest, extra trees, HistGradientBoosting, LightGBM, XGBoost, CatBoost, explainable boosting machines (EBM/GAM), points scorecards and MLPs, matched to data size, width, categorical and high-cardinality share, missingness, class imbalance, text, and constraints such as interpretability, monotonic constraints, calibrated probabilities, latency budgets and tiny deployable models. Ranks candidates with starting hyperparameters and cautions, then generates a bake-off script running every candidate on identical CV folds with per-fold metrics, fit time and prediction latency.
clustering-algorithm-selector
Choose the right clustering algorithm and check that clustering makes sense at all: cluster tendency (Hopkins statistic with a correlated-features caveat, nearest-neighbour isolation), then k-means / MiniBatchKMeans, Gaussian mixtures with BIC, agglomerative (Ward, average, complete, single) with dendrograms, DBSCAN, HDBSCAN, OPTICS, spectral clustering, BIRCH, mean shift, k-prototypes and k-modes for mixed or categorical data, and Gower distance, matched to data size, expected shapes, noise, varying density, known k, soft memberships, hierarchy and streaming. Covers preprocessing (scaling, encoding, dimensionality, distance metrics), validation (internal indices, bootstrap stability, external labels, business profiling) and assigning new points.
collaborative-filtering-implementer
Implement collaborative filtering recommenders that beat popularity: item-based kNN with cosine, Jaccard or asymmetric similarity, shrinkage, neighbourhood size, positive-only or mean-centred rating signals and 'because you liked X' explanations; implicit ALS with confidence weighting, BPR pairwise ranking and the closed-form EASE model in plain NumPy, tuned on a temporal validation split by recall@k and NDCG@k and refit on all data; plus user-kNN, explicit matrix factorisation, the implicit/LightFM libraries, hyperparameter ranges, cold-start fallbacks, scaling with sparse matrices and approximate nearest neighbours. Produces top-k lists in the format of the recommendation evaluator.