A model only creates value once it serves predictions reliably, often outside Python.
model.save_model(path, format="cbm") writes CatBoost's native binary format, and CatBoostClassifier().load_model(path) reads it back. The .cbm format keeps everything: trees, CTR tables for categorical features, feature names and parameters. Pickle also works but ties you to Python and library versions.
Other formats (format=):
"json": human-readable, for inspection or custom evaluators"onnx": for ONNX Runtime and other platforms; categorical features are not supported in ONNX export, so it suits numeric-only models"coreml"for Apple devices,"cpp"and"python"to generate standalone source code,"pmml"for PMML consumers
For serving, options include the Python package itself, the C/C++ evaluation library (libcatboostmodel) and the official Java and .NET appliers, all reading .cbm with categorical support. Prediction is fast thanks to symmetric trees; batch requests rather than predicting one row at a time.
Consistency rules:
- Feed the same columns in the same order and types as in training; categorical values as the same strings.
- Record the feature list (
model.feature_names_) and the version of CatBoost used. prediction_typematters:"Probability","Class","RawFormulaVal"(log-odds) give different numbers.
model.shrink(ntree_end=...) cuts trees for faster, smaller models; sum_models blends several models into one.
Example
import numpy as np
import pandas as pd
from catboost import CatBoostClassifier
rng = np.random.default_rng(0)
X = pd.DataFrame({"amount": rng.uniform(1, 500, 400),
"country": rng.choice(["fr", "de", "us"], 400)})
y = ((X["amount"] > 250) | (X["country"] == "us")).astype(int)
model = CatBoostClassifier(iterations=100, verbose=0, random_seed=0,
allow_writing_files=False).fit(X, y, cat_features=["country"])
model.save_model("fraud.cbm") # native, keeps CTRs
loaded = CatBoostClassifier().load_model("fraud.cbm")
row = pd.DataFrame({"amount": [120.0], "country": ["us"]})
print(np.allclose(model.predict_proba(row), loaded.predict_proba(row))) # True
print(loaded.feature_names_) # ['amount', 'country']
print(loaded.predict(row, prediction_type="RawFormulaVal").round(2)) # [3.83] log-odds
print(loaded.predict(row, prediction_type="Probability").round(3)) # [[0.021 0.979]]
num = CatBoostClassifier(iterations=50, verbose=0, allow_writing_files=False)
num.fit(X[["amount"]], y)
num.save_model("numeric.onnx", format="onnx") # numeric-only for ONNX
model.shrink(ntree_end=50)
print(model.tree_count_) # 50Remember
- save_model/load_model with .cbm keeps trees and categorical CTR tables
- Export to json, onnx (numeric only), coreml, cpp, python as needed
- Serve with the same columns, order and types as training
- Be explicit about prediction_type: Probability, Class or RawFormulaVal
Watch out for
- Exporting a model with categorical features to ONNX and expecting it to work.