{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Probabilities" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:05.271606Z", "start_time": "2021-02-15T09:50:00.013623Z" } }, "outputs": [], "source": [ "from matplotlib import pyplot as plt\n", "from fractions import Fraction\n", "import poisson_approval as pa" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Random Factories" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The package provides a large variety of random factories to generate **profiles**, **strategies** or **tau-vectors**. For example, define a random factory of tau-vectors:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:05.282577Z", "start_time": "2021-02-15T09:50:05.276764Z" } }, "outputs": [], "source": [ "rand_tau = pa.RandTauVectorUniform()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then use this random factory to generate a tau-vector:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:05.318861Z", "start_time": "2021-02-15T09:50:05.285569Z" } }, "outputs": [ { "data": { "text/plain": [ " ==> b" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tau = rand_tau()\n", "tau" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Most random factories of the package also have a \"grid\" counterpart where the coefficients are fractions of a given denominator. This is convenient to generate less \"messy\" examples:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:05.360947Z", "start_time": "2021-02-15T09:50:05.322851Z" } }, "outputs": [ { "data": { "text/plain": [ " ==> c" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rand_tau = pa.RandTauVectorGridUniform(denominator=100)\n", "tau = rand_tau()\n", "tau" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Also, most random factories have options that enable to finely tune the distribution:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:05.402717Z", "start_time": "2021-02-15T09:50:05.364738Z" } }, "outputs": [ { "data": { "text/plain": [ " ==> a (Plurality)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rand_tau = pa.RandTauVectorUniform(\n", " ballots=['a', 'b'], \n", " d_ballot_fixed_share={'c': 0.1}, \n", " voting_rule=pa.PLURALITY\n", ")\n", "tau = rand_tau()\n", "tau" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For more information, cf. the *Reference* section on random factories." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Conditional Random Factory" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*RandConditional* is a random factory implementing rejection sampling. It needs:\n", "\n", "* Another random factory that is responsible for generating the objects,\n", "* A test that the objects must meet,\n", "* A maximum number of trials before renouncing (which can be *None* if you want to draw objects forever, until finding one that meets the test)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here, we use a conditional random factory to generate an example of *TauVector* with a direct focus:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:05.432590Z", "start_time": "2021-02-15T09:50:05.405629Z" } }, "outputs": [], "source": [ "def test_direct_focus(tau):\n", " return tau.focus == pa.Focus.DIRECT" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:05.476473Z", "start_time": "2021-02-15T09:50:05.435582Z" } }, "outputs": [ { "data": { "text/plain": [ " ==> b" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rand_tau = pa.RandConditional(\n", " factory=pa.RandTauVectorGridUniform(denominator=100),\n", " test=test_direct_focus,\n", " n_trials_max=None\n", ")\n", "tau = rand_tau()\n", "tau" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Alternatively, *RandConditional* accepts a tuple of factories, and a test on the tuple of the results. Here is an example of a *ProfileNoisyDiscrete* and a *StrategyOrdinal*, such that the strategy is an equilibrium for the profile:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:05.504401Z", "start_time": "2021-02-15T09:50:05.480463Z" } }, "outputs": [], "source": [ "rand_profile = pa.RandProfileNoisyDiscreteGridUniform(\n", " denominator=100,\n", " types=[('abc', 0.4, 0.01),\n", " ('bac', 0.2, 0.01),\n", " ('cab', 0.7, 0.01)]\n", ")\n", "rand_strategy = pa.RandStrategyOrdinalUniform()\n", "def test_is_equilibrium(profile, strategy):\n", " return profile.is_equilibrium(strategy) == pa.EquilibriumStatus.EQUILIBRIUM" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:05.580209Z", "start_time": "2021-02-15T09:50:05.507390Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " (Condorcet winner: a)\n", "\n" ] } ], "source": [ "rand_example = pa.RandConditional(\n", " factory=(rand_profile, rand_strategy),\n", " test=test_is_equilibrium,\n", " n_trials_max=None\n", ")\n", "profile, strategy = rand_example()\n", "print(profile)\n", "print(strategy)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Probability Estimation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To compute a probability, use the function *probability*." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For example, estimate the probability that a *TauVector* drawn uniformly at random has a direct focus:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:05.590184Z", "start_time": "2021-02-15T09:50:05.583201Z" } }, "outputs": [], "source": [ "def test_direct_focus(tau):\n", " return tau.focus == pa.Focus.DIRECT" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:05.931947Z", "start_time": "2021-02-15T09:50:05.594173Z" } }, "outputs": [ { "data": { "text/plain": [ "0.43" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pa.probability(\n", " factory=pa.RandTauVectorUniform(),\n", " n_samples=100,\n", " test=test_direct_focus\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To avoid the definition of an auxiliary function, you can use a *lambda*. For example:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:06.244476Z", "start_time": "2021-02-15T09:50:05.934940Z" } }, "outputs": [ { "data": { "text/plain": [ "0.52" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pa.probability(\n", " factory=pa.RandTauVectorUniform(),\n", " n_samples=100,\n", " test=lambda tau: tau.focus == pa.Focus.DIRECT\n", ")" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2020-01-03T06:55:13.021088Z", "start_time": "2020-01-03T06:55:13.016102Z" } }, "source": [ "You can also compute a conditional probability. For example, the probability that a *ProfileNoisyDiscrete* (generated by the random factory defined below) has an ordinal equilibrium, conditionally on having a strict Condorcet winner:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:06.256443Z", "start_time": "2021-02-15T09:50:06.248539Z" } }, "outputs": [], "source": [ "rand_profile = pa.RandProfileNoisyDiscreteUniform(\n", " types=[('abc', 0.4, 0.01),\n", " ('bac', 0.2, 0.01),\n", " ('cab', 0.7, 0.01)]\n", ")\n", "def test_exists_ordinal_equilibrium(profile):\n", " return len(profile.analyzed_strategies_ordinal.equilibria) > 0\n", "def test_is_strictly_condorcet(profile):\n", " return profile.is_profile_condorcet == 1.0" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:10.768581Z", "start_time": "2021-02-15T09:50:06.258437Z" } }, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pa.probability(\n", " factory=rand_profile,\n", " n_samples=100,\n", " test=test_exists_ordinal_equilibrium,\n", " conditional_on=test_is_strictly_condorcet\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also use a tuple of random factories, and tests on the tuple of the results. For example, estimate the probability that a random *StrategyOrdinal* is an equilibrium for a random *ProfileNoisyDiscrete* (generated by the random factory defined below), conditionally on the fact that the profile has a strict Condorcet winner and that the initial strategy elects the Condorcet winner:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:10.787122Z", "start_time": "2021-02-15T09:50:10.773804Z" } }, "outputs": [], "source": [ "rand_profile = pa.RandProfileNoisyDiscreteUniform(\n", " types=[('abc', 0.4, 0.01),\n", " ('bac', 0.2, 0.01),\n", " ('cab', 0.7, 0.01)]\n", ")\n", "rand_strategy = pa.RandStrategyOrdinalUniform()\n", "def test_is_equilibrium(profile, strategy):\n", " return profile.is_equilibrium(strategy) == pa.EquilibriumStatus.EQUILIBRIUM\n", "def test_elect_condorcet_winner(profile, strategy):\n", " return (profile.is_profile_condorcet == 1. \n", " and profile.tau(strategy).winners == profile.condorcet_winners)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:11.478812Z", "start_time": "2021-02-15T09:50:10.790166Z" } }, "outputs": [ { "data": { "text/plain": [ "0.36" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pa.probability(\n", " factory=(rand_profile, rand_strategy),\n", " n_samples=100,\n", " test=test_is_equilibrium,\n", " conditional_on=test_elect_condorcet_winner\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, you can also use a tuple of tests in order to estimate several probabilities with the same sample. For example, estimate the probability that a *TauVector* drawn uniformly at random is direct, forward-focused, backward-focused, or unfocused:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:11.820701Z", "start_time": "2021-02-15T09:50:11.482801Z" } }, "outputs": [ { "data": { "text/plain": [ "(0.52, 0.48, 0.0, 0.0)" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "pa.probability(\n", " factory=pa.RandTauVectorUniform(),\n", " n_samples=100,\n", " test=(lambda tau: tau.focus == pa.Focus.DIRECT, \n", " lambda tau: tau.focus == pa.Focus.FORWARD_FOCUSED,\n", " lambda tau: tau.focus == pa.Focus.BACKWARD_FOCUSED,\n", " lambda tau: tau.focus == pa.Focus.UNFOCUSED)\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Image Distribution Estimation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To compute an image distribution, use the function *image_distribution*.\n", "\n", "For example, when drawing a *ProfileNoisyDiscrete* (with the random factory defined below) and an initial *StrategyOrdinal* at random, and when applying iterated voting, let us estimate the distribution of the length of the cycle to which it converges:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:11.833830Z", "start_time": "2021-02-15T09:50:11.826783Z" } }, "outputs": [], "source": [ "rand_profile = pa.RandProfileNoisyDiscreteUniform(\n", " types=[('abc', 0.4, 0.01),\n", " ('bca', 0.2, 0.01),\n", " ('cab', 0.7, 0.01)]\n", ")\n", "rand_strategy = pa.RandStrategyOrdinalUniform()" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:11.853016Z", "start_time": "2021-02-15T09:50:11.836724Z" } }, "outputs": [], "source": [ "def len_cycle(profile, strategy_ini):\n", " cycle = profile.iterated_voting(init=strategy_ini, n_max_episodes=100)['cycle_taus_actual']\n", " return len(cycle)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:15.348999Z", "start_time": "2021-02-15T09:50:11.856008Z" } }, "outputs": [ { "data": { "text/plain": [ "{1: 0.21, 2: 0.02, 3: 0.77}" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "d_len_occurrences = pa.image_distribution(\n", " factory=(rand_profile, rand_strategy),\n", " n_samples=100, f=len_cycle)\n", "d_len_occurrences" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "ExecuteTime": { "end_time": "2021-02-15T09:50:15.815367Z", "start_time": "2021-02-15T09:50:15.353987Z" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plt.bar(d_len_occurrences.keys(), d_len_occurrences.values())" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": false, "sideBar": true, "skip_h1_title": true, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": { "height": "calc(100% - 180px)", "left": "10px", "top": "150px", "width": "218.875px" }, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }