I said that a probability is a measurement of a possibility. We’ve now formalized what a possibility is in this context. Now let’s turn to the measurement part.
The Kolmogorov axioms build the notion of a probability measure from the more general concept of a measure. All a probability measure \(\mathbb{P}\) is going to do is to map from some event in the event space (e.g. high vowel, high back vowel, etc.) to a non-negative real value–with values corresponding to higher probabilities. So it is a function \(\mathbb{P}: \mathcal{F} \rightarrow \mathbb{R}_+\). This condition is the first of the Kolmogorov axioms.
You might be used to thinking of probabilities as being between \([0, 1]\). This property is a consequence of the two other axioms:
The probability of the entire sample space \(\mathbb{P}(\Omega) = 1\) (the assumption of unit measure)
Given a countable collection of events \(E_1, E_2, \ldots \in \mathcal{F}\) that is pairwise disjoint–i.e. \(E_i \cap E_j = \emptyset\) for all \(i \neq j\)–\(\mathbb{P}\left(\bigcup_i E_i\right) = \sum_i \mathbb{P}(E_i)\) (the assumption of \(\sigma\)-additivity)
Define FiniteMeasurableSpace
from typing import Iterablefrom itertools import chain, combinationsfrom functools importreduceSampleSpace =frozenset[str]Event =frozenset[str]SigmaAlgebra =frozenset[Event]def powerset(iterable: Iterable) -> Iterable:"""The power set of a set See https://docs.python.org/3/library/itertools.html#itertools-recipes Parameters ---------- iterable The set to take the power set of """ s =list(iterable)return chain.from_iterable(combinations(s, r) for r inrange(len(s)+1))class FiniteMeasurableSpace:"""A finite measurable space Parameters ---------- atoms The atoms of the space sigma_algebra The σ-algebra of the space """def__init__(self, atoms: SampleSpace, sigma_algebra: SigmaAlgebra):self._atoms = atomsself._sigma_algebra = sigma_algebraself._validate()def _validate(self):for subset inself._sigma_algebra:# check powerset conditionifnot subset <=self._atoms:raiseValueError("All events must be a subset of the atoms")# check closure under complementifnot (self._atoms - subset) inself._sigma_algebra:raiseValueError("The σ-algebra must be closed under complements")for subsets in powerset(self._sigma_algebra): subsets =list(subsets)# python doesn't like to reduce empty iterablesifnot subsets:continue# check closure under finite union union =frozenset(reduce(frozenset.union, subsets))if union notinself._sigma_algebra:raiseValueError("The σ-algebra must be closed under countable union" )# check closure under finite intersection intersection =frozenset(reduce(frozenset.intersection, subsets))if intersection notinself._sigma_algebra:raiseValueError("The σ-algebra must be closed under countable intersection" )@propertydef atoms(self) -> SampleSpace:returnself._atoms@propertydef sigma_algebra(self) -> SigmaAlgebra:returnself._sigma_algebra
Define generate_sigma_algebra
def generate_sigma_algebra(family: SigmaAlgebra) -> SigmaAlgebra:"""Generate a σ-algebra from a family of sets Parameters ---------- family The family of sets from which to generate the σ-algebra """ sigma_algebra =set(family) old_sigma_algebra =set(family) complete =Falsewhilenot complete:for subsets in powerset(old_sigma_algebra): subsets =list(subsets)ifnot subsets:continue union =reduce(frozenset.union, subsets) sigma_algebra.add(union) intersection =reduce(frozenset.intersection, subsets) sigma_algebra.add(intersection) complete = sigma_algebra == old_sigma_algebra old_sigma_algebra =set(sigma_algebra)returnfrozenset(sigma_algebra)
from typing import Dictfrom itertools import combinationsclass ProbabilityMeasure:"""A probability measure with finite support Parameters ---------- domain The domain of the probability measure measure The graph of the measure """def__init__(self, domain: FiniteMeasurableSpace, measure: Dict[Event, float]):self._domain = domainself._measure = measureself._validate()def__call__(self, event: Event) ->float:returnself._measure[event]def _validate(self):# check that the measure covers the domainfor event inself._domain.sigma_algebra:if event notinself._measure:raiseValueError("Probability measure must be defined for all events.")# check the assumption of unit measureifself._measure[frozenset(self._domain.atoms)] !=1:raiseValueError("The probability of the sample space must be 1.")# check assumption of 𝜎-additivityfor events in powerset(self._domain.sigma_algebra): events =list(events)ifnot events:continueifnotany(e1.intersection(e2) for e1, e2 in combinations(events, 2)): prob_union =self._measure[reduce(frozenset.union, events)] prob_sum =sum(self._measure[e] for e in events)ifround(prob_union, 4) !=round(prob_sum, 4):raiseValueError("The measure does not satisfy 𝜎-additivity.")
One example of a probability measure for our measurable space \(\langle \Omega, \mathcal{F}_\text{highness-backness}\rangle\) is the uniform measure: \(\mathbb{P}(E) = \frac{|E|}{|\Omega|}\).
measure_highness_backness = ProbabilityMeasure( highness_backness_space, {e: len(e)/len(highness_backness_space.atoms)for e in highness_backness_space.sigma_algebra})
These axioms imply that the range of \(\mathbb{P}\) is \([0, 1]\), even if its codomain is \(\mathbb{R}_+\); otherwise, it would have to be the case that \(\mathbb{P}(E) > 1\) for some \(E \subset \Omega\). (\(E\) would have to be a strict subset of \(\Omega\), since \(\Omega \supseteq E\) for all \(E \in \mathcal{F}\) and \(\mathbb{P}(\Omega) = 1\) by definition.) But \(\mathbb{P}(E) > 1\) cannot hold, since \(\mathbb{P}(\Omega - E)\)–which must be defined, given that \(\mathcal{F}\) is closed under complementation–is nonnegative; and thus \(\mathbb{P}(E) + \mathbb{P}(\Omega - E) > \mathbb{P}(\Omega) = 1\) contradicts the third axiom \(\mathbb{P}(E) + \mathbb{P}(\Omega - E) = \mathbb{P}(E \cup [\Omega - E]) = \mathbb{P}(\Omega) = 1\).
(One reason the codomain of \(\mathbb{P}\) is often specified as the more general \(\mathbb{R}_+\)–rather than \([0, 1]\) is to make salient the fact that probabilities are analogous to other kinds of measurements, like weight, height, temperature, etc.)
These axioms also imply that \(\mathbb{P}(\emptyset) = 0\), since \(\mathbb{P}(\Omega) = \mathbb{P}(\Omega \cup \emptyset) = \mathbb{P}(\Omega) + \mathbb{P}(\emptyset) = 1\), and so \(\mathbb{P}(\emptyset) = 1 - \mathbb{P}(\Omega) = 0\).
class ProbabilityMeasure(ProbabilityMeasure):def are_mutually_exclusive(self, *events: Iterable[Event]):self._validate_events(events)returnnotany(e1.intersection(e2) for e1, e2 in combinations(events, 2))def _validate_events(self, events: Iterable[Event]):for i, event inenumerate(events):if event notinself._domain.sigma_algebra:raiseValueError(f"event{i} is not in the event space.")
In our running example, the set of high vowels \(H\) and the set of not high vowels \(L\) are mutually exclusive events because \(H \cap L = \emptyset\).
measure_highness_backness = ProbabilityMeasure( highness_backness_space, {e: len(e)/len(highness_backness_space.atoms)for e in highness_backness_space.sigma_algebra})measure_highness_backness.are_mutually_exclusive(high, nonhigh)