Evaluating and Revalidating Models¶
Once a predictor is trained, there are two ways to check how well it's actually performing:
evaluate()— score the predictor against labeled data you supply (a holdout set, new labeled data, a re-upload of your original test split). This is the primary way to re-test a model.coverage()— check "answer only when you know" selective-prediction metrics. Depending on training state, this may return the metrics captured during training rather than a fresh live re-run — see the caveat below before relying on it as a re-test.
Re-testing with evaluate()¶
evaluate() runs your records through the trained model and scores the predictions against your ground-truth labels — all on the server, using the same metric code the predictor itself reports from. You don't reimplement scoring client-side, so the positive class, thresholds, and metric conventions always match what the model reports elsewhere (training metrics, predict() results, etc).
from featrixsphere.api import FeatrixSphere
featrix = FeatrixSphere()
fm = featrix.foundational_model("your-session-id")
predictor = fm.list_predictors()[0]
# From a labeled holdout DataFrame
metrics = predictor.evaluate(holdout_df, labels="churned")
print(metrics["accuracy"], metrics["auc"], metrics["f1"])
Or pass records and labels explicitly:
metrics = predictor.evaluate(
records=[{"age": 35, "income": 50000, "city": "NYC"}, ...],
labels=["yes", "no", ...],
)
What you get back:
| Task type | Metrics |
|---|---|
| Classification | accuracy, f1, auc (plus f1_error / auc_error if the positive class can't be resolved) |
| Regression | r2, rmse, mae |
When to use this: any time you want to know "how does this model actually do on labeled data" — a re-uploaded original test split, a fresh batch of labeled records, or data collected since deployment. This is the call to reach for when you want a genuine, on-demand re-validation.
Selective-prediction coverage with coverage()¶
coverage() reports "answer only when you know" metrics — how much of your data the model can answer confidently at various operating points, and the accuracy/precision/recall lift you get by abstaining on the rest.
# All four strategy views at once
cov = predictor.coverage()
if not cov.get('intent_feasible', True):
print(f"Warning: {cov['intent_feasibility_reason']}")
# Don't auto-deploy without acknowledging this
for key, view in cov['strategies'].items():
print(f"{view['label']}: coverage={view['coverage']:.0%}, AUC={view['covered_auc']:.3f}")
# A single strategy
pos = predictor.coverage(strategy="only_on_strong_positives")
print(f"Caught {pos['true_positives_caught']}/{pos['true_positives_total']} positives")
Strategies:
| Strategy | What it optimizes |
|---|---|
everything |
Act on every row, no abstention (baseline) |
only_when_sure |
Max AUC on the answered set; demurred rows feed a human-in-the-loop queue |
only_on_strong_positives |
Max precision when predicting positive |
only_on_strong_negatives |
Max NPV when predicting negative |
Each view returns coverage, covered_auc, full_auc, auc_lift, confidence_threshold, n_covered, n_total, and label. Always check intent_feasible — if False, the framework couldn't honor the intent contract you trained with (e.g. a precision floor), and the returned operating point is a max-AUC fallback, not what you asked for.
Caveat: this may return cached training-time numbers, not a live re-run¶
Internally, coverage() recomputes metrics by pulling the model's own stored validation set and re-running predictions against it — a genuine re-validation, not a client-side estimate. However, if the predictor already has selective-prediction metrics captured from training, the endpoint returns those cached numbers by default rather than recomputing. There is currently no SDK parameter to force a fresh live re-run — coverage() will transparently use whichever result is available.
In practice: treat coverage() as "the selective-prediction picture for this model" rather than an on-demand re-test tool. If you need a guaranteed fresh score against specific data, use evaluate().
Which one should I use?¶
| Goal | Call |
|---|---|
| "Does this model still perform well on labeled data I have?" | evaluate() |
| "What's my model's answer-only-when-confident tradeoff?" | coverage() |
| "I need a guaranteed fresh recomputation, not cached numbers" | evaluate() |
Next Steps¶
- Running Predictions for single/batch prediction and confidence interpretation
- Safety and Quality for guardrails and training metric thresholds
- Cost-Optimal Thresholds for background on selective prediction and intent contracts