"""Feature engineering: costruisce la matrice X dalle colonne di contesto. Le feature sono SOLO informazioni note al momento dell'incrocio (nessun esito futuro). Categoriche e numeriche sono gestite da un ColumnTransformer (one-hot per le categoriche, passthrough per le numeriche) per restare compatibili con l'export ONNX della Fase 4. """ from __future__ import annotations import pandas as pd from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder from sklearn.impute import SimpleImputer from sklearn.pipeline import Pipeline def build_preprocessor(num_cols: list[str], cat_cols: list[str]) -> ColumnTransformer: num = Pipeline([("impute", SimpleImputer(strategy="median"))]) cat = Pipeline([ ("impute", SimpleImputer(strategy="most_frequent")), ("oh", OneHotEncoder(handle_unknown="ignore", sparse_output=False)), ]) return ColumnTransformer([ ("num", num, num_cols), ("cat", cat, cat_cols), ]) def select_xy(df: pd.DataFrame, num_cols: list[str], cat_cols: list[str]): cols = num_cols + cat_cols X = df[cols].copy() for c in cat_cols: X[c] = X[c].astype(str) return X