The ZIP Code That Ate the Cluster
A home-services marketplace wants to predict which quotes convert to booked jobs. The training file is a 9.2 GB CSV with 11.8 million rows and 58 columns, loaded on a 3-node H2O-3 cluster with 48 GB of RAM per node. Three fields dominate: zip_code (about 41,000 distinct values), pro_id (about 310,000 values, the matched professional), and device_model (about 8,900 values). The 34 numeric columns include quote_amount, which is heavily right-skewed with 6% negative values, and days_since_signup, which is 31% missing. quote_timestamp arrives as a string such as 2024-03-11T08:42:19Z. The team launches h2o.automl() with default settings; four hours later only two models have finished, the log shows repeated OutOfMemoryError: Java heap space, and one node dropped out of the cluster. Cross-validated AUC on the two finished models is 0.71. The team's proposed fix is to add more RAM to each node.
1. Diagnose the memory blow-up and prescribe what to do with `zip_code`, `pro_id`, and `device_model`.
Read the worked answer
Adding RAM treats a symptom. H2O holds entire frames in memory, column-compressed, so a 9.2 GB CSV typically expands to roughly 2–4x that once parsed, and categorical domains add per-level metadata. Worse, several algorithms expand categoricals into a design matrix internally - H2O's XGBoost wrapper one-hot encodes categorical columns, and GLM does too - so zip_code alone can become ~41,000 columns and pro_id ~310,000 over 11.8M rows. Cross-validation then multiplies the footprint: each fold holds training frames plus a model copy, and retaining CV predictions for stacked ensembles keeps more alive at once. That is the OOM.
Prescriptions:
pro_id: drop it. It is an identifier with hundreds of thousands of levels, near-unique relative to the signal it carries; it will memorise professionals rather than generalise, and it is useless for a quote that has not yet been matched.zip_code: recode. Roll up to 3-digit prefix or a sales region (hundreds of levels), or replace with frequency and a small set of market-level aggregates. Keep the raw code only as anignored_columnsentry.device_model: collapse. Top-N models plus an 'other' bucket. Then setignored_columnsexplicitly so the raw columns never enter AutoML, reducenfoldswhile iterating, and disablekeep_cross_validation_predictionsuntil the final run.
2. How would you handle the missingness in `days_since_signup`, the skew and negative values in `quote_amount`, and the string `quote_timestamp`?
Read the worked answer
days_since_signup, 31% missing. Missingness this large is usually a signal, not noise - accounts created in-session have no value. Do not mean-impute: it collapses a meaningful group into the middle of the distribution. Add an explicit signup_missing binary flag, and let GBM/DRF/XGBoost route NAs down a default branch, which they handle natively. If the downstream model cannot take NAs (e.g. a plain GLM), impute a sentinel and keep the flag.
quote_amount. Tree models are invariant to monotone transforms, so the skew is harmless for GBM/DRF/XGBoost - log-transforming buys nothing and costs interpretability. The negatives are the real issue: 6% refunds are a different business event, not a small quote. Create is_refund and model the absolute amount separately, or clip and flag. If a regularised GLM is in the mix, rank-transform or winsorise, because IRLSM will be dominated by the tail.
quote_timestamp. Force parsing at import (col.types with a date type, or h2o.as_date with the exact format) rather than leaving it as a string; a string column is either dropped or one-hot encoded into hundreds of thousands of garbage levels. Then derive hour-of-day, day-of-week, month, holiday proximity, and days-since-previous-quote. Do not feed the raw epoch as a numeric feature - trees cannot extrapolate beyond the training range and the model will silently go stale.
3. The stakeholder asks whether this should be built in H2O-3 or Driverless AI. What is your reasoning?
Read the worked answer
The decision hinges on who owns the encoding work and how much transparency is required.
H2O-3 gives explicit control: you decide exactly how zip_code is recoded, what is dropped, and which folds are used. That is valuable here because the correct treatment (drop the professional ID, roll up geography) is a domain judgement, not a statistical one, and you want it documented and reproducible. The cost is that AutoML will happily one-hot encode whatever you leave in the frame.
Driverless AI automates much of this: it detects high-cardinality categoricals and applies frequency and out-of-fold target encoding rather than one-hot expansion, adds date and text feature engineering, and runs time-boxed experiments with its own model and hyperparameter search. For a dataset with three very high-cardinality fields, DAI is likely to reach a usable model faster without manual recoding - but the target encoding is a statistical transform that must be audited for leakage and for stability as new levels appear, and the resulting pipeline is less transparent to a sceptical reviewer.
Either way, the non-negotiable step is the same: drop pro_id before training. Neither tool should be trusted to discover that on its own. If the team's priority is explainability and a documented feature pipeline, choose H2O-3; if it is time-to-first-model and the team lacks feature engineering capacity, choose DAI and budget time for encoding review.