Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Autoimputation

This notebook demonstrates the functionality of the autoimpute module, which provides an automated approach to selecting and applying optimal imputation methods for missing data. Rather than manually testing different approaches, autoimpute evaluates multiple methods (tuning their hyperparameters to the specific dataset), identifies which performs best for your specific data, and applies it to generate high-quality imputations.

autoimpute function

def autoimpute(
    donor_data: pd.DataFrame,
    receiver_data: pd.DataFrame,
    predictors: List[str],
    imputed_variables: List[str],
    weight_col: Optional[str] = None,
    models: Optional[List[Type]] = None,
    imputation_quantiles: Optional[List[float]] = None,
    hyperparameters: Optional[Dict[str, Dict[str, Any]]] = None,
    tune_hyperparameters: Optional[bool] = False,
    preprocessing: Optional[Dict[str, str]] = None,
    impute_all: Optional[bool] = False,
    metric_priority: Optional[str] = "auto",
    random_state: Optional[int] = RANDOM_STATE,
    train_size: Optional[float] = TRAIN_SIZE,
    k_folds: Optional[int] = 5,
    force_retrain: Optional[bool] = False,
    log_level: Optional[str] = "WARNING",
) -> AutoImputeResult
ParameterTypeDefault usedDescription
donor_datapd.DataFrame-DataFrame with predictor and target variables for training
receiver_datapd.DataFrame-DataFrame where imputed values will be generated
predictorsList[str]-Column names of predictor variables
imputed_variablesList[str]-Column names of variables to impute
weight_colstrNoneColumn name for sampling weights
modelsList[Type][QRF, OLS, QuantReg, Matching, MDN]List of imputer classes to compare.
imputation_quantilesList[float][0.05 to 0.95 in steps of 0.05]Quantiles at which to predict
hyperparametersDictNoneModel-specific hyperparameters (e.g., {“QRF”: {“n_estimators”: 200}})
tune_hyperparametersboolFalseEnable automatic hyperparameter tuning
preprocessingDict[str, str]NoneVariable transformations: {“var”: “normalize”/“log”/“asinh”}
impute_allboolFalseReturn imputations for all models, not just the best
metric_prioritystr“auto”Model selection strategy: “auto”, “numerical”, “categorical”, “combined”
random_stateint42Random seed for reproducibility
train_sizefloat0.8Proportion of donor data for training in cross-validation
k_foldsint5Number of cross-validation folds
force_retrainboolFalseForce MDN model retraining (bypass cache)
log_levelstr“WARNING”Logging verbosity level

AutoImputeResult

The function returns an AutoImputeResult object with the following attributes:

AttributeTypeDescription
imputationsDictMaps model names to quantile → DataFrame of imputed values
receiver_datapd.DataFrameReceiver data with imputed values integrated
fitted_modelsDictMaps model names to fitted ImputerResults objects (if impute_all=True also includes all other fitted models)
cv_resultsDictCross-validation metrics per model (quantile_loss, log_loss)

Access the best model’s imputations using AutoImputeResult.imputations["best_method"].

Data preparation

This demonstration uses the diabetes dataset from scikit-learn. In real-world imputation scenarios, you would typically have a “donor” dataset with complete information for both predictor and target variables, and a “receiver” dataset that lacks some target variables that need to be imputed.

Loading...

For this demonstration, the diabetes dataset is split into donor and receiver portions. Part of the data is treated as the donor dataset with complete information, and another part as the receiver dataset with some variables that need imputation. autoimpute handles imputation of numerical, categorical and boolean variables, lifting constraints on the choice of data sets and variables.

Donor data shape: (309, 10)
Receiver data shape: (133, 8)
Predictors: ['age', 'sex', 'bmi', 'bp']
Variables to impute: ['s1', 's4']

Running autoimpute

Use the autoimpute function to automatically evaluate different imputation methods, select the best one, and generate imputations. The function handles all the complexity of model evaluation, selection, and application in a single call.

