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.

Ordinary Least Squares (OLS) imputation

This notebook demonstrates how to use Microimpute’s OLS imputer to impute values using linear regression. OLS imputation is a parametric approach that assumes a linear relationship between the predictor variables and the variable being imputed.

Variable type support

The OLS model intelligently handles both numerical and categorical variables. When imputing numerical targets, it uses standard linear regression. For categorical targets (strings, booleans, or numerically-encoded categorical variables), it automatically switches to logistic regression classification internally. You don’t need to specify variable types—the model detects and adapts automatically.

The OLS model supports iterative imputation with a single object and workflow. Pass a list of imputed_variables with all variables that you hope to impute for and the model will do so without needing to fit and predict for each separately.

OLS class

class OLS(
    log_level: Optional[str] = "WARNING"
)
ParameterTypeDefault usedDescription
log_levelstr“WARNING”Logging verbosity level

fit() method

def fit(
    X_train: pd.DataFrame,
    predictors: List[str],
    imputed_variables: List[str],
    weight_col: Optional[str] = None,
) -> OLSResults
ParameterTypeDefault usedDescription
X_trainpd.DataFrame-Training data with predictors and target variables
predictorsList[str]-Column names to use as predictors
imputed_variablesList[str]-Column names to impute
weight_colstrNoneColumn name for sampling weights

It returns a OLSResults object for prediction. Internally uses linear regression for numerical targets and logistic regression for categorical/boolean targets.

OLSResults.predict() method

def predict(
    X_test: pd.DataFrame,
    quantiles: Optional[List[float]] = None
) -> Dict[float, pd.DataFrame]
ParameterTypeDefaultDescription
X_testpd.DataFrame-Data to impute (with predictors)
quantilesList[float]NoneQuantiles at which to return predictions

It returns a dictionary mapping quantiles to DataFrames of imputed values. For numerical variables, quantile predictions are based on the normal distribution assumption. For categorical variables, predictions are sampled from the predicted probability distribution.

Setup and data preparation

Loading...
Loading...
Training set size: 353 records
Testing set size: 89 records

Simulating missing data

For this example, we’ll simulate missing data in our test set by removing the values we want to impute.

Loading...

Training and using the OLS imputer

Now we’ll train the OLS imputer and use it to impute the missing values in our test set.

Modeling these quantiles: [np.float64(0.05), np.float64(0.1), np.float64(0.15), np.float64(0.2), np.float64(0.25), np.float64(0.3), np.float64(0.35), np.float64(0.4), np.float64(0.45), np.float64(0.5), np.float64(0.55), np.float64(0.6), np.float64(0.65), np.float64(0.7), np.float64(0.75), np.float64(0.8), np.float64(0.85), np.float64(0.9), np.float64(0.95)]
Loading...

Evaluating the imputation results

Now let’s compare the imputed values with the actual values to evaluate the performance of our imputer. To understand OLS’s ability to capture variability accross quantiles let us find and plot the prediction closest to the true value across quantiles for each data point.

Loading...

This scatter plot compares actual observed values with those imputed by a OLS Linear Regression model, providing a visual assessment of imputation accuracy. Each point represents a data record, with the x-axis showing the true value and the y-axis showing the model’s predicted value. The red dashed line represents the ideal 1:1 relationship, where predictions perfectly match actual values. Most points cluster around this line, suggesting that the OLS model effectively captures the underlying linear structure of the diabetes data. However, we can see how it tends to underpredict in the upper tail of the distribution. This suggests that OLS can be a powerful method for imputing missing values when the relationship between features and the target variable is simply linear and homoscedastic, but may perform worse otherwise.

Examining quantile predictions

The OLS imputer generates quantile predictions based on the normal distribution assumption, which can help understand prediction uncertainty.

Loading...

Visualizing prediction intervals

By visualizing the prediction intervals of the model’s imputations we can better understand the uncertainty in our imputed values.

Loading...

This plot illustrates the prediction intervals generated by an OLS Linear Regression model for imputing total serum cholesterol values across ten records. For each observation, the red dot represents the median prediction (Q50), while the black dot indicates the true observed value. Vertical bars depict the model’s 40% prediction interval (Q30–Q70) in dark gray and the 80% prediction interval (Q10–Q90) in light gray. The intervals convey the model’s estimation of uncertainty, with wider intervals indicating less certainty about the imputed value. In some cases, the actual value falls within the 80% interval, suggesting that the OLS model is reasonably well-calibrated. However, the intervals tend to be vertically symmetric and relatively wide, sometimes missing the real values altogether. This reflects the linear nature of OLS: less responsive to local heteroskedasticity or skewness, and possibly limited in imputing power. Compared to Quantile Regression Forests, which can produce more adaptive and asymmetric intervals, the intervals here are more uniform in shape and spread. Overall, this plot shows that OLS is capable of performing fairly well on homocesdastic and simple linear datasets, though the fit may be quite limited in highly nonlinear settings.

Assesing the method’s performance

To check whether our model is overfitting and ensure robust results we can perform cross-validation and visualize the results.

[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.
[Parallel(n_jobs=-1)]: Done   2 out of   5 | elapsed:   13.5s remaining:   20.2s
[Parallel(n_jobs=-1)]: Done   3 out of   5 | elapsed:   13.5s remaining:    9.0s
[Parallel(n_jobs=-1)]: Done   5 out of   5 | elapsed:   13.6s finished
Quantile loss results:
           0.05      0.10      0.15      0.20      0.25  ...      0.75      0.80      0.85      0.90      0.95
train  0.003837  0.006478  0.008737  0.010719  0.012360  ...  0.014393  0.012980  0.011086  0.008605  0.005269
test   0.003877  0.006548  0.008872  0.010896  0.012535  ...  0.014515  0.013096  0.011194  0.008689  0.005352

[2 rows x 19 columns]
Loading...

Categorical variable imputation

OLS automatically handles categorical variables through random forest classification. Let’s evaluate its performance on categorical imputation tasks.

Categorical variable distribution:
risk_level
medium    150
low       148
high      144
Name: count, dtype: int64

Percentage distribution:
risk_level
medium    0.339367
low       0.334842
high      0.325792
Name: proportion, dtype: float64

Data types: {'age': dtype('float64'), 'sex': dtype('float64'), 'bmi': dtype('float64'), 'bp': dtype('float64'), 'risk_level': <StringDtype(na_value=nan)>}

Training set size: 353 records
Testing set size: 89 records
OLS model fitted for categorical variable imputation

Assessing categorical imputation performance

We can look at the accuracy of the model’s predictions to understand the quality of its categorical imputations. Cross-validation will employ log loss to evaluate the performance of the logistic regression method used.

Categorical imputation accuracy: 37.08%

Confusion matrix:
                Predicted: low  Predicted: medium  Predicted: high
Actual: low                  9                 10               11
Actual: medium               4                 20                5
Actual: high                 6                 20                4
[Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.
[Parallel(n_jobs=-1)]: Done   2 out of   5 | elapsed:    1.1s remaining:    1.6s
[Parallel(n_jobs=-1)]: Done   3 out of   5 | elapsed:    1.2s remaining:    0.8s
[Parallel(n_jobs=-1)]: Done   5 out of   5 | elapsed:    1.6s finished
Categorical imputation cross-validation results (log loss):
Mean train log loss: 1.0681
Mean test log loss: 1.0794
Loading...