Metadata-Version: 2.4
Name: relativities
Version: 0.1.0
Summary: Local rating and portfolio analysis for actuaries
Author: EffectiveAI
License-Expression: LicenseRef-Proprietary
License-File: LICENSE
Requires-Dist: httpx>=0.28,<1
Requires-Dist: pydantic>=2.12,<3
Requires-Dist: rslc==0.3.0
Requires-Dist: numpy>=2,<3 ; extra == 'models'
Requires-Dist: scipy>=1.15,<2 ; extra == 'models'
Requires-Dist: statsmodels>=0.14.6,<0.15 ; extra == 'models'
Requires-Dist: pandas>=2.2,<4 ; extra == 'pandas'
Requires-Dist: matplotlib>=3.10,<4 ; extra == 'plot'
Requires-Python: >=3.12
Provides-Extra: models
Provides-Extra: pandas
Provides-Extra: plot
Description-Content-Type: text/markdown

# Relativities

Local actuarial models, rating pipelines, and population analysis in Python.
Load a versioned model, apply it to one submission or a dataset, and inspect
premiums, distributions, refusals, and weighted summaries. The interface takes
inspiration from Hugging Face's model/pipeline pattern; actuarial assumptions
remain explicit.

Both catalog raters and Python-authored RSL execute locally in Rust. The
[native authoring guide](../docs/relativities/native-authoring.md) and
[Progressive policy-term example](examples/progressive_policy_term.py) describe
the smaller set of rules currently expressible through the Python builder.

This is an initial implementation, not a published PyPI release. Python 3.12+
is required. The proposed proprietary terms are in [LICENSE](LICENSE).
The [release runbook](../docs/relativities/releasing.md) describes the packaging,
platform validation and separate approval required before public publication.

## Install

From the repository root:

```sh
python -m pip install ./effectiveai-tools/raters/rslc ./relativities
# Optional dataframe, statistical modeling, and plotting support:
python -m pip install ./effectiveai-tools/raters/rslc './relativities[pandas,models,plot]'
```

The package installs independently of Effective's application packages. Its
required dependencies are HTTPX, Pydantic and the RSLC native runtime. Building
RSLC from source needs Rust 1.92+ and a C++ compiler; the isolated build installs
CMake. Installing built wheels needs no compiler. Local execution needs no
running server.

## Rate offline

```python
from operator import itemgetter
from relativities import Population, load_dataset, pipeline

households = load_dataset("example-auto-households")
population = Population(households, unit="household", weights="weight")

with pipeline(
    "rating",
    rater="builtin://example-auto",
    preprocess=itemgetter("submission"),
) as rate:
    ratings = rate(households)

summary = ratings.summarize(
    output="/Policy/annual_premium",
    weights=population.weights,
)
print(summary.mean, summary.quantile(0.95))
print(summary.rated_weight, summary.unrated_weight)
print(ratings.refusals)
```

The six synthetic households include five successful premiums and one deliberate
mileage refusal. Bundled examples are instructional, not observed experience or
representative market samples. `list_datasets()` describes the available
resources and their content revisions.

One native submission, a list, and a `Dataset` all produce a `RatingResult`.
Dataset IDs survive preprocessing; lists receive positional IDs. The result
retains every input, including mapping failures, refusals, and execution failures.
Nested drivers and vehicles remain part of one submission.
`ratings.refusals` contains business rejections; `ratings.invalid_inputs`
contains malformed submissions. `ratings.failures` includes both and runtime failures.

Finite numeric results preserve exact decimals. Non-terminating rational
calculations remain `{"$rational": "p/q"}` objects rather than silently rounded
numbers. Decimal summaries require finite numeric outputs, such as a rounded premium.

`Population` adds explicit representation weights. Weights align by ID and must
be finite and nonnegative, with positive total weight. Means and quantiles are
conditional on the successfully rated weight, which is reported alongside the
unrated weight. Quantiles use the inverse weighted empirical CDF. Population
weights are separate from policy exposure and statistical fitting weights.

