The best way of solve this is using pipelines as follows:
Working example:
import pandas as pd
import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.compose import make_column_selector, make_column_transformer
from sklearn.linear_model import LogisticRegression
from sklearn.impute import SimpleImputer, KNNImputer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import plot_roc_curve
from sklearn.datasets import fetch_openml
# Load the data
X, y = fetch_openml("titanic", version=1, as_frame=True, return_X_y=True)
X.replace({None:np.nan}, inplace = True)
# Some preprocessing to correct data types and replace None with nans for pipeline imputer
X.drop(["name","home.dest"], axis = 1, inplace = True)
X["embarked"] = X["embarked"].astype("object")
X["sex"] = X["sex"].astype("object")
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=0.2)
cat_prepro = Pipeline([("imputer",SimpleImputer(strategy="most_frequent")),
("encoder",OneHotEncoder(handle_unknown = "ignore"))])
cont_prepro = Pipeline([("imputer", KNNImputer()), ("scaler",StandardScaler())])
preprocessor = make_column_transformer(
(cat_prepro,make_column_selector(dtype_include= "object")),
(cont_prepro,make_column_selector(dtype_exclude="object"))
)
model = Pipeline([("preprocessor",preprocessor),
("classifier",LogisticRegression(random_state= 1990))]).fit(X_train, y_train)
model.score(X_test,y_test)
plot_roc_curve(model,X_test,y_test);
