Predict the Electoral College: The Paths to Victory
Seth J. Chandler
Seth J. Chandler
Disputes currently rage in the United States about which candidate, Joe Biden or Donald Trump, should receive the electoral votes of various states in which the popular vote outcome was close and disputed. Each candidate has a number of paths to victory by receiving the electoral votes in some subset of these states. This essay develops an interactive tool whereby the user can input their probabilities for each candidate winning each state and computes the overall probability that the particular candidate will receive enough votes in the electoral college to serve as President beginning on January 20, 2021
Scenarios
Scenarios
I start with electoral vote data. Here are the states that, based on my reading of the news (others can differ) appear to be in play with both close election results and allegations of election improprieties or miscounts.
Create an Association from state to electoral votes:
unclearElectoralVotes=AssociationThread[{"Georgia","Pennsylvania","Michigan","Arizona","Nevada"},{20,16,16,11,6}]
Out[]=
Georgia20,Pennsylvania16,Michigan16,Arizona11,Nevada6
Let' s form a list of all possible outcomes. Since, ultimately, one slate of electors must be acknowledged by Congress as representing the state, I exclude the possibility of ties.
Use Tuples to form all possible scenarios:
5
2
In[]:=
unclear=Keys[unclearElectoralVotes];
(scenarios=Map[AssociationThread[unclear,#]&,Tuples[{"Biden","Trump"},Length[unclear]]])//[10]
Out[]//Short=
{GeorgiaBiden,PennsylvaniaBiden,MichiganBiden,ArizonaBiden,NevadaBiden,GeorgiaBiden,PennsylvaniaBiden,MichiganBiden,ArizonaBiden,NevadaTrump,GeorgiaBiden,PennsylvaniaBiden,MichiganBiden,ArizonaTrump,NevadaBiden,26,GeorgiaTrump,PennsylvaniaTrump,MichiganTrump,ArizonaBiden,NevadaTrump,GeorgiaTrump,PennsylvaniaTrump,MichiganTrump,ArizonaTrump,NevadaBiden,GeorgiaTrump,PennsylvaniaTrump,MichiganTrump,ArizonaTrump,NevadaTrump}
State - by - state outcome distributions
State - by - state outcome distributions
I now create a probability distribution of outcomes for each state. Notice that I do not yet need to assign values to the probabilities; I keep them symbolic:
Create synbolic categorical distributions for each state:
In[]:=
dist[state_]:=CategoricalDistribution[{"Biden","Trump"},{p[state,"Biden"],1-p[state,"Biden"]}]
dists=AssociationMap[dist,unclear]
Out[]=
GeorgiaCategoricalDistribution,PennsylvaniaCategoricalDistribution,MichiganCategoricalDistribution,ArizonaCategoricalDistribution,NevadaCategoricalDistribution
Assign probabilities to scenarios
Assign probabilities to scenarios
I now want to assign a probability to each outcome. For example, if the probability that Trump would win Michigan is very low, any scenario that contains such an assumption will itself have a low probability. The scenario probabilities remain symbolic.
Use KeyValueMap and the PDF function to compute the symbolic probability of each scenario:
(scenarioProbabilities=AssociationMap[scenarioTimes@@KeyValueMap[{k,v}PDF[dists[k],v],scenario],scenarios])//[20]
Out[]//Short=
GeorgiaBiden,PennsylvaniaBiden,MichiganBiden,ArizonaBiden,NevadaBidenp[Arizona,Biden]p[Georgia,Biden]p[Michigan,Biden]p[Nevada,Biden]p[Pennsylvania,Biden],GeorgiaBiden,PennsylvaniaBiden,MichiganBiden,ArizonaBiden,NevadaTrumpp[Arizona,Biden]p[Georgia,Biden]p[Michigan,Biden](1-p[Nevada,Biden])p[Pennsylvania,Biden],GeorgiaBiden,PennsylvaniaBiden,MichiganBiden,ArizonaTrump,NevadaBiden(1-p[Arizona,Biden])p[Georgia,Biden]p[Michigan,Biden]p[Nevada,Biden]p[Pennsylvania,Biden],27,GeorgiaTrump,PennsylvaniaTrump,MichiganTrump,ArizonaTrump,NevadaBiden(1-p[Arizona,Biden])(1-p[Georgia,Biden])(1-p[Michigan,Biden])p[Nevada,Biden](1-p[Pennsylvania,Biden]),GeorgiaTrump,PennsylvaniaTrump,MichiganTrump,ArizonaTrump,NevadaTrump(1-p[Arizona,Biden])(1-p[Georgia,Biden])(1-p[Michigan,Biden])(1-p[Nevada,Biden])(1-p[Pennsylvania,Biden])
Assign electoral votes to scenarios
Assign electoral votes to scenarios
To determine who wins, I need to assign electoral votes to each scenario.
For each scenario, total the electoral votes the candidate would receive :
(scenarioVotes=AssociationMap[scenarioGroupBy[Reverse/@Normal[scenario],FirstLast,(Lookup[unclearElectoralVotes,#,Missing[]]&)/*Total],scenarios])//[12]
Out[]//Short=
GeorgiaBiden,PennsylvaniaBiden,MichiganBiden,ArizonaBiden,NevadaBidenBiden69,GeorgiaBiden,PennsylvaniaBiden,MichiganBiden,ArizonaBiden,NevadaTrumpBiden63,Trump6,GeorgiaBiden,PennsylvaniaBiden,MichiganBiden,ArizonaTrump,NevadaBidenBiden58,Trump11,26,GeorgiaTrump,PennsylvaniaTrump,MichiganTrump,ArizonaBiden,NevadaTrumpTrump58,Biden11,GeorgiaTrump,PennsylvaniaTrump,MichiganTrump,ArizonaTrump,NevadaBidenTrump63,Biden6,GeorgiaTrump,PennsylvaniaTrump,MichiganTrump,ArizonaTrump,NevadaTrumpTrump69
Develop a symbolic expression for a victory criteria
Develop a symbolic expression for a victory criteria
I now want to merge our probability information with our vote information and compute the aggregate probability of each candidate winning. I'll do this symbolically at first and later plug in estimated values.
Use GroupBy and Merge to get the aggregate probability of Biden receiving the requisite number of votes :
In[]:=
victoryFunction[scenariovotes_,v_:33]:=If[Lookup[scenariovotes,"Biden",0]≥v,"Biden","Trump"]
results=GroupBy[Values@Merge[{scenarioProbabilities,scenarioVotes},{#[[1]],victoryFunction[#[[2]],33]}&],LastFirst,Total];
In[]:=
Short[results]
Out[]//Short=
Biden1,Trump1+12+1
An Interactive Tool
An Interactive Tool
I can now construct an interactive tool that lets the user input the probabilities for each state and computes the aggregate probability of each candidate receiving enough votes to win the presidency. So as not to take sides in any of the disputes, I initialize the Biden win probability in each of the contested states to 0.5. Obviously, users and partisans can change those probabilities as they wish:
Create a simple Manipulate to make the results concrete :
Manipulate[Map[Evaluate,results/.{p["Georgia","Biden"]bidenga,p["Pennsylvania","Biden"]bidenpa,p["Michigan","Biden"]bidenmi,p["Arizona","Biden"]bidenaz,p["Nevada","Biden"]bidennv}]//Dataset,{{bidenga,0.5,"Biden win probability in Georgia"},0,1,0.01,Appearance"Labeled"},{{bidenpa,0.5,"Biden win probability in Pennsylvania"},0,1,0.01,Appearance"Labeled"},{{bidenmi,0.5,"Biden win probability in Michigan"},0,1,0.01,Appearance"Labeled"},{{bidenaz,0.5,"Biden win probability in Arizona"},0,1,0.01,Appearance"Labeled"},{{bidennv,0.5,"Biden win probability in Nevada"},0,1,0.01,Appearance"Labeled"},SaveDefinitionsTrue]
Out[]=
Generalizing the process
Generalizing the process
The material above considers a specific example drawn from the 2020 election as it appears in mid November, 2020. But we can construct a more general approach.
Write a function that combines the steps taken above :
In[]:=
v[electoralVotes_Association,categoricalDists_Association,victoryfunction_]:=Module[{scenarios,scenarioProbabilities,scenarioVotes,results},scenarios=Map[AssociationThread[unclear,#]&,Tuples[Information[categoricalDists[Keys[electoralVotes][[1]]],"Categories"],Length[unclear]]];scenarioVotes=AssociationMap[scenarioGroupBy[Reverse/@Normal[scenario],FirstLast,(Lookup[electoralVotes,#,Missing[]]&)/*Total],scenarios];scenarioProbabilities=AssociationMap[scenarioTimes@@KeyValueMap[{k,v}PDF[categoricalDists[k],v],scenario],scenarios];results=GroupBy[Values@Merge[{scenarioProbabilities,scenarioVotes},{#[[1]],victoryfunction[#[[2]]]}&],LastFirst,Total]]
We can check to see if it replicates the results from above :
See if it works on the pre - existing example :
Now let' s extend it to a six state scenario in which I add the hypothetical "West" candidate to the equation. Let's create the new distributions
Create probability distributions by state with three candidates :
Tweak the victory function to accomodate the third candidate :
Run the v function :
We can make our state - by - state distributions concrete and see the results.
Create new distributions:
Building a Website
Building a Website
We can also create a simple website that enables users to input their own probability estimates. It's an amazingly simple process:
Develop a FormPage with controls, a function and some options:
Run the form to make sure it works:
Keywords
Keywords
◼
Political science
◼
Electoral college
◼
FormPage
◼
Combinatorics