## Catalog access and compatibility

```python
from relativities import Hub

with Hub(profile="canary") as hub:
    catalog = hub.list_raters()
    print([(row["raterId"], row["bundleId"]) for row in catalog])
```

This uses an existing Effective CLI schema-v2 profile without depending on the
CLI. Alternatively, pass `hub=Hub(base_url=..., api_key=...)`; environment
credentials use `EFFECTIVE_API_BASE_URL` and `EFFECTIVE_API_KEY`. Credentials
are bound to their configured origin. A configured profile takes precedence
unless `EFFECTIVE_PREFER_ENV_VARS=true`.

For example, this published Progressive AZ auto bundle runs natively:

```python
with Rater.load(
    "progressive-preferred-az-ppa",
    revision="724d07d7353bcf69f8da5a841a2ce255f967e6df26571b83a4e4add08b58a84a",
    profile="canary",
) as rater:
    print(rater.input_schema)  # Use this carrier's submission shape.
```

`examples/canary.py <submission.json>` loads that pinned release and rates the
provided submission locally. String catalog IDs cannot be shadowed
by local files; use a `Path` or explicit `./`, `../`, `/`, or `~` prefix to load locally.

Loading may download an immutable rater bundle. Rating, prediction,
evaluation, and comparison then run locally. Inputs and results are never
implicitly uploaded. Downloaded revisions are cached by origin, rater ID, and
bundle ID; `Hub(base_url=..., offline=True)` uses pinned cached artifacts
without credentials or network access.

The loader checks bundle integrity, then checks and executes the RSL in Rust.
It never executes the bundled `rater.py`. This version supports
`rslc-python-rater/2`, hash version 7, with RSL 0.4 source. Older source raises
`BundleError` with migration guidance; there is no generated-Python fallback.

The canary catalog still contains older RSL revisions. They must be migrated,
checked against their published premiums and refusals, and published before this
runtime can load them. The repository-only E&O fixture records expectations from
an older Imperium release and is excluded from public distributions. The
Progressive example above uses a published RSL 0.4
bundle without modifying or migrating it.

## Fit a frequency model

Requires the `models` extra:

```python
from relativities import Dataset, LossModel, evaluate, load_dataset, pipeline

experience = load_dataset("example-claims")
training = Dataset([row for _, row in experience.iter_rows() if row["split"] == "train"])
holdout = Dataset([row for _, row in experience.iter_rows() if row["split"] == "test"])

frequency = LossModel(
    family="poisson",
    features=("driver_age",),
    target="claim_count",
    exposure="exposure",
    unit="claims over supplied exposure",
).fit(training)

predictions = pipeline("loss", model=frequency)(holdout)
counts = predictions.distributions["claim_count"]
print(counts.mean())
print(counts.survival(2))  # P(N > 2) for each record, conditional on the fitted model
print(evaluate(frequency, data=holdout).summary())
```

Initial statistical support is deliberately bounded: Poisson counts with an
optional exposure offset and Gamma positive individual claim severity. Both use
a log link, an intercept, and explicit numeric predictors. Fitting is unweighted
and returns a new model. There is no inferred categorical encoding, aggregate
loss model, parameter uncertainty, or portfolio dependence model. Conditional
loss quantiles are not confidence intervals, and summing individual quantiles
does not produce a portfolio quantile.

Statistical models save as validated JSON; raters save as verified bundle
directories. Saves refuse existing artifacts; use a new path for a new revision.
`Rater.push_to_hub(...)` explicitly uploads a model artifact only;
it does not create or move a release. Remote statistical model publication,
remote datasets, studies, projects, and notebook synchronization are outside
this implementation.

See the repository's [complete snippets](../docs/relativities/snippets.md) and
runnable [rating](examples/rating.py) and [canary](examples/canary.py) examples.
For development and verification, see [CONTRIBUTING.md](CONTRIBUTING.md).
