Inference¶
Predict on new data after training. Two paths:
| Path | When to use |
|---|---|
Load model_rndNN.joblib and call .predict() |
Scripting, notebooks, embedding predictions in a pipeline |
coremat export-predictor |
Hand a ready-made Gradio app to end users |
Load the trained pipeline and predict¶
Each round's fitted pipeline is stored at:
Results land next to the data file: with data_file_path: data/alloys.csv the run
folder is data/results/<run_name>/. paths.results_root moves it (relative to the
data folder, or an absolute path).
Loading it is all you need — the pipeline contains the fitted preprocessor and the fitted regressor:
import joblib
import pandas as pd
pipeline = joblib.load(
"data/results/yield_strength_experiment/lin__ridge/round_01/model_rnd01.joblib"
)
X_new = pd.read_csv("new_alloys.csv")
# Select only the features the pipeline was trained on
required_features = pipeline.coremat_export_meta_["features"]
y_pred = pipeline.predict(X_new[required_features])
pipeline.coremat_export_meta_["features"] is the list of columns the model was
trained on. Slice X_new with it: a missing column raises, while extra or
reordered columns are accepted silently — slicing makes sure the model sees exactly
what it was trained on and nothing else.
Target-transform caveat¶
The pipeline does not include the target transform. If you configured one
(e.g. log10 on yield_strength), the regressor was fitted on the
transformed target and pipeline.predict() returns values in transformed
space. Invert manually according to the configured transform:
import numpy as np
y_pred_original = 10 ** y_pred # for a log10 target transform
y_pred_original = np.exp(y_pred) # for an ln target transform
y_pred_original = np.expm1(y_pred) # for a log1p target transform
Each transform kind means exactly what its name says:
| Kind | Forward | Inverse |
|---|---|---|
log10 |
np.log10 |
10 ** y |
ln |
np.log |
np.exp |
log1p |
np.log1p |
np.expm1 |
yeo-johnson |
PowerTransformer |
its inverse_transform; past its asymptote the training extreme |
A bare log is rejected — the base would be ambiguous. Accepted aliases are
ln / loge / log_e, and yeo_johnson / yeojohnson. With strict: true an
unknown kind raises ValueError; with strict: false it is silently ignored,
so a config saying log trains with no target transform at all and says nothing.
If domain_policy: shift was active, a per-column offset was added before the
log and is subtracted again on inversion — in that case do not invert by hand,
use the exported bundle or Transforms.inverse_y.
If no target transform was configured, pipeline.predict() is already in the
original space. Which transform was active is recorded in the run's config
backup (data/results/<run_name>/_config/) and in the Model Report's
Reproduction block.
What the back-transformed prediction is¶
With a log10 target transform the model is fitted on the logarithm, and the prediction
is turned back with 10 ** y_pred. That gives you the typical value, not the average.
Three samples of 10, 100 and 1000 show the difference:
| average of the values | 370 |
| back-transformed prediction | 100 |
Both answer a real question. 100 is the middle sample; 370 is pulled up by the largest one.
What follows from it:
- Reading one prediction — the typical value is what you want, and MAE (the default metric weight) scores it correctly.
- Doing arithmetic with many predictions — summing them, scaling up to a batch, comparing against an average from the literature — they come out low. On a right-skewed target expect double-digit percent.
The same applies to submission.csv and to anything predicted through the exported
pipeline. Without a target transform the question does not arise.
Alternative: coremat export-predictor¶
This generates a self-contained Gradio prediction bundle for the delivered round
(best_round) — recommended when someone else should use the model through a web UI
instead of Python.
Tip
The target-transform caveat above does not apply to the bundle: it carries the fitted X and y transformers alongside the pipeline and applies them automatically. Enter feature values in raw units and read predictions in raw units.
Exporting a round other than the best round¶
By default the exported round is best_round — the delivered round, marked selected
in the round-scores CSV: the round with the fewest features whose OOF skill the best
round does not clearly beat, chosen without looking at the hold-out. Being chosen among
rounds, its OOF skill can overstate its true skill; the Final Model's Test-Skill is the
independent number. Override with --round N:
A round override is appropriate when you have a deliberate, domain-driven
reason to prefer a different feature set — e.g. an earlier round reaches
acceptable performance with features that are cheaper to measure. Do not
pick the round based on Hold-out Test metrics: that turns the test set into a
validation set and its performance estimate loses independence. The generated bundle labels any override prominently
in README_predict.md and in the Gradio app title.
Passing a round that does not exist exits with an error listing the available
rounds and the canonical best_round.
See also¶
- Use Trained Models Programmatically — access pipeline steps and TabPFN embeddings
- The Model Report's Reproduction panel shows, for each round, the estimator, features, transforms and parameters it was trained with; the delivered round carries the ★ in the metrics table