Decision Making¶
online_cp.decision.UtilityFunction
¶
Utility function bundled with its decision space.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
callable
|
A function |
required |
decisions
|
sequence
|
The set of available decisions (the decision space D). |
required |
Examples:
>>> utility = UtilityFunction(lambda x, y, d: -(y - d)**2,
... decisions=[0.0, 0.5, 1.0, 1.5, 2.0])
>>> utility(None, 1.0, 0.5)
-0.25
Source code in src/online_cp/decision.py
online_cp.decision.cps_expected_utilities(cpd, utility: UtilityFunction, x: Any, tau: float = 0.5) -> dict[Any, float]
¶
Compute expected utility under a CPD for each decision (Vovk & Bendtsen 2018).
For each decision d in utility.decisions, computes:
where \(\Delta Q_\tau(C_j)\) is the probability mass at critical point \(C_j\) under randomisation parameter \(\tau\).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cpd
|
ConformalPredictiveDistributionFunction
|
A conformal predictive distribution object with attributes |
required |
utility
|
UtilityFunction
|
Utility function with decision space. |
required |
x
|
any
|
Features of the test object (passed to utility). |
required |
tau
|
float
|
Randomisation parameter in [0, 1]. |
0.5
|
Returns:
| Type | Description |
|---|---|
dict
|
Mapping from each decision to its expected utility (float). |
Source code in src/online_cp/decision.py
online_cp.decision.cps_decision(cpd, utility: UtilityFunction, x: Any, tau: float = 0.5) -> Any
¶
Select optimal decision by maximising expected utility under a label-CPD.
This is the naive approach: a single CPD is trained on raw labels, and expected utility is computed by weighting U(x, C_j, d) by the CPD masses. Practical for large or continuous decision spaces.
For the exact Vovk & Bendtsen (2018) Algorithm 1 (one CPD per decision,
trained on utility-transformed labels), use
:class:ConformalPredictiveDecisionMaker.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cpd
|
ConformalPredictiveDistributionFunction
|
Conformal predictive distribution. |
required |
utility
|
UtilityFunction
|
Utility function with decision space. |
required |
x
|
any
|
Features of the test object. |
required |
tau
|
float
|
Randomisation parameter in [0, 1]. |
0.5
|
Returns:
| Type | Description |
|---|---|
any
|
The optimal decision. |
Source code in src/online_cp/decision.py
online_cp.decision.venn_expected_utilities(venn_pred, utility: UtilityFunction, x: Any) -> dict[Any, NDArray[np.floating]]
¶
Compute expected utility under each Venn hypothesis for each decision.
For each decision d and hypothesis v:
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
venn_pred
|
VennPrediction
|
Multiprobability prediction with |
required |
utility
|
UtilityFunction
|
Utility function with decision space. |
required |
x
|
any
|
Features of the test object (passed to utility). |
required |
Returns:
| Type | Description |
|---|---|
dict
|
Mapping from each decision to an ndarray of shape (|Y|,) giving the expected utility under each hypothesis. |
Source code in src/online_cp/decision.py
online_cp.decision.venn_decision(venn_pred, utility: UtilityFunction, x: Any, criterion: str = 'utility', alpha: float = 0.0) -> Any
¶
Select optimal decision under Venn multiprobability (Venn-PDMS).
Computes expected utilities under each Venn hypothesis, then applies one of two decision criterion families:
"utility"(α-utility): score(d) = α·upper + (1−α)·lower. α=0 is maximin, α=1 is maximax, α=0.5 is midpoint."regret"(α-regret): minimise the α-weighted regret. α=0 is minimax regret, α=1 is minimin regret.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
venn_pred
|
VennPrediction
|
Multiprobability prediction. |
required |
utility
|
UtilityFunction
|
Utility function with decision space. |
required |
x
|
any
|
Features of the test object. |
required |
criterion
|
str
|
One of |
"utility"
|
alpha
|
float
|
Optimism index in [0, 1]. α=0 is pessimistic (default). |
0.0
|
Returns:
| Type | Description |
|---|---|
any
|
The optimal decision. |
Source code in src/online_cp/decision.py
online_cp.decision.alpha_utility(expectations: dict[Any, float | NDArray | tuple], alpha: float = 0.0) -> Any
¶
α-utility criterion: Hurwicz-weighted expected utility.
For each decision d, the score is:
score(d) = α · upper(E[U|d]) + (1 − α) · lower(E[U|d])
Special cases:
- α = 0: maximin (pessimistic — maximise worst-case utility)
- α = 1: maximax (optimistic — maximise best-case utility)
- α = 0.5: midpoint (average of best/worst case)
When expectations are scalars (point case), all α values give the same result (maximize).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
expectations
|
dict
|
Mapping from decision to expected utility. Values can be: scalars (point), ndarrays (one per hypothesis), or tuples (lo, hi). |
required |
alpha
|
float
|
Optimism index in [0, 1] (0 = pessimistic, 1 = optimistic). |
0.0
|
Returns:
| Type | Description |
|---|---|
any
|
The optimal decision. |
Source code in src/online_cp/decision.py
online_cp.decision.alpha_regret(expectations: dict[Any, NDArray | tuple], alpha: float = 0.0) -> Any
¶
α-regret criterion: Hurwicz-weighted regret minimisation.
For each scenario/hypothesis v, the regret of decision d is
max_{d'} E_v[U(d')] - E_v[U(d)]. The score for each decision is:
score(d) = α · min_v R_v(d) + (1 − α) · max_v R_v(d)
We select the decision minimising this score.
Special cases:
- α = 0: minimax regret (pessimistic — minimise worst-case regret)
- α = 1: minimin regret (optimistic — minimise best-case regret)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
expectations
|
dict
|
Mapping from decision to imprecise expectations (ndarray or tuple). |
required |
alpha
|
float
|
Optimism index in [0, 1] (0 = pessimistic, 1 = optimistic). |
0.0
|
Returns:
| Type | Description |
|---|---|
any
|
The decision minimising the α-regret score. |
Source code in src/online_cp/decision.py
online_cp.decision.ConformalPredictiveDecisionMaker
¶
Bases: SerializableMixin
Conformal Predictive Decision Making (Vovk & Bendtsen 2018, Algorithm 1).
Maintains one conformal predictive system per decision.
Each model is trained on utility-transformed labels:
(x_i, U(x_i, y_i, d)) for the corresponding decision d.
At prediction time, the conformal mean of each utility-CPD gives the expected utility of that decision; the decision with highest expected utility is returned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
utility
|
UtilityFunction
|
Utility function bundled with its finite decision space. |
required |
cps_class
|
type
|
The CPS class to use for each decision. Must implement
|
None
|
**cps_kwargs
|
Keyword arguments passed to each CPS instance (e.g., |
{}
|
Examples:
>>> import numpy as np
>>> from online_cp import UtilityFunction, ConformalPredictiveDecisionMaker
>>> U = UtilityFunction(lambda x, y, d: [[0, -10, 3], [-3, 5, 1]][int(y)][int(d)],
... decisions=[0, 1, 2])
>>> cdm = ConformalPredictiveDecisionMaker(U, a=1.0)
>>> X = np.random.default_rng(0).normal(size=(40, 5))
>>> y = (X[:, 0] > 0).astype(float)
>>> cdm.learn_initial_training_set(X, y)
>>> decision = cdm.predict(X[0])
>>> decision in [0, 1, 2]
True
Source code in src/online_cp/decision.py
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 | |
learn_initial_training_set(X: NDArray, y: NDArray) -> None
¶
Train all |D| internal CPS models on utility-transformed labels.
For each decision d, the training labels are
u_i(d) = U(x_i, y_i, d) for i = 1, ..., n.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
ndarray of shape (n, p)
|
Training features. |
required |
y
|
ndarray of shape (n,)
|
Training labels (outcomes). |
required |
Source code in src/online_cp/decision.py
predict(x: Any, tau: float = 0.5) -> Any
¶
Return the decision with highest expected utility.
For each decision d, computes the conformal mean of the utility-CPD \(Q^*_d\) and returns the decision maximising it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
array-like of shape (p,)
|
Test object features. |
required |
tau
|
float
|
Randomisation parameter in [0, 1]. |
0.5
|
Returns:
| Type | Description |
|---|---|
any
|
The optimal decision. |
Source code in src/online_cp/decision.py
predict_expected_utilities(x: Any, tau: float = 0.5) -> dict[Any, float]
¶
Return expected utilities for all decisions (without selecting one).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
array-like of shape (p,)
|
Test object features. |
required |
tau
|
float
|
Randomisation parameter in [0, 1]. |
0.5
|
Returns:
| Type | Description |
|---|---|
dict
|
Mapping from each decision to its expected utility. |
Source code in src/online_cp/decision.py
learn_one(x: Any, y: Any) -> None
¶
Update all |D| internal models with a new observation.
For each decision d, the model is updated with the pair
(x, U(x, y, d)).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
array-like of shape (p,)
|
Features of the new observation. |
required |
y
|
any
|
True outcome (label). |
required |
Source code in src/online_cp/decision.py
save(filepath: str | os.PathLike, *, compress: int = 3) -> None
¶
Save this decision maker to filepath.
The utility function callable (utility.fn) must be registered via
:func:~online_cp.register_callable or be a module-level named
function; lambdas will raise :class:~online_cp.SerializationError.
Warning
Only load files from trusted sources. Deserialising a file from an untrusted source can execute arbitrary code.
Source code in src/online_cp/decision.py
load(filepath: str | os.PathLike) -> ConformalPredictiveDecisionMaker
classmethod
¶
Load a decision maker from filepath.
Warning
Only load files from trusted sources. Deserialising a file from an untrusted source can execute arbitrary code.