Revealed preference analysis at scale — rationality scores, efficiency indices, and utility recovery. Rust engine, Python interface.
Project description
PyRevealed
Rationality scores for every user, at scale. Rust engine, Python interface.
pip install pyrevealed
What it does
Scores how consistently each user's choices align with rational utility maximization. Feed it choice data, get back per-user scores you can plug into any ML pipeline, segmentation model, or dashboard.
from pyrevealed.engine import Engine
import numpy as np
# Each user: (prices T x K, quantities T x K)
users = [(prices_i, quantities_i) for prices_i, quantities_i in user_data]
engine = Engine(metrics=["garp", "ccei", "mpi", "harp", "hm"])
results = engine.analyze_arrays(users)
for r in results:
print(r.is_garp, r.ccei, r.mpi, r.is_harp)
is_garp ccei mpi is_harp hm
False 0.847 0.023 True 18/20
True 1.000 0.000 True 20/20
False 0.791 0.041 False 15/20
Scores
| Score | Field | What it measures | Range |
|---|---|---|---|
| Consistency | is_garp |
Are choices rationalizable? (GARP) | bool |
| Efficiency | ccei |
How close to perfectly rational? (Afriat) | 0-1 |
| Exploitability | mpi |
Value left on the table per choice (Karp cycle) | 0-1 |
| Homotheticity | is_harp |
Do preferences scale with budget? | bool |
| Noise fraction | hm_consistent/hm_total |
Fraction of rationalizable choices (Houtman-Maks) | 0-1 |
| Utility recovery | utility_success |
Can latent utility be reconstructed? (Afriat LP) | bool |
| Per-obs efficiency | vei_mean |
Average efficiency across observations (Varian) | 0-1 |
Every score is a feature. Use them for fraud detection, user segmentation, A/B testing, churn prediction, or personalization.
Performance
The Rust engine (rpt-core) handles graph algorithms and LP solving via Rayon thread pool. Python handles I/O and the user-facing API.
| Users | Metrics | Time | Throughput |
|---|---|---|---|
| 1,000 | 5 | 0.1s | 10,000/s |
| 10,000 | 5 | 2s | 5,000/s |
| 100,000 | 5 | 20s | 5,000/s |
18-100x faster than pure Python. Memory stays bounded via streaming chunks.
How it works
User choice data (prices + quantities per observation)
|
v
+-----------+
| Engine | partition by user, stream in chunks
+-----+-----+
|
v
+-----------+
| Rust + | SCC decomposition -> Floyd-Warshall transitive closure
| Rayon | Karp's cycle algorithm -> HiGHS LP solver
+-----+-----+
|
v
list[EngineResult] (one per user)
Core algorithms
| Algorithm | Module | Computation |
|---|---|---|
| GARP | garp.py |
Boolean cycle detection via SCC + Floyd-Warshall |
| CCEI (AEI) | aei.py |
Binary search over efficiency levels |
| MPI | mpi.py |
Karp's max-mean-weight cycle O(T^3) |
| HARP | harp.py |
Max-product cycle in log-space |
| Houtman-Maks | mpi.py |
Greedy feedback vertex set / ILP |
| Quasilinear | quasilinear.py |
Bellman-Ford negative cycle detection |
| Utility recovery | utility.py |
Afriat LP via HiGHS |
| VEI | vei.py |
Per-observation efficiency LP |
| Menu SARP | abstract_choice.py |
Cycle detection on item-space graph |
| Attention | attention.py |
Consideration sets + graph + LP |
| Production GARP | production.py |
Profit comparison graph |
4 Choice Categories
We test whether observed choices are consistent with rational optimization — without estimating parameters. We answer "does a rational model exist?", not "which model is it?".
Test (bool) Score (0-1) Recover (vector) Structure (bool)
Budget GARP, WARP CCEI, MPI, HM Utility, CV/EV HARP, Separability
Discrete SARP, RUM LP HM (menu) Ordinal utility Congruence
Production Prod GARP Prod CCEI Tech efficiency Cost minimization
Intertemporal Exp discount — Discount delta Quasi-hyperbolic
| Category | Input format | Example domain |
|---|---|---|
| Budget | (prices T×K, quantities T×K) |
E-commerce, grocery, food delivery |
| Discrete | (menus, choices) or (menus, frequencies) |
Surveys, A/B tests, recommendations |
| Production | (input_p, input_q, output_p, output_q) |
Supply chain, manufacturing |
| Intertemporal | (amounts, dates, chosen) |
Subscriptions, savings, loyalty |
Each user is a tuple of arrays. T can vary per user:
users = [
(prices_user_0, quantities_user_0),
(prices_user_1, quantities_user_1),
...
]
results = engine.analyze_arrays(users)
Documentation
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyrevealed-0.5.1.tar.gz.
File metadata
- Download URL: pyrevealed-0.5.1.tar.gz
- Upload date:
- Size: 309.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
52a1d0a2b0eca7ec30099b90f24affb6495f2d64bbb4b03795fd64b8dbb791ff
|
|
| MD5 |
3126f4741c8c061ca662fa3cb85b811f
|
|
| BLAKE2b-256 |
9750bd4d35fc4cf2223b03d1aa781a6a729e4807192e1c73d99ef3dbdb5e40f2
|
File details
Details for the file pyrevealed-0.5.1-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: pyrevealed-0.5.1-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 2.0 MB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4247b84a49fc6753d450f01e502ae6bc80194cc6d28c4234d038f15b120bbd9
|
|
| MD5 |
ffded22705464f055e9aadfdead0176a
|
|
| BLAKE2b-256 |
5b10f503699b0233384d06d05e27bf75b7762d9366818bf59db88b1aa772bfdd
|
File details
Details for the file pyrevealed-0.5.1-cp312-cp312-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pyrevealed-0.5.1-cp312-cp312-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 2.7 MB
- Tags: CPython 3.12, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fc7e419053e214dd0e06f34a7a2cd5378a43a26ecfc55f2cfb8e1d6612ec21c0
|
|
| MD5 |
92acbf020edb6e72eb9c974e329bf0f6
|
|
| BLAKE2b-256 |
9700fd835ed98bd80fd8e0761a8528e308f9f08525d5d8df7f9c93d5d9bf101b
|
File details
Details for the file pyrevealed-0.5.1-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyrevealed-0.5.1-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
445b0cce73b2d5e144e9820d770a692171f6bd6eabe6879d081f57016ae4266a
|
|
| MD5 |
1c7cd0fd50e3aa840441918bbd113041
|
|
| BLAKE2b-256 |
906d5027861c4a24764349ccd48940ccd7a7cc4693b2d6980dc24f3a96a608c0
|
File details
Details for the file pyrevealed-0.5.1-cp312-cp312-macosx_10_12_x86_64.whl.
File metadata
- Download URL: pyrevealed-0.5.1-cp312-cp312-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.12, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c20452cd3fef40533442a2b94219cf083c4bd58736e6226b35a2e186a1528645
|
|
| MD5 |
9f041cec9dfb6a10a69eba72fe712754
|
|
| BLAKE2b-256 |
fc61d659e9772b513f631569e27a69a11bbff3ed52acc17c5cfa163bc9cfd2ba
|
File details
Details for the file pyrevealed-0.5.1-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: pyrevealed-0.5.1-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 2.0 MB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b857e3115dc46351d67626d056f25e5313b073de230744d80a5969939c8c24c9
|
|
| MD5 |
447e3e38dbf0bf990c4a9e37d32d856e
|
|
| BLAKE2b-256 |
633480a51da6b42f8882fa71ebf8957d4f656c8db6fb0516a34011d7bce654a0
|
File details
Details for the file pyrevealed-0.5.1-cp311-cp311-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pyrevealed-0.5.1-cp311-cp311-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 2.7 MB
- Tags: CPython 3.11, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27e6e46f6f7b997467ee61515027174d38a27ffe8501f46089c93c60dc558b5c
|
|
| MD5 |
bf1dfb0a8fc34bce8dffdf12825df1f9
|
|
| BLAKE2b-256 |
c8fa832065be27016a9ebbaa941ff37ea58259b1c091045852f1edecc66f0f30
|
File details
Details for the file pyrevealed-0.5.1-cp311-cp311-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyrevealed-0.5.1-cp311-cp311-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.2 MB
- Tags: CPython 3.11, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5b5dc9d606341cfe71d9d2f17fcda8ba79ccd59b535bb648118bf08712f92f5
|
|
| MD5 |
b9017a9069b5eb5350c77a60040d112f
|
|
| BLAKE2b-256 |
4a77605dbd7122a43c02f68493bb2c1111783794af4e7a625e3b6d4bb3a90150
|
File details
Details for the file pyrevealed-0.5.1-cp311-cp311-macosx_10_12_x86_64.whl.
File metadata
- Download URL: pyrevealed-0.5.1-cp311-cp311-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.11, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf2a1ac67c312cc3e362e21f67fc7471a1effdd67ebcce76a00fa5e2e650a4f5
|
|
| MD5 |
ee40dfcc6107507358d790c223a7f2e9
|
|
| BLAKE2b-256 |
f61947785e3510b30040bfb6971c66f0b77f2f11027c2b5e8418dafd0bbf83f9
|
File details
Details for the file pyrevealed-0.5.1-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: pyrevealed-0.5.1-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 2.0 MB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
101c94186bb9277939eecc856f550c76b962679e55b493453aacb3701c0fab99
|
|
| MD5 |
86602a0f7300a93b573340b171f53d75
|
|
| BLAKE2b-256 |
93ff1b88028df4f85b38f5a52b9e816cacfeb8e47d8140aff8c6ba7a891fca61
|
File details
Details for the file pyrevealed-0.5.1-cp310-cp310-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pyrevealed-0.5.1-cp310-cp310-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 2.7 MB
- Tags: CPython 3.10, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ae4db54ea925e19a18afc05945e9b303d9b7fa070d2660611cb412d83720d36
|
|
| MD5 |
e5d3faeacb96917014b0ac73e64bccfa
|
|
| BLAKE2b-256 |
f741d286870b5d044b50c65805f28a0e8bd9e8223e553ddaa00813ec18c4b2b4
|
File details
Details for the file pyrevealed-0.5.1-cp310-cp310-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyrevealed-0.5.1-cp310-cp310-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.10, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ff846bc0bce42d25b499e7306aec69e560d4f4ecb34973d6e327b7085162674e
|
|
| MD5 |
59e6bc43233828054c883f2d831bcf40
|
|
| BLAKE2b-256 |
4ad3c10c694e7684c46624a8d9b723b0f9266ebb47d9829934b71c64900ff4e8
|
File details
Details for the file pyrevealed-0.5.1-cp310-cp310-macosx_10_12_x86_64.whl.
File metadata
- Download URL: pyrevealed-0.5.1-cp310-cp310-macosx_10_12_x86_64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.10, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: maturin/1.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
09af592de345c418868505904714c2b06a9acc9d88237ecaa89137e414fc796b
|
|
| MD5 |
47fc95474753edb200f45044e2edb993
|
|
| BLAKE2b-256 |
ca0f765f70efd6c80f123ac590dc9d5758a4dc22d31fc8aef51039b9865967e2
|