Skip to content

Instantly share code, notes, and snippets.

@florimondmanca
Last active December 24, 2020 15:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save florimondmanca/4731e58c077471aeafbed96fda656c32 to your computer and use it in GitHub Desktop.
Save florimondmanca/4731e58c077471aeafbed96fda656c32 to your computer and use it in GitHub Desktop.
Bayes' Rule, reframed "odds" instead of "chances"
"""
Bayes rule, reframed as "odds" instead of "chances".
https://twitter.com/florimondmanca/status/1342119381573238789
Inspired by 3Blue1Brown's "The medical test paradox: Can redesigning Bayes rule help?".
"""
from fractions import Fraction
from typing import Any
def bayesfactor(accuracy: float, false_positive_rate: float) -> float:
return accuracy / false_positive_rate
class Odds:
# Run tests: $ python -m doctest bayesodds.py
"""
>>> prior = Odds[1:9]
>>> prior
Odds[1:9]
>>> prior.prob
0.1
>>> b = bayesfactor(accuracy=0.9, false_positive_rate=0.01)
>>> b
90.0
>>> posterior = prior * b
>>> posterior
Odds[10:1]
>>> posterior.prob
0.9090909090909091
"""
def __init__(self, fraction: Fraction) -> None:
self._fraction = fraction
@classmethod
def __class_getitem__(cls, item: Any) -> "Odds":
if not isinstance(item, slice):
raise NotImplementedError
positive = item.start
negative = item.stop
return Odds(Fraction(positive, negative))
def __mul__(self, other: Any) -> "Odds":
try:
other = float(other)
except (TypeError, ValueError):
raise NotImplementedError
return Odds(self._fraction * other)
def __rmul__(self, other: Any) -> "Odds":
return self.__mul__(other)
def __repr__(self) -> str:
positive, negative = self._fraction.as_integer_ratio()
return f"Odds[{positive}:{negative}]"
@property
def prob(self) -> float:
positive, negative = self._fraction.as_integer_ratio()
return positive / (positive + negative)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment