Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Ballots from Parameters notebook #108

Merged
merged 2 commits into from
Nov 17, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
233 changes: 233 additions & 0 deletions notebooks/ballots_from_parameters.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Ballots from Parameters\n",
"\n",
"In the VoteKit world of ballot generating, there are usually 4 parameters that need to be chosen.\n",
"- Bloc proportions\n",
"- Cohesion parameters\n",
"- Preference intervals\n",
"- Candidates per bloc\n",
"\n",
"Instead of choosing a preference interval, VoteKit also makes it possible to generate a preference interval using the Dirichlet distribution.\n",
"The Dirichlet distribution samples a point from a simplex, in this case the candidate simplex. For three candidates, the candidate simplex is a triangle, where each corner represents a candidate. A point in the triangle is a vector of length 3 whose entries are non-negative and sum to 1 (exactly what a preference interval is!). A point that is close to a vertex is a preference interval with high support for one candidate. A point near the center of the triangle is a preference interval with near equal support for all three.\n",
"\n",
"The Dirichlet distribution is parameterized by a parameter $\\alpha \\in (0,\\infty)$. When $\\alpha=1$, the distribution is uniform on the candidate simplex, so it is uniform on preference intervals. As $\\alpha\\to\\infty$, the distribution's mass moves towards the center of the simplex, so we get preference intervals that have more equal support for all candidates. As $\\alpha\\to 0$, the distribution's mass moves towards the corners, so we get preference intervals that have strong support for one candidate.\n",
"\n",
"By using the Dirichlet distribution instead of a fixed preference interval, you can study how the behavior of voters impacts elections.\n",
"- What happens in STV elections when voters have a strong preference for one candidate? A diffuse preference for all?\n",
"\n",
"Let's see an example of how to construct ballots using the Dirichlet parameters.\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import votekit.ballot_generator as bg"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# the Plackett-Luce model\n",
"\n",
"bloc_proportions = {\"A\": .8, \"B\": .2}\n",
"cohesion_parameters = {\"A\": .9, \"B\": .9}\n",
"dirichlet_alphas = {\"A\": {\"A\":1, \"B\":1},\n",
" \"B\": {\"A\":1, \"B\":1}}\n",
"\n",
"slate_to_candidates = {\"A\": [\"A1\", \"A2\"],\n",
" \"B\": [\"B1\", \"B2\"]}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We need four different Dirichlet parameter's; $\\alpha_{AA}$ generates the $A$ voters preference interval for $A$ candidates and $\\alpha_{AB}$ generates the $A$ voters preference interval for $B$ candidates. To construct the full preference interval for $A$ voters, we take the two intervals generated by the Dirichlet distribution, scale the $A$ interval by the $A$ cohesion parameter and the $B$ interval by 1 minus the $A$ cohesion parameter, and append them.\n",
"\n",
"Also notice that we need a bit more information in this case than if we gave the PL model a preference interval; we must specify the cohesion parameters and which candidates are in which bloc."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"PreferenceProfile truncated to 15 ballots.\n",
" Ballots Weight\n",
"(A2, B1, A1, B2) 209\n",
"(A2, A1, B1, B2) 184\n",
"(A2, B1, B2, A1) 101\n",
"(A2, A1, B2, B1) 74\n",
"(B1, B2, A1, A2) 72\n",
"(A2, B2, B1, A1) 59\n",
"(A2, B2, A1, B1) 47\n",
"(B1, A2, A1, B2) 38\n",
"(B2, B1, A1, A2) 36\n",
"(A1, A2, B1, B2) 33\n",
"(B1, B2, A2, A1) 27\n",
"(B1, A1, B2, A2) 26\n",
"(B1, A2, B2, A1) 21\n",
"(A1, A2, B2, B1) 14\n",
"(B2, B1, A2, A1) 13\n"
]
}
],
"source": [
"pl = bg.PlackettLuce.from_params(slate_to_candidates=slate_to_candidates,\n",
" bloc_voter_prop=bloc_proportions,\n",
" cohesion=cohesion_parameters,\n",
" alphas=dirichlet_alphas)\n",
"\n",
"profile = pl.generate_profile(number_of_ballots=1000)\n",
"print(profile)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can see what preference intervals were generated. Check for understanding; are these intervals what you would expect given the choices of parameter above?"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'A': {'A1': 0.06902221893010327,\n",
" 'A2': 0.8309777810698967,\n",
" 'B1': 0.07233491281949957,\n",
" 'B2': 0.027665087180500415},\n",
" 'B': {'A1': 0.07911776818363357,\n",
" 'A2': 0.020882231816366403,\n",
" 'B1': 0.6544994218711536,\n",
" 'B2': 0.24550057812884657}}"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pl.pref_interval_by_bloc"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's fiddle with the Dirichlet parameter's to see how they impact things. By lowering $\\alpha_{AB}$, we expect to see that $A$ voters have a strong preference for a particular $B$ candidate. By raising $\\alpha_{BA}$, we expect $B$ voters to not relatively uniform preferences for $A$ candidates."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"A preference interval {'A1': 0.8482122567812463, 'A2': 0.05178774321875372, 'B1': 3.347178913699908e-08, 'B2': 0.09999996652821083}\n",
"B preference interval {'A1': 0.03862281248244345, 'A2': 0.061377187517556525, 'B1': 0.44004319506039635, 'B2': 0.45995680493960367} \n",
"\n",
"PreferenceProfile truncated to 15 ballots.\n",
" Ballots Weight\n",
"(A1, B2, A2, B1) 465\n",
"(A1, A2, B2, B1) 216\n",
"(B2, A1, A2, B1) 59\n",
"(B1, B2, A2, A1) 50\n",
"(B2, B1, A2, A1) 44\n",
"(A2, A1, B2, B1) 42\n",
"(B2, B1, A1, A2) 40\n",
"(B1, B2, A1, A2) 28\n",
"(A2, B2, A1, B1) 12\n",
"(B2, A2, A1, B1) 9\n",
"(B2, A2, B1, A1) 9\n",
"(B1, A2, B2, A1) 6\n",
"(B2, A1, B1, A2) 5\n",
"(A2, B1, B2, A1) 4\n",
"(B1, A1, B2, A2) 4\n"
]
}
],
"source": [
"# the Plackett-Luce model\n",
"\n",
"bloc_proportions = {\"A\": .8, \"B\": .2}\n",
"cohesion_parameters = {\"A\": .9, \"B\": .9}\n",
"dirichlet_alphas = {\"A\": {\"A\":1, \"B\":.01},\n",
" \"B\": {\"A\":1, \"B\":1000}}\n",
"\n",
"slate_to_candidates = {\"A\": [\"A1\", \"A2\"],\n",
" \"B\": [\"B1\", \"B2\"]}\n",
"\n",
"pl = bg.PlackettLuce.from_params(slate_to_candidates=slate_to_candidates,\n",
" bloc_voter_prop=bloc_proportions,\n",
" cohesion=cohesion_parameters,\n",
" alphas=dirichlet_alphas)\n",
"\n",
"print(\"A preference interval\", pl.pref_interval_by_bloc[\"A\"])\n",
"print(\"B preference interval\", pl.pref_interval_by_bloc[\"B\"], \"\\n\")\n",
"\n",
"profile = pl.generate_profile(number_of_ballots=1000)\n",
"print(profile)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Check for understanding; are the intervals and ballots what you'd expect?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Any of our other ballot generating models that rely on preference intervals can be generated from the Dirichlet distribution in a similar way."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "votekit",
"language": "python",
"name": "votekit"
},
"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.11.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Loading