Skip to content

CrossFittedTransformer(Preprocessor(add_missing_indicator=True)) crashes when a fold's training rows contain no missing value #89

Description

@ChrisW09

Description

Cross-fitting a Preprocessor that adds missing indicators (add_missing_indicator=True or missing_policy="impute_with_indicator") fails whenever a column with missing values has none in some fold's training rows.

  • A column with a single missing value always triggers it.
  • With two missing values and 5 folds it happens about 20% of the time.

The error message blames adaptive sizing, which is not involved. missing_policy="separate_state" works.

Affected code

Reproduction

import warnings
import numpy as np, pandas as pd
from pretab import CrossFittedTransformer, Preprocessor

warnings.simplefilter("ignore")
rng = np.random.default_rng(0)
n = 200
a = rng.normal(size=n)
a[7] = np.nan  # a single missing value: one fold's training rows have none
X = pd.DataFrame({"a": a, "b": rng.normal(size=n)})
y = np.nan_to_num(a) + 0.1 * rng.normal(size=n)
for cfg in [dict(add_missing_indicator=True), dict(missing_policy="impute_with_indicator"), dict(missing_policy="separate_state")]:
    pre = Preprocessor(numerical_method="ple", output_dim=4, **cfg)
    print(cfg, "| Preprocessor alone:", pre.fit_transform(X, y).shape)
    try:
        print("   CrossFittedTransformer:", CrossFittedTransformer(pre, n_folds=5, random_state=0).fit_transform(X, y).shape)
    except Exception as e:
        print("   CrossFittedTransformer ->", type(e).__name__ + ":", e)

Output (PreTab 1.0.0 (6bacaba), Python 3.12, numpy 2.5.3, pandas 2.3.3, scikit-learn 1.9.1, scipy 1.18.1):

{'add_missing_indicator': True} | Preprocessor alone: (200, 12)
   CrossFittedTransformer -> IncompatibleParamsError: Cross-fitting requires a fixed output width across folds; expected 12, got 8. Disable adaptive sizing on the wrapped transformer.
{'missing_policy': 'impute_with_indicator'} | Preprocessor alone: (200, 12)
   CrossFittedTransformer -> IncompatibleParamsError: Cross-fitting requires a fixed output width across folds; expected 12, got 8. Disable adaptive sizing on the wrapped transformer.
{'missing_policy': 'separate_state'} | Preprocessor alone: (200, 10)
   CrossFittedTransformer: (200, 10)

Expected behavior

The out-of-fold features have the same columns as transform. The indicator columns do not use the target, so they can come from the all-data fit, as #86 already does for the blocks that do not use y.

Actual behavior

IncompatibleParamsError: Cross-fitting requires a fixed output width across folds; expected 12, got 8. Disable adaptive sizing on the wrapped transformer.

Impact

A crash on a combination of two documented features whenever a target-aware column has very few missing values: always with one, about 20% of the time with two, and a few percent with three (5 folds).

Root cause

The missing indicator is refitted on each fold's training rows together with the target-aware representation, so its width depends on which rows the fold contains.

Suggested fix direction

  • Keep the indicator branch from the all-data fit and refit only the representation branch of an indicator block per fold.
  • Make the width-mismatch message describe the general cause (a width that depends on the training rows) rather than adaptive sizing only.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions