A fitted scikit-learn estimator often needs to move from training code into a later scoring job without using a raw pickle artifact. skops.io saves supported estimators in a format that can be inspected for unknown types before Python reconstructs the object.

The saved artifact still belongs to the Python stack that created it. Keep the training and loading environments on matching scikit-learn, NumPy, SciPy, and skops versions, and store the training code or dependency lock file with the model when the artifact is shared.

A built-in HistGradientBoostingClassifier on the Iris dataset keeps the trust review at an empty extra-type list. Models that contain third-party estimators or custom components can report type names; inspect those names against the training code and trust only classes or functions expected in that artifact.

Steps to save and load a scikit-learn model with skops:

  1. Install scikit-learn and skops in the Python environment that will train and load the model.
    $ python -m pip install scikit-learn skops

    Use the same virtual environment, container image, or dependency lock for training and loading when the artifact will be reused later.

  2. Create the smoke script that trains an estimator, saves a .skops file, inspects unknown types, and reloads only after the review is empty.
    save-load-skops.py
    from pathlib import Path
     
    import skops.io as sio
    from sklearn.datasets import load_iris
    from sklearn.ensemble import HistGradientBoostingClassifier
    from sklearn.model_selection import train_test_split
     
     
    model_path = Path("iris-hist-gradient.skops")
     
    X, y = load_iris(return_X_y=True)
    X_train, X_test, y_train, _ = train_test_split(
        X,
        y,
        random_state=42,
        stratify=y,
    )
     
    model = HistGradientBoostingClassifier(random_state=42).fit(X_train, y_train)
    expected = model.predict(X_test[:5]).tolist()
    sio.dump(model, model_path)
     
    unknown_types = sio.get_untrusted_types(file=model_path)
    print(f"artifact: {model_path}")
    print(f"untrusted types: {unknown_types}")
     
    if unknown_types:
        raise SystemExit("Review these types before loading the artifact.")
     
    trusted_types = []
    loaded = sio.load(model_path, trusted=trusted_types)
    actual = loaded.predict(X_test[:5]).tolist()
     
    print(f"expected predictions: {expected}")
    print(f"loaded predictions:   {actual}")
    print(f"predictions match: {actual == expected}")

    If unknown_types prints names, compare them with the model training code and set trusted_types to only the reviewed names before calling sio.load().

  3. Run the smoke script and confirm the loaded model reproduces the reference predictions.
    $ python save-load-skops.py
    artifact: iris-hist-gradient.skops
    untrusted types: []
    expected predictions: [0, 1, 1, 1, 0]
    loaded predictions:   [0, 1, 1, 1, 0]
    predictions match: True

    The empty untrusted types list means skops did not require extra user-trusted classes beyond its defaults for this built-in estimator.

  4. Remove the smoke-test artifact when the check was only a local validation run.
    $ rm iris-hist-gradient.skops

    Keep real .skops files only in a controlled artifact store. Loading a model from an untrusted source is still a security decision, even when the format is designed for inspection.