> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hollerith.monarcha.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# How Hollerith works

> No training required

```python theme={null}
clf = Hollerith()
clf.fit(train, target="churned")
preds = clf.predict(test)
```

The shape is scikit-learn. What happens underneath is not.

## fit does not train

No gradients are computed. No weights change. `fit` sends your labeled table to the model
and returns a handle to it.

The model was pretrained once, by us, on a very large number of tables. It did not learn any
particular relationship between columns — it learned how to read a table and infer the
relationships inside it.

Your table becomes the context the model reads while it predicts. Closer to handing someone
a reference sheet than making them study for the exam.

<img className="block dark:hidden" src="https://mintcdn.com/monarcha-53b27419/8XBoJyUBLB_e0wrZ/images/how-hollerith-works-light.svg?fit=max&auto=format&n=8XBoJyUBLB_e0wrZ&q=85&s=5c6842ec5c45a052db35fb49ccf211ba" alt="The usual loop discards the table after training; Hollerith reads the same table on every call." width="720" height="348" data-path="images/how-hollerith-works-light.svg" />

<img className="hidden dark:block" src="https://mintcdn.com/monarcha-53b27419/8XBoJyUBLB_e0wrZ/images/how-hollerith-works-dark.svg?fit=max&auto=format&n=8XBoJyUBLB_e0wrZ&q=85&s=b845ecd05d2f362c0a7c0a56f9778e0d" alt="The usual loop discards the table after training; Hollerith reads the same table on every call." width="720" height="348" data-path="images/how-hollerith-works-dark.svg" />

## Nothing to tune

There is no learning rate, no tree depth, no regularization term, no early-stopping patience.
There is no optimization loop for those knobs to sit on.

```python theme={null}
Hollerith()                      # that is the whole configuration
```

## No world knowledge

Like a language model reading a prompt, Hollerith conditions on what you put in front of it.
Unlike a language model, it has nothing stored to fall back on.

It does not know that `churn` means a customer left, or that a `price` of `-40` is probably a
refund. It knows the shape of tables in general, and the one table you handed it.

Two consequences:

* **Signal has to be in the columns.** Ratios, aggregates and joins that encode domain
  knowledge help here for the same reason they help gradient boosting.
* **Column names carry no meaning.** Renaming `x7` to `days_since_last_login` will not change
  a prediction.

## The cost moves to prediction time

Training cost does not disappear. It moves.

Your table is read on every call, so its size is a cost you pay every time rather than once
up front. Time and price both scale with how much table the model reads.

Two things to internalize before building on this:

* **`fit` is a real job.** It runs on a GPU, takes seconds to minutes, and bills the rows you
  send. "No training" is a claim about gradients, not about cost or latency.
* **More context is not better.** Rows that carry no signal cost latency and money and buy
  nothing. The most informative table usually beats the largest one.

## Fit once, predict many

`fit` returns a reusable artifact that lives on our side for 7 days. Each `predict`
against it sends only the rows you want scored.

```python theme={null}
clf.fit(train, target="churned")   # once
clf.predict(batch_1)               # sends batch_1 only
clf.predict(batch_2)               # sends batch_2 only
```

Expiry, resuming from another process, and the ways you can accidentally skip it are in
[The fitted context](/concepts/fitted-context).

## What the model reads

Numbers and categories are read as they are. Missing values are read as missing — they are
information, not something to impute first.

Free text and dates are accepted but read as categories. The model sees that two rows share a
value, not what the value means. A `signup_date` tells it which rows signed up together, not
which signed up earlier.

The task is inferred from your target. A whole-number target with 20 or fewer distinct values is
treated as **classification** — right for a 1–5 rating, wrong for a small count.

```python theme={null}
clf.fit(df, target="units_sold", task="regression")   # override when it guesses wrong
```

Row-wise `predict` has no notion of time. Time-indexed targets belong in
[Forecast](/guides/forecasting).

## Re-fit when your data moves

Predictions assume the rows you score look like the rows you fit on. A new product line or a
pricing change breaks that, and the model has no way to tell you.

Re-fitting costs one call. Do it often rather than building drift detection you do not need
yet.

## Next

* [Quickstart](/quickstart) — first prediction in about a minute
* [The fitted context](/concepts/fitted-context) — fit once, predict many
* [Preparing your table](/guides/preparing-your-table) — dtypes, targets, and the traps
* [The model](/reference/model) — where it wins, and where it does not
