Skip to main content
One labeled table, one column to predict. fit stages the table, predict scores new rows against it. predict returns a plain Python list, row-aligned with the frame you passed in. Not an array and not a Series — slice it, iterate it, or zip it with your row ids. risk_label holds 0 and 1, so the labels come back as integers. A whole-number target with 20 or fewer distinct values is read as classification, which is what you want here. See Preparing your table for when that inference is wrong.

Multi-class is the same call

Nothing about the call changes when the target holds three labels instead of two. The distinct values in your target column are the only difference.
classes_ is the sorted set of labels seen at fit time, and exists for classification only. A client resumed with Hollerith.from_fitted_context() has none until predict_proba runs.

Class probabilities

A NumPy array of float64, one row per input row and one column per class, ordered to match classes_. Index columns through classes_ rather than by a position you assumed. Reach for probabilities when a label is not enough. The fraud sample is 10% positive, and a label collapses an imbalanced call into a threshold somebody else picked for you.

predict_proba rewrites classes_

predict_proba overwrites classes_ with the ordering the server returned. Read the attribute again after the call instead of trusting an order you captured before it.

Picking an operating point

A cutoff of 0.5 is a choice, not a default worth keeping. Move it down when a missed fraud costs more than a false alarm, and up when reviewer time is the scarce thing. Ranking avoids the question. If a team can work fifty cases a day, send the fifty highest-scoring rows and let the cutoff land where it lands.

The ceiling is 160 classes

fit counts the distinct values in your target before anything is uploaded. Past 160 it raises a ValidationError with code dataset_too_large, and no job is submitted. There is no automatic fallback. Nothing is grouped, bucketed or truncated for you, so a target with 400 product codes has to become a smaller target first:
  • Group the tail. Keep the labels that carry volume, fold the rest into one other.
  • Predict a coarser level. Category rather than product code, region rather than store.
  • Split the problem. One model per segment, each with a target inside the ceiling.

When the task is inferred wrong

Hollerith reads the task from your target column. A non-numeric or boolean target is classification, and so is an integer target with 20 or fewer distinct values. Integer class ids above that count are read as magnitudes instead. Pass task= whenever the inference goes the wrong way.

Good candidates

A column that already exists in your table, and rows that look like the rows you will score:
  • Mixed-type, wide rows. Numbers, categories and missing values are read as they are.
  • Imbalanced targets. predict_proba plus a threshold you set beats a fixed label.
  • Tables that move weekly. Re-fitting is one call, so drift is cheaper to fix than to detect.
  • Small labeled sets. A few hundred labeled rows is a working starting point.

When this will not help

  • The signal lives in free text. Text and dates are ordinal-encoded, so the model sees that two rows share a value, not what the value means.
  • The target is time-indexed. Row-wise predict has no notion of order — see Forecast.
  • More than 160 classes. The call fails rather than degrading.
  • A pipeline you have already tuned. A gradient boosting model somebody spent weeks on may still win on one stable table. Measure both before you move.

Before you ship

  • task_ is classification, not an inference you did not intend.
  • classes_ re-read after any predict_proba call.
  • The threshold written down, with the cost that chose it.
  • evaluate() run once on the labeled table you fit on.
  • fitted_context_expires_at_ checked if you predict on a schedule.

Next