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

# Rate submissions with a rater

> Load one carrier's rater from a path or the catalog, rate submissions, and read the results in pandas or as exact values.

Rate submissions with one carrier's rater, and read each premium and status.

[Install Relativities and download the example data](/relativities/setup) before running this page.

```python theme={null}
from pathlib import Path

import pandas as pd

from relativities import Dataset, Rater

rater = Rater.load(Path("relativities-examples/example-auto.zip"))
submissions = pd.DataFrame(
    {
        "submission_id": ["S-1", "S-2", "S-3"],
        "drivers": [[{"age": 42}], [{"age": 19}], [{"age": 50}]],
        "vehicles": [[{"annual_mileage": 5_000}], [{"annual_mileage": 12_000}], [{"annual_mileage": 45_000}]],
        "coverages": [{"collision": False}, {"collision": True}, {"collision": False}],
    }
)
results = rater.rate(Dataset.from_pandas(submissions, key="submission_id"))
results  # RatingResult(3 rows: 2 succeeded, 1 refused)
```

The rater is the synthetic example in `relativities-examples/example-auto.zip`. Its premium
is for a twelve-month term. It refuses a vehicle over 30,000 miles a year.

```mermaid theme={null}
flowchart LR
  load["Rater.load: a Path or a catalog ID"] --> rate["rater.rate"]
  rate --> result["RatingResult: one row per submission"]
  result --> pandas["to_pandas for analysis"]
  result --> rows["rows for exact values"]
```

## Load a rater

* To load a local bundle, pass a `Path` to [`Rater.load`](/relativities/reference/relativities#rater).
* To load a catalog rater, pass its ID as a string, with `EFFECTIVE_API_KEY` set.

```python theme={null}
catalog_id = "your-rater-id"  # replace with an ID available to your API key
latest = Rater.load(catalog_id)
bundle_id = latest.bundle_id
```

The first catalog load downloads the bundle, verifies it and caches it by its `bundle_id`.
[Bundles and exact rating](/relativities/explanation/bundles-and-exact-rating) describes the checks.

## Pin a revision

To load a numbered release, pass `revision=` a whole number. To rerun a rating exactly, pass
`revision=` the `bundle_id`.

```python theme={null}
fourth = Rater.load(catalog_id, revision=4)  # choose a published release number
exact = Rater.load(
    catalog_id,
    revision=bundle_id,
    local_files_only=True,  # read the cache only
)
exact.bundle_id == latest.bundle_id  # True
```

A cached `bundle_id` loads offline with `local_files_only=True`.

## Download a rater to a folder

To keep a rater next to your work, call [`Rater.download`](/relativities/reference/relativities#rater)
with a path. Then load it from that path.

```python theme={null}
folder = Rater.download(catalog_id, Path("raters/study-rater"), revision=bundle_id)
sorted(path.name for path in folder.iterdir())  # ['rater-manifest.json', 'rater.py', 'rater.rsl']
local = Rater.load(folder)  # offline
local.bundle_id == latest.bundle_id  # True
```

* A path that ends in `.zip` gets the bundle archive. Any other path gets a folder with the
  rater's RSL source, its tables and, for a program, its `program/` folder.
* The bundle is verified first. Then it goes to a new path or an empty folder, and the call
  raises `FileExistsError` for any other path.
* `revision=` pins the download, as it does for `Rater.load`.

## List the fields a rater accepts

`rater.inputs` lists each field a submission can give, one row per field. `rater.outputs` lists
the outcomes that `rate` returns. Both use the type names of a book's [`Schema`](/relativities/reference/book-schema).

```python theme={null}
rater.inputs.values.tolist()
# [['coverages.collision', 'bool', '', '', True, ''],
#  ['drivers[].age', 'int', '', '16 to 99', True, ''],
#  ['vehicles[].annual_mileage', 'int', '', '0 to 30000', True, '']]
rater.outputs["path"].tolist()  # ['annual_premium']
```

`path` names the field as `explain` does, with `[]` for each list. `values` gives the allowed
values or range, and the default when the rater has one. `input_schema` is the same contract as
JSON Schema.

## Rate one submission or a list

* To rate one submission, pass a dict.
* To rate several submissions, pass a list. Each row ID is the list position.

```python theme={null}
one = rater.rate({"drivers": [{"age": 30}], "vehicles": [{"annual_mileage": 9_000}], "coverages": {"collision": True}})
one.to_pandas()["annual_premium"].item()  # 650.0
several = rater.rate([{"drivers": [{"age": 30}], "vehicles": [{"annual_mileage": 9_000}], "coverages": {"collision": False}}] * 2)
several.to_pandas()["annual_premium"].tolist()  # [500.0, 500.0]
```

The dict holds the fields of the rater's root record, `Policy`.

## Rate a dataset

To keep your own IDs on the results, build a `Dataset` with a `key` column. Then rate the dataset,
as the first example does.

* The `key` column stays on every result row. The rater receives the other columns.
* A `NaN`, `None` or `NaT` cell leaves its field out of the rater's input.
* A date becomes ISO 8601 text.

## Read the results in pandas

Call `to_pandas()` for one row per submission, with float64 outcomes.

```python theme={null}
frame = results.to_pandas()
frame.columns.tolist()  # ['submission_id', 'status', 'reason_code', 'reason', 'annual_premium']
frame["annual_premium"].tolist()  # [400.0, 812.5, nan]
frame.groupby("reason_code").size()  # MILEAGE_OUT_OF_RANGE: 1
frame.loc[frame["status"] == "succeeded", "annual_premium"].mean()  # 606.25
```

S-3 has the status `refused` with the rule's code and message. Its premium is `NaN`, so the mean
skips it. [Results](/relativities/reference/results) lists every column and status.

Report the two successes and one refusal with that mean. It describes the successfully rated population on this rater's coverage basis.

## Read exact values

To read exact `Decimal` values, use `results.rows`.

```python theme={null}
results.rows[1].outputs["Policy"]["annual_premium"]  # Decimal('812.5')
results.rows[2].error.code  # 'MILEAGE_OUT_OF_RANGE'
```

Each row holds the root record's fields. Nested records are lists and dicts. To list the
calculations behind one premium, see [Explain a premium](/relativities/how-to/explain-a-premium).

## Release the raters

Close each rater to release its runtime.

```python theme={null}
for loaded in (rater, latest, fourth, exact, local):
    loaded.close()
```

`with Rater.load(...) as rater:` closes the rater at the end of the block.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.