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.
Description
Cross-fitting a
Preprocessorthat adds missing indicators (add_missing_indicator=Trueormissing_policy="impute_with_indicator") fails whenever a column with missing values has none in some fold's training rows.The error message blames adaptive sizing, which is not involved.
missing_policy="separate_state"works.Affected code
pretab/core/supervised.py:173-194: each fold refits the wrappedPreprocessorand requires the all-data output width.pretab/compose/factory.py:121: the indicator is produced by scikit-learn's missing indicator, which only emits a column for features that have missing values in the rows it is fitted on.fix/bug-hunt-2branch (fix: resolve 10 high-priority bugs found in a library audit (#76-#85) #86), each fold derives its model from the all-data fit and refits the target-aware blocks only, but it refits the whole block, indicator included, so the same failure remains.Reproduction
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):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 usey.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