Loading...
[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.
[Parallel(n_jobs=-1)]: Done   3 out of   3 | elapsed:    7.3s finished
[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.
[Parallel(n_jobs=-1)]: Done   3 out of   3 | elapsed:    1.0s finished
[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.
[Parallel(n_jobs=-1)]: Done   3 out of   3 | elapsed:    0.8s finished
Shape of receiver data before imputation: (133, 10) 
Shape of receiver data after imputation: (133, 10)
[Parallel(n_jobs=1)]: Done   1 tasks      | elapsed:    1.1s
[Parallel(n_jobs=1)]: Done   3 out of   3 | elapsed:    1.2s finished

Understanding the results

The autoimpute function returns an AutoimputeResults objects that provide comprehensive information about the imputation process:

Cross-validation results for different imputation methods:

Model: OLS
quantile loss results: 0.0126

Model: QuantReg
quantile loss results: 0.0126

Model: QRF
quantile loss results: 0.0160

Model: Matching
quantile loss results: 0.0233

The table above provides a comprehensive view of how each imputation method performs across different quantiles. The ‘mean_loss’ column shows the average quantile loss across all quantiles for each method. Lower values indicate better performance, and autoimpute automatically selects the method with the lowest average loss.

Best performing method: <microimpute.models.ols.OLSResults object at 0x177c5e900>

Visualizing method comparison

Visualize how different methods perform across quantiles provides insight into which methods are most appropriate for different parts of the distribution.

Loading...

The plot above illustrates how each imputation method performs across different quantiles of the distribution. Methods with consistently lower lines generally perform better overall.

Examining the imputed values

Now let us assess the actual imputed values generated by the best-performing method.

Median imputed values:
Loading...
Receiver dataset with imputed values:
Loading...

Evaluating imputation quality

In this demonstration, since the receiver dataset was artificially created by removing variables from the original data, there exists the unique opportunity to evaluate the quality of our imputations by comparing them to the actual values.

Loading...
Loading...

The plots above show how well the imputed values (red) match the actual values (blue) that were removed from the receiver dataset. This visual comparison helps assess the quality of the imputations generated by the best-performing method.

Advanced usage

Custom models and hyperparameters

The autoimpute function allows for customization of both the models to evaluate and their hyperparameters. This flexibility enables adaptation to specific dataset characteristics and imputation requirements. The models that support hyperparameter specification and tuning are Matching and QRF.

Loading...
[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.
[Parallel(n_jobs=-1)]: Done   3 out of   3 | elapsed:    1.6s finished
[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.
[Parallel(n_jobs=-1)]: Batch computation too fast (0.1265852451324463s.) Setting batch_size=2.
[Parallel(n_jobs=-1)]: Done   3 out of   3 | elapsed:    0.1s finished
[Parallel(n_jobs=1)]: Done   1 tasks      | elapsed:    0.1s
[Parallel(n_jobs=1)]: Done   3 out of   3 | elapsed:    0.1s finished
Loading...

Comparison of imputed values across models

For comparing, not only performance through quantile loss, but also final results through the evaluation of imputed values, autoimpute supports setting the parameter impute_all to True so that it will not only perform impuation with the model chosen as the best performing but also all others. When set to True, this parameter ensures that autoimpute’s results base clase contains an imputations dictionary and fitted models dictionary for all other models in addition to the “best_method”.

Loading...
[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.
[Parallel(n_jobs=-1)]: Batch computation too fast (0.1340169906616211s.) Setting batch_size=2.
[Parallel(n_jobs=-1)]: Done   3 out of   3 | elapsed:    0.1s finished
[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.
[Parallel(n_jobs=-1)]: Done   3 out of   3 | elapsed:    0.4s finished
[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.
[Parallel(n_jobs=-1)]: Done   3 out of   3 | elapsed:    0.8s finished
[Parallel(n_jobs=1)]: Done   1 tasks      | elapsed:    0.0s
[Parallel(n_jobs=1)]: Done   3 out of   3 | elapsed:    0.1s finished
Imputation results available for models: dict_keys(['best_method', 'QuantReg', 'QRF', 'Matching'])
The best performing model is: OLSResults