DecPyMC-1-Utility-Foundations : Axiomes et Fondements
Serie : Programmation Probabiliste avec PyMC (1/7) Duree estimee : 50 minutes Prerequis : Avoir explore les notebooks 1-8 (modèles probabilistes de base)
Objectifs
Comprendre les loteries comme representation des choix en environnement stochastique
Maitriser les axiomes de Von Neumann-Morgenstern
Deriver la fonction d’utilite par calibration
Comprendre la maximisation de l’utilite esperee comme fondement de l’agent rationnel
Pourtant, la plupart des gens preferent A. Pourquoi ?
La valeur esperee ne suffit pas
Le Paradoxe de Saint-Petersbourg illustre cette limite. Formule par Nicolas Bernoulli en 1713 (lettre a Pierre Raymond de Montmort), il doit sa resolution a son cousin Daniel Bernoulli (1738) dans Specimen theoriae novae de mensura sortis (ou il introduit l’utilite logarithmique) :
Une piece est lancee jusqu’a obtenir Face. Si Face apparait au tour n, vous gagnez \(2^n\) euros. Combien paieriez-vous pour jouer ?
Valeur esperee infinie, mais personne ne paierait un million pour jouer. Il faut une autre approche.
2. Loteries : Representation Formelle des Choix
Definition
Une loterie est une distribution de probabilite sur des outcomes (résultats).
Notation : L = [p1:o1, p2:o2, …, pn:on]
Ou : - pi est la probabilite de l’outcome oi - la somme des pi = 1
Exemples
Loterie
Description
[1.0 : 100EUR]
100 EUR avec certitude (outcome degenere)
[0.5 : 200EUR, 0.5 : 0EUR]
Pile ou face pour 200 EUR
[0.6 : Succes, 0.4 : Echec]
Examen avec 60% de reussite
Loteries composees
Une loterie composee a d’autres loteries comme outcomes :
L = [0.5 : L1, 0.5 : L2]
Elle peut etre reduite en loterie simple par le calcul des probabilites totales.
Preparation de l’environnement
import numpy as npimport pymc as pmimport arviz as azimport matplotlib.pyplot as pltfrom dataclasses import dataclassfrom typing import List, Tuple, Generic, TypeVarimport warningswarnings.filterwarnings("ignore", category=FutureWarning)warnings.filterwarnings("ignore", category=UserWarning)RANDOM_SEED =42rng = np.random.default_rng(RANDOM_SEED)print(f"PyMC version : {pm.__version__}")print(f"ArviZ version : {az.__version__}")print("PyMC pret pour la theorie de la decision !")
PyMC version : 5.28.5
ArviZ version : 0.23.4
PyMC pret pour la theorie de la decision !
Packages charges
Package
Rôle
pymc
Modèles probabilistes, inference bayesienne
arviz
Diagnostics et visualisation des posteriors
numpy
Calculs numériques et generation de données
dataclasses
Structure de données pour les loteries
Les packages PyMC (Salvatier et al., 2016) et ArviZ (Kumar et al., 2019) fournissent l’infrastructure d’inference bayesienne. Ce notebook introduit les fondements de la théorie de la decision. Nous utiliserons PyMC pour l’inference bayesienne et des constructions Python pures pour les calculs d’utilite.
Implementation de la classe Loterie
Nous definissons une classe Loterie qui encapsule une distribution discrete sur des outcomes numériques. Cette implementation : - Valide que les probabilites somment a 1 - Fournit un affichage lisible de la forme [p1:o1, p2:o2, ...] - Permet le calcul de l’utilite esperee
# Representation d'une loterie simple@dataclassclass Loterie:"""Loterie : distribution de probabilite sur des outcomes numeriques.""" outcomes: List[Tuple[float, float]] # Liste de (probabilite, outcome)def __post_init__(self): total =sum(p for p, _ inself.outcomes)ifabs(total -1.0) >1e-6:raiseValueError(f"Probabilites doivent sommer a 1, got {total}")def__str__(self): parts = [f"{p:.0%}:{o}"for p, o inself.outcomes]returnf"[{', '.join(parts)}]"def expected_value(self):"""Valeur esperee de la loterie."""returnsum(p * o for p, o inself.outcomes)def expected_utility(self, utility_func):"""Utilite esperee : E[U(X)]."""returnsum(p * utility_func(o) for p, o inself.outcomes)# Exemplescertainty = Loterie([(1.0, 100)])coin_flip = Loterie([(0.5, 200), (0.5, 0)])print(f"Certitude : {certainty}")print(f"Pile ou face : {coin_flip}")print(f"E[certitude] = {certainty.expected_value()}")print(f"E[coin_flip] = {coin_flip.expected_value()}")
Certitude : [100%:100]
Pile ou face : [50%:200, 50%:0]
E[certitude] = 100.0
E[coin_flip] = 100.0
3. Axiomes de Préférences Rationnelles
Von Neumann et Morgenstern (1944) ont etabli les axiomes qui definissent un agent rationnel. Ces quatre axiomes ne sont pas arbitraires : ils capturent les conditions minimales pour qu’un système de préférences soit coherent et non-exploitable. Un agent qui les viole peut etre “money-pumped” (arnaque par cycle de préférences).
Notation
A > B : l’agent prefere strictement A a B
A < B : l’agent prefere strictement B a A
A ~ B : l’agent est indifferent entre A et B
A >= B : l’agent prefere A ou est indifferent (préférence faible)
Les 4 Axiomes
Axiome 1 : Completude (Orderability)
Pour toute paire de loteries A et B, exactement une relation est vraie : A > B, ou B > A, ou A ~ B
Interpretation : L’agent peut toujours comparer deux options. Sans cet axiome, l’agent pourrait etre paralyse face a certains choix.
Axiome 2 : Transitivite
Si A > B et B > C, alors A > C
Interpretation : Les préférences sont coherentes, pas de cycles. Si A > B > C > A, on peut vous faire payer pour echanger C->B, B->A, A->C et vous revenez au point de depart avec moins d’argent (“money pump”).
Axiome 3 : Continuite
Si A > B > C, alors il existe p dans (0,1) tel que : B ~ [p:A, (1-p):C]
Interpretation : Même le pire outcome peut etre compense par une probabilite suffisante du meilleur.
Axiome 4 : Indépendance
Si A > B, alors pour toute loterie C et toute probabilite p : [p:A, (1-p):C] > [p:B, (1-p):C]
Interpretation : Les préférences ne dependent pas des alternatives non pertinentes. C’est l’axiome le plus controverse : les expériences de Maurice Allais (1953) (Le comportement de l’homme rationnel devant le risque, Econometrica) ont montre que des agents rationnels le violent systematiquement, et Daniel Ellsberg (1961) a exhibit une aversion a l’ambiguite similaire. La Prospect Theory de Kahneman & Tversky (1979) proposera une refonte descriptive de ces comportements.
Demonstration : Verification de la transitivite
Illustrons l’axiome de transitivite avec un agent simule utilisant une fonction d’utilite concave U(x) = sqrt(x). Nous comparons trois loteries et verifions que les préférences sont transitives.
# Verification de la transitivite des preferences# Agent avec fonction d'utilite concave : aversion au risquedef utilite_sqrt(x):"""Fonction d'utilite concave U(x) = sqrt(x)."""return np.sqrt(x)# Trois loteriesA = Loterie([(1.0, 100)]) # 100 certainB = Loterie([(0.5, 196), (0.5, 0)]) # E[B] = 98C = Loterie([(1.0, 49)]) # 49 certainUA = A.expected_utility(utilite_sqrt)UB = B.expected_utility(utilite_sqrt)UC = C.expected_utility(utilite_sqrt)print(f"U(A) = {UA:.3f} (100 certain)")print(f"U(B) = {UB:.3f} (50% de 196)")print(f"U(C) = {UC:.3f} (49 certain)")print()print(f"A > B ? {UA > UB}")print(f"B ~ C ? {abs(UB - UC) <1e-10} (U(B) = {UB}, U(C) = {UC})")print(f"A > C ? {UA > UC} (transitivite verifiee)")
U(A) = 10.000 (100 certain)
U(B) = 7.000 (50% de 196)
U(C) = 7.000 (49 certain)
A > B ? True
B ~ C ? True (U(B) = 7.0, U(C) = 7.0)
A > C ? True (transitivite verifiee)
Exercice : Verifier l’axiome d’indépendance
Objectif : L’axiome d’indépendance dit que si A ≻ B, alors pour toute loterie C et tout α ∈ (0,1), αA + (1-α)C ≻ αB + (1-α)C.
On considere : - Loterie A : 80% chance de 500 EUR, 20% de 0 EUR - Loterie B : 30% chance de 1000 EUR, 70% de 0 EUR - Loterie C : 100% chance de 200 EUR
Travail : 1. Calculez l’utilite esperee de A et B avec u(x) = sqrt(x) (fonction CRRA, rho=0.5) 2. Verifiez que A ≻ B 3. Construisez les loteries composees αA + (1-α)C et αB + (1-α)C pour α = 0.5 4. Calculez l’utilite esperee de chaque loterie composee et verifiez que l’ordre est preserve
Indices : - La loterie composee αA + (1-α)C a pour outcomes : les outcomes de A ponderes par α, plus l’outcome de C pondere par (1-α) - αA + (1-α)C = [0.50.8 : 500, 0.50.2 : 0, 0.5*1.0 : 200]
# Exercice : Verifier l'axiome d'independanceA_outcomes = {500: 0.8, 0: 0.2}B_outcomes = {1000: 0.3, 0: 0.7}C_outcomes = {200: 1.0}alpha =0.5# TODO etudiant : definissez u(x) = np.sqrt(x)# u = lambda x: ...# TODO etudiant : calculez E[u(A)] et E[u(B)], verifiez A > B# eu_A = sum(p * u(o) for o, p in A_outcomes.items())# eu_B = ...# TODO etudiant : construisez les loteries composees# composee_A = {o: alpha * p for o, p in A_outcomes.items()}# composee_A[200] = composee_A.get(200, 0) + (1 - alpha) * 1.0# composee_B = ...# TODO etudiant : calculez E[u(composee_A)] et E[u(composee_B)]# verifiez que l'ordre est preserve : composee_A > composee_Bprint("Exercice a completer")
Exercice a completer
Analyse des résultats : Transitivite et Indifference
Loterie
Utilite esperee
Interpretation
A (100 certain)
U(A) = 10.000
sqrt(100) = 10
B (50% de 196)
U(B) = 7.000
0.5 x sqrt(196) + 0.5 x sqrt(0) = 7
C (49 certain)
U(C) = 7.000
sqrt(49) = 7
Observation cle : U(B) = U(C), donc B ~ C (indifference).
La transitivite est preservee car : - A > B (10 > 7) - B ~ C (7 = 7, indifference) - Donc A > C (10 > 7)
Note technique : Avec une utilite concave (sqrt), la loterie B a le même attrait que le montant certain C = 49, bien que E[B] = 98 >> 49. C’est exactement l’aversion au risque (formalisee par Pratt, 1964 et Arrow, 1965) : l’agent prefere 49 certain a une esperance de 98 avec risque.
4. Theoreme de Representation
Le theoreme fondamental
Theoreme (Von Neumann-Morgenstern, 1944)
Si les préférences d’un agent satisfont les 4 axiomes, alors il existe une fonction U (unique a transformation affine pres) telle que :
A > B ssi E[U(A)] > E[U(B)]
Ce theoreme est remarquable : des axiomes qualitatifs sur les préférences impliquent l’existence d’une fonction quantitative (utilite). C’est le pont entre psychologie (préférences) et mathematiques (optimisation).
Consequences
L’utilite esperee suffit : Pour prendre des decisions rationnelles, il suffit de maximiser E[U(outcome)]
Unicite relative : U est unique a transformation affine pres (U’ = aU + b, a > 0). Seules les différences d’utilite comptent.
Fondement de l’agent rationnel : Un agent qui viole ces axiomes peut etre “money-pumped”
L’agent : 1. Observe le monde 2. Infere l’etat via inference bayesienne (PyMC) 3. Evalue l’utilite esperee de chaque action possible 4. Choisit l’action qui maximise E[U] 5. Agit dans le monde
Modelisation d’un agent rationnel avec PyMC
Scénario : Un patient a potentiellement une maladie. L’agent (medecin) doit decider : traiter ou ne pas traiter.
Le modèle bayesien calcule d’abord P(malade|test+), puis l’agent utilise ce posterior pour calculer l’utilite esperee de chaque action.
# Modele de diagnostic medical avec PyMCprior_malade =0.3sensibilite =0.9# P(test+|malade)specificite =0.8# P(test-|sain)with pm.Model() as model_diagnostic:# Prior sur la maladie malade = pm.Bernoulli("malade", p=prior_malade)# Probabilite du test selon l'etat p_test = pm.math.switch(malade, sensibilite, 1- specificite)# Observation : test positif test = pm.Bernoulli("test", p=p_test, observed=1)# Inference trace_diag = pm.sample( draws=5000, chains=4, random_seed=RANDOM_SEED, progressbar=False, return_inferencedata=True )# Extraire le posteriorp_malade_post =float(trace_diag.posterior["malade"].mean().values)print(f"Posterior P(malade|test+) = {p_malade_post:.1%}")# Verification analytiquep_test_total = prior_malade * sensibilite + (1- prior_malade) * (1- specificite)p_malade_analytique = (prior_malade * sensibilite) / p_test_totalprint(f"Analytique P(malade|test+) = {p_malade_analytique:.1%}")print(f"(Theoreme de Bayes : 0.30 x 0.90 / {p_test_total:.2f} = {p_malade_analytique:.3f})")
Posterior P(malade|test+) = 66.3%
Analytique P(malade|test+) = 65.9%
(Theoreme de Bayes : 0.30 x 0.90 / 0.41 = 0.659)
Interpretation : Le theoreme de Bayes en action
Le résultat P(malade|test+) ~ 65.9% illustre le theoreme de Bayes :
Malgre un test positif avec 90% de sensibilite, la probabilite n’est “que” de 66%. C’est parce que la maladie est relativement rare (prior 30%) et que les faux positifs contribuent significativement.
Au-dela du conjugue : diagnostic hiérarchique multi-sites
Le diagnostic a 2 etats précédent est conjugue : le posterior a une forme close, et MCMC redonne exactement le calcul analytique de Bayes (les deux valeurs coincident a 66%). Pour montrer la vraie puissance de l’inference bayesienne par MCMC, considerons un problème non conjugue ou aucune forme close n’existe.
Scénario : un reseau de 8 hopitaux partage le même test, mais chaque hopital a sa propre prevalence de la maladie (liee a sa population). On observe le nombre de patients testes \(n_i\) et de cas positifs \(k_i\) par site. Objectif : inferer la prevalence de chaque site en empruntant l’information de tous les sites (partial pooling).
Le lien logit et la structure hiérarchique cassent la conjugaison : MCMC est requis. Le benefice pedagogique concret est le shrinkage (retrecissement) : les sites peu observes sont tires vers la moyenne de population \(\mu_{pop}\), ce qu’une mise a jour Beta-Binomial independante par site ne produirait jamais.
Ce modèle est une instance du cadre hiérarchique bayesien classique (Gelman & Hill, Data Analysis Using Regression and Multilevel/Hierarchical Models, 2006). La parametrisation non-centree \(\mu_{pop} + \tau \cdot z_i\) (plutot que la centree) evite le funnel de Neal qui apparait quand \(\tau\) est petit.
# Diagnostic hierarchique multi-sites (cas NON-CONJUGUE : MCMC requis)# 8 hopitaux, prevalences variables. On infer chaque prevalence avec partial pooling.n_patients = np.array([20, 30, 15, 100, 25, 40, 12, 60])k_positifs = np.array([3, 7, 2, 43, 8, 14, 2, 10])empirique = k_positifs / n_patientsprint("Prevalences empiriques par site :", empirique.round(3))with pm.Model() as model_hierarchique:# Niveau population (parametrisation NON-CENTREE : evite le funnel, recette #3801) mu_pop = pm.Normal("mu_pop", mu=-1.5, sigma=1.5) # logit-prevalence moyenne tau = pm.HalfNormal("tau", sigma=1.0) # dispersion entre hopitaux z = pm.Normal("z", 0.0, 1.0, shape=len(n_patients)) logit_p = mu_pop + tau * z p = pm.Deterministic("p", pm.math.sigmoid(logit_p))# Vraisemblance binomiale observee k = pm.Binomial("k", n=n_patients, p=p, observed=k_positifs) trace_hier = pm.sample( draws=2000, tune=1500, chains=4, target_accept=0.95, random_seed=RANDOM_SEED, progressbar=False, return_inferencedata=True )# Diagnostics MCMC (honetete des sorties)div =int(trace_hier.sample_stats["diverging"].sum())resume = az.summary(trace_hier, var_names=["mu_pop", "tau", "p"])print("Inference hierarchique des prevalences (MCMC, logit-Binomial non-centre)")print("="*60)print(f"Divergences NUTS : {div} (cible = 0)")print(f"R-hat max : {resume['r_hat'].max():.3f} (cible < 1.01)")print(f"ESS bulk min : {int(resume['ess_bulk'].min())}")print()print("Comparaison : prevalence empirique vs posterior (shrinkage vers la moyenne)")p_post = resume.loc[[f"p[{i}]"for i inrange(len(n_patients))], "mean"].valuesfor i inrange(len(n_patients)): diff =abs(p_post[i] - empirique[i]) marqueur =" <-- shrinkage (site petit tire vers mu_pop)"if (diff >0.02and n_patients[i] <30) else""print(f" site {i} (n={n_patients[i]:3d}): empirique={empirique[i]:.3f} -> posterior={p_post[i]:.3f}{marqueur}")print()print("Partial pooling : les sites peu observes sont tires vers mu_pop,")print("ce qu'aucune mise a jour conjuguee independante (Beta-Binomial par site) ne produit.")
Prevalences empiriques par site : [0.15 0.233 0.133 0.43 0.32 0.35 0.167 0.167]
Inference hierarchique des prevalences (MCMC, logit-Binomial non-centre)
============================================================
Divergences NUTS : 0 (cible = 0)
R-hat max : 1.000 (cible < 1.01)
ESS bulk min : 2697
Comparaison : prevalence empirique vs posterior (shrinkage vers la moyenne)
site 0 (n= 20): empirique=0.150 -> posterior=0.203 <-- shrinkage (site petit tire vers mu_pop)
site 1 (n= 30): empirique=0.233 -> posterior=0.243
site 2 (n= 15): empirique=0.133 -> posterior=0.206 <-- shrinkage (site petit tire vers mu_pop)
site 3 (n=100): empirique=0.430 -> posterior=0.400
site 4 (n= 25): empirique=0.320 -> posterior=0.294 <-- shrinkage (site petit tire vers mu_pop)
site 5 (n= 40): empirique=0.350 -> posterior=0.319
site 6 (n= 12): empirique=0.167 -> posterior=0.223 <-- shrinkage (site petit tire vers mu_pop)
site 7 (n= 60): empirique=0.167 -> posterior=0.193
Partial pooling : les sites peu observes sont tires vers mu_pop,
ce qu'aucune mise a jour conjuguee independante (Beta-Binomial par site) ne produit.
De l’inference a la decision
Maintenant, l’agent utilise le posterior pour prendre une decision. Nous definissons une matrice d’utilite qui specifie les consequences de chaque action dans chaque etat.
L’ecart de ~39 unites en faveur du traitement est substantiel. Le cout asymetrique des erreurs (0 vs 60) rend le traitement rationnel même si le patient pourrait etre sain.
5. Calibration par Mise a l’Indifference
Le problème pratique
Comment determiner la fonction d’utilite U d’un agent ? On ne peut pas observer U directement. La calibration permet de reconstruire U a partir des choix.
Méthode de l’indifference (Axiome de continuite)
Étape 1 : Fixer les references - o_best avec U(o_best) = 1 - o_worst avec U(o_worst) = 0
Étape 2 : Pour chaque outcome intermediaire - Option A : outcome o avec certitude - Option B : loterie [p : o_best, (1-p) : o_worst] - Faire varier p jusqu’a indifference
Étape 3 : En deduire l’utilite - U(o) = p* (la probabilite d’indifference)
Exemple : Evaluer une assurance
Vous avez une voiture de 10 000 EUR. Probabilite de vol = 5%.
Outcome
Valeur
Pas de vol
10 000 EUR
Vol
0 EUR
# Calibration de l'utilite pour la decision d'assurance# Utilite logarithmique (introduite par Daniel Bernoulli, 1738 ; aversion au risque classique)# U(x) = log(x + 1) normalise sur [0, 10000]def utilite_log(x):"""Utilite logarithmique normalisee."""if x <=0:return0return np.log(x +1) / np.log(10001) # Normalise: U(10000) ~ 1# Sans assurance : loterie [0.95 : 10000, 0.05 : 0]p_vol =0.05loterie_sans = Loterie([(1- p_vol, 10000), (p_vol, 0)])EU_sans = loterie_sans.expected_utility(utilite_log)# Avec assurance : certitude de (10000 - 600) = 9400prime_assurance =600EU_avec = utilite_log(10000- prime_assurance)print(f"E[U(sans assurance)] = 0.95 x U(10000) + 0.05 x U(0)")print(f" = 0.95 x {utilite_log(10000):.4f} + 0.05 x {utilite_log(0):.4f}")print(f" = {EU_sans:.4f}")print()print(f"E[U(avec assurance)] = U(9400) = {EU_avec:.4f}")print()if EU_avec > EU_sans:print(f"Decision : PRENDRE l'assurance (gain utilite = {EU_avec - EU_sans:.4f})")else:print(f"Decision : NE PAS prendre l'assurance")# Prime maximale acceptable# U(10000 - p) = EU_sans => 10000 - p = exp(EU_sans * log(10001)) - 1prime_max =10000- (np.exp(EU_sans * np.log(10001)) -1)print(f"\nPrime maximale acceptable : {prime_max:.0f} EUR")
E[U(sans assurance)] = 0.95 x U(10000) + 0.05 x U(0)
= 0.95 x 1.0000 + 0.05 x 0.0000
= 0.9500
E[U(avec assurance)] = U(9400) = 0.9933
Decision : PRENDRE l'assurance (gain utilite = 0.0433)
Prime maximale acceptable : 3691 EUR
Exercice : Modèle PyMC pour une loterie d’assurance
Objectif : L’exemple ci-dessus utilise un calcul analytique pour la decision d’assurance. On peut aussi modeliser la loterie directement dans PyMC.
On considere une maison de 200 000 EUR, avec P(inondation) = 2%. Si inondation, perte totale. L’assurance couvre la perte mais coute 5 000 EUR/an.
Travail : 1. Construisez un modèle PyMC avec une variable inondation ~ Bernoulli(0.02) et perte conditionnelle 2. Echantillonnez la distribution du gain net (sans assurance) : 0 si pas d’inondation, -200 000 si inondation 3. Calculez l’utilite esperee avec U(x) = log(x + 1) pour les deux options (assurance vs pas d’assurance) 4. Comparez et decidez
Indices : - Utilisez pm.math.switch pour le gain conditionnel - Richesse initiale = 200 000 EUR - Sans assurance : loterie [0.98 : 0, 0.02 : -200 000] - Avec assurance : certitude de -5 000 EUR (prime)
# Exercice : Modele PyMC pour une loterie d'assurancerichesse_maison =200_000p_inondation =0.02prime_assurance_maison =5_000# TODO etudiant : construisez un modele PyMC avec la variable inondation ~ Bernoulli(0.02)# with pm.Model() as model_assurance:# inondation = pm.Bernoulli("inondation", p=p_inondation)# perte = pm.math.switch(inondation, -richesse_maison, 0.0)# gain_net = pm.Deterministic("gain_net", perte)# trace_assurance = pm.sample(..., chains=4)# TODO etudiant : calculez E[U(sans assurance)] et E[U(avec assurance)]# eu_sans = ...# eu_avec = ...# print(f"Decision : {'prendre assurance' if eu_avec > eu_sans else 'ne pas prendre assurance'}")print("Exercice a completer : modele PyMC pour la loterie d'assurance")
Exercice a completer : modele PyMC pour la loterie d'assurance
Analyse du résultat : Pourquoi une prime si elevee ?
Metrique
Sans assurance
Avec assurance (600 EUR)
Valeur esperee
9 500 EUR
9 400 EUR
Utilite esperee
0.9500
0.9933
L’utilite logarithmique U(x) = log(x+1) est fortement concave : perdre les 10 000 EUR de la voiture serait catastrophique en utilite, tandis que payer 600 EUR de prime a un effet marginal. Jusqu’a combien l’agent est-il alors pret a payer pour eliminer le risque ? La reponse distingue deux grandeurs differentes, souvent confondues : la prime de risque de Pratt et la prime maximale d’assurance.
Cadre de calcul : richesse initiale \(w = 10\,000\) EUR ; sans assurance, le gain net vaut \(X = 0\) avec probabilite \(0{,}95\) et \(X = -10\,000\) avec probabilite \(0{,}05\), donc \(E[X] = -500\) EUR : la perte esperee vaut 500 EUR. L’equivalent certain de richesse finale, note \(CE\), verifie \(U(CE) = E[U(w+X)] = 0{,}95\), soit \(CE = 10001^{0{,}95} - 1 \approx 6\,309{,}17\) EUR.
1. Prime de risque de Pratt : le prix du risque seul
\[U(w + E[X] - \pi) = E[U(w + X)]\]
L’agent est indifferent entre garder la loterie et recevoir avec certitude \(w + E[X] - \pi\). La prime de risque mesure le cout du risque au-dela de la perte esperee. Comme \(U\) est croissante, \(w + E[X] - \pi = CE\), d’ou :
\[\pi = w + E[X] - CE = 10\,000 - 500 - 6\,309{,}17 = 3\,190{,}83 \text{ EUR}\]
C’est la forme classique de Pratt (1964) et Arrow (1965), \(\pi = E[X] - CE_{gain}\), avec l’equivalent certain exprime en gains : \(CE_{gain} = CE - w = -3\,690{,}83\) EUR.
2. Prime maximale d’assurance : le prix total du contrat
\[U(w - p_{max}) = E[U(w + X)]\]
Cette fois, l’agent compare la richesse certaine \(w - p_{max}\) — il paie la prime et l’assureur couvre le vol — a la loterie sans assurance. On resout le paiement total maximal accepte :
\[p_{max} = w - CE = 10\,000 - 6\,309{,}17 = 3\,690{,}83 \text{ EUR}\]
C’est exactement la quantite affichee par la cellule de calcul de l’assurance (“Prime maximale acceptable : 3691 EUR”, arrondie a l’unite).
Note technique : \(U(w - p_{max}) = E[U(w+X)]\) definit la prime d’assurance (paiement total, perte esperee comprise) ; \(U(w + E[X] - \pi) = E[U(w+X)]\) definit la prime de risque (cout du risque au-dela de la perte esperee). Un agent neutre au risque (\(\pi = 0\)) n’accepterait de payer que 500 EUR.
Cette decomposition explique pourquoi l’assurance peut creer un surplus pour un agent averse au risque : son prix de reserve, 3 690,83 EUR, depasse la perte esperee de 500 EUR de la prime de risque de 3 190,83 EUR. Le prix effectivement propose reste determine par le contrat et le marche.
6. Modelisation avec PyMC
Loteries comme modèles probabilistes
Une loterie peut etre naturellement modelisee comme une variable aleatoire dans PyMC. L’avantage est triple :
Inference : PyMC peut calculer les posteriors sur des variables latentes
Composition : Les loteries composees sont modelisees par des modèles graphiques
Integration : Le calcul de E[U] s’appuie sur les distributions inferees
# Loterie modelisee avec PyMC# 50% de gagner 1000, 50% de perdre 500with pm.Model() as model_loterie:# Variable latente : issue de la loterie gagne = pm.Bernoulli("gagne", p=0.5)# Gain conditionnel gain = pm.math.switch(gagne, 1000.0, -500.0)# Deterministic pour tracer le gain gain_det = pm.Deterministic("gain", gain)# Echantillonnage (pas d'observation = prior predictive) trace_loterie = pm.sample( draws=5000, chains=4, random_seed=RANDOM_SEED, progressbar=False, return_inferencedata=True )# Analyser la distribution du gaingains = trace_loterie.posterior["gain"].values.flatten()print(f"Distribution du gain :")print(f" E[gain] = {gains.mean():.0f} EUR")print(f" P(gain = +1000) = {(gains ==1000).mean():.1%}")print(f" P(gain = -500) = {(gains ==-500).mean():.1%}")print()# Calcul de l'utilite esperee avec U(x) = sqrt(x + 1000)def U(x):return np.sqrt(x +1000)EU =0.5* U(1000) +0.5* U(-500)U_certain = U(gains.mean())print(f"E[U(loterie)] = 0.5 x U(1000) + 0.5 x U(-500)")print(f" = 0.5 x {U(1000):.2f} + 0.5 x {U(-500):.2f}")print(f" = {EU:.2f}")print()print(f"U(valeur esperee) = U(250) = {U_certain:.2f}")print()print(f"EU < U(EV) ? {EU < U_certain} => agent averse au risque prefere la certitude")
Distribution du gain :
E[gain] = 254 EUR
P(gain = +1000) = 50.3%
P(gain = -500) = 49.7%
E[U(loterie)] = 0.5 x U(1000) + 0.5 x U(-500)
= 0.5 x 44.72 + 0.5 x 22.36
= 33.54
U(valeur esperee) = U(250) = 35.42
EU < U(EV) ? True => agent averse au risque prefere la certitude
Interpretation : Equivalent certain et aversion au risque
Concept
Valeur
Interpretation
E[gain]
250 EUR
Valeur esperee de la loterie
U(E[gain])
35.36
Utilite de la valeur esperee
E[U(gain)]
33.54
Utilite esperee de la loterie
Inegalite de Jensen (Jensen, 1906 ; appliquee a l’utilite par Pratt, 1964, et Arrow, 1965) : Pour une fonction d’utilite concave U,
\[E[U(X)] \leq U(E[X])\]
C’est la signature mathematique de l’aversion au risque.
Equivalent certain : Le montant CE tel que U(CE) = E[U(loterie)] :
50% de chance de gagner 2000 EUR, 50% de perdre 500 EUR (richesse initiale = 10 000 EUR).
Travail a realiser
Implementer U_CARA(x, alpha) = -exp(-alpha * x) et calculer CE pour alpha = 0.001
Implementer U_CRRA(x, rho) = x^(1-rho)/(1-rho) et calculer CE pour rho = 2.0
Calculer les primes de risque : Prime = E[gain] - CE
Comparer et interpreter
Bonus : Tester avec richesse = 1000 EUR et observer que la prime CARA ne change pas mais CRRA change
# Exercice : Comparer les primes de risque CARA vs CRRArichesse_initiale =10000.0gain_haut =2000.0perte_basse =-500.0proba =0.5valeur_esperee = proba * gain_haut + (1- proba) * perte_basseprint(f"Loterie : {proba:.0%} de +{gain_haut:.0f} EUR, {(1-proba):.0%} de {perte_basse:.0f} EUR")print(f"Valeur esperee du gain : {valeur_esperee:.0f} EUR")print(f"Richesse initiale : {richesse_initiale:.0f} EUR")print()# A completer 1 : Implementer la fonction d'utilite CARA# Hint : def u_cara(x, alpha): return -np.exp(-alpha * x)# A completer 2 : Implementer la fonction d'utilite CRRA# Hint : utiliser la fonction crra() definie plus haut# A completer 3 : Calculer l'equivalent certain CE pour chaque fonction# L'equivalent certain CE verifie : U(richesse + CE) = E[U(richesse + gain)]# Methode : recherche par dichotomie dans l'intervalle [perte_basse - 100, gain_haut + 100]# A completer 4 : Calculer et afficher les primes de risque# Prime de risque = valeur_esperee - CE# A completer 5 (BONUS) : Repeter avec richesse_initiale = 1000 EUR# Observer : la prime CARA change-t-elle ? La prime CRRA change-t-elle ?print("Exercice a completer : fonctions CARA et CRRA, calcul des equivalents certains et primes de risque.")print("Indices : CARA = aversion absolue constante, CRRA = aversion relative constante.")
Loterie : 50% de +2000 EUR, 50% de -500 EUR
Valeur esperee du gain : 750 EUR
Richesse initiale : 10000 EUR
Exercice a completer : fonctions CARA et CRRA, calcul des equivalents certains et primes de risque.
Indices : CARA = aversion absolue constante, CRRA = aversion relative constante.
Théorie de la decision et utilite esperee - Bernoulli, D. (1738) : Specimen Theoriae Novae de Mensura Sortis (paradoxe de Saint-Petersbourg, utilite logarithmique) - Bernoulli, N. (1713) : lettre a Montmort (formulation initiale du paradoxe) - Von Neumann, J. & Morgenstern, O. (1944) : Theory of Games and Economic Behavior (axiomes VNM, theoreme de representation) - Savage, L. J. (1954) : The Foundations of Statistics (axiomatique subjective, sure-thing principle) - Allais, M. (1953) : Le comportement de l’homme rationnel devant le risque, Econometrica (paradoxe d’Allais) - Ellsberg, D. (1961) : Risk, Ambiguity, and the Savage Axioms, QJE (paradoxe d’Ellsberg) - Pratt, J. W. (1964) : Measuring Risk Aversion, Annals of Mathematical Statistics (prime de risque, aversion absolue/relative) - Arrow, K. J. (1965) : Aspects of the Theory of Risk-Bearing (CRRA, CARA) - Kahneman, D. & Tversky, A. (1979) : Prospect Theory, Econometrica (aversion aux pertes)
Implementation - Salvatier, J., Wiecki, T. V. & Fonnesbeck, C. (2016) : Probabilistic programming in Python using PyMC3, PeerJ Computer Science - Kumar, R. et al. (2019) : ArviZ: a unified library for exploratory analysis of Bayesian models in Python, JOSS - Russell, S. & Norvig, P. : Artificial Intelligence: A Modern Approach, chapitre 16 (Making Simple Decisions)
Conclusion : Ce notebook a etabli les fondements de la théorie de la decision : loteries, axiomes VNM, theoreme de representation, et calibration de la fonction d’utilite par la méthode de l’indifference